| | |
| | | |
| | | function getOptions(xLabels = [], data = []) { |
| | | let barColor = '#02a7f0'; |
| | | let maxColor = '#d9001b'; |
| | | let minColor = '#f59a23'; |
| | | let maxColor = '#438D29'; |
| | | let minColor = '#DBD608'; |
| | | let legends = []; |
| | | return { |
| | | grid: { |
| | |
| | | // useWebSocket.js |
| | | import { ref, reactive, onMounted, onUnmounted } from "vue"; |
| | | import { |
| | | ref, |
| | | reactive, |
| | | onMounted, |
| | | onUnmounted, |
| | | onActivated, |
| | | onDeactivated, |
| | | } from "vue"; |
| | | import getWsUrl from "@/assets/js/getWsUrl"; |
| | | |
| | | export default function (url) { |
| | |
| | | socket.value.onopen = () => { |
| | | isConnected.value = true; |
| | | console.log("WebSocket Connected, url: ", url); |
| | | sendCallback.forEach(v => v()); |
| | | sendCallback.forEach((v) => v()); |
| | | sendCallback.length = 0; |
| | | }; |
| | | |
| | |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | console.log('socket mount', Date.now(), '============='); |
| | | |
| | | // console.log('socket mount', Date.now(), '============='); |
| | | console.log("on socket mount", url, "============="); |
| | | |
| | | connect(); |
| | | }); |
| | | |
| | | onActivated(() => { |
| | | if (!socket.value) { |
| | | console.log("on socket active", url, "============="); |
| | | connect(); |
| | | } |
| | | }); |
| | | |
| | | onDeactivated(() => { |
| | | if (socket.value) { |
| | | socket.value.close(); |
| | | } |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | if (socket.value) { |
| | | socket.value.close(); |
| | |
| | | const tagAndTagSpacing = 0; // tagAndTagSpacing |
| | | const left = ref(0); |
| | | const scrollContainer = ref(); |
| | | const props = defineProps({ |
| | | tagRefs: { |
| | | type: Array, |
| | | default: () => [], |
| | | }, |
| | | }); |
| | | |
| | | const wrap = computed(() => { |
| | | return scrollContainer.value.$refs.wrap; |
| | | return scrollContainer.value.wrapRef; |
| | | }); |
| | | // onMounted(() => { |
| | | // console.log("?", scrollContainer.value, wrap, "============="); |
| | |
| | | // // wrap.addEventListener("scroll", emitScroll, true); |
| | | |
| | | // nextTick(() => { |
| | | // // 尝试找到滚动容器,这里假设它是 scrollContainer 的直接子元素 |
| | | // // 注意:这取决于 Element Plus 的具体实现,可能需要调整 |
| | | // // 尝试找到滚动容器,这里假设它是 scrollContainer 的直接子元素 |
| | | // // 注意:这取决于 Element Plus 的具体实现,可能需要调整 |
| | | // const scrollElement = scrollContainer.value.$el; |
| | | // if (scrollElement) { |
| | | // scrollElement.addEventListener('scroll', emitScroll, { passive: true }); |
| | | // } |
| | | // if (scrollElement) { |
| | | // scrollElement.addEventListener('scroll', emitScroll, { passive: true }); |
| | | // } |
| | | // }); |
| | | // }); |
| | | // onBeforeUnmount(() => { |
| | |
| | | function emitScroll() { |
| | | $emit("scroll"); |
| | | } |
| | | // function moveToTarget(currentTag) { |
| | | // const $container = $refs.scrollContainer.$el; |
| | | // const $containerWidth = $container.offsetWidth; |
| | | // const $scrollWrapper = scrollWrapper; |
| | | // const tagList = $parent.$refs.tag; |
| | | function moveToTarget(currentTag) { |
| | | // const $container = $refs.scrollContainer.$el; |
| | | const $container = scrollContainer.value.$el; |
| | | const $containerWidth = $container.offsetWidth; |
| | | // const $scrollWrapper = scrollWrapper; |
| | | const $scrollWrapper = scrollContainer.value; |
| | | // const tagList = $parent.$refs.tag; |
| | | const tagList = props.tagRefs; |
| | | |
| | | // let firstTag = null; |
| | | // let lastTag = null; |
| | | let firstTag = null; |
| | | let lastTag = null; |
| | | |
| | | // // find first tag and last tag |
| | | // if (tagList.length > 0) { |
| | | // firstTag = tagList[0]; |
| | | // lastTag = tagList[tagList.length - 1]; |
| | | // } |
| | | // find first tag and last tag |
| | | if (tagList.length > 0) { |
| | | firstTag = tagList[0]; |
| | | lastTag = tagList[tagList.length - 1]; |
| | | } |
| | | |
| | | // if (firstTag === currentTag) { |
| | | // $scrollWrapper.scrollLeft = 0; |
| | | // } else if (lastTag === currentTag) { |
| | | // $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth; |
| | | // } else { |
| | | // // find preTag and nextTag |
| | | // const currentIndex = tagList.findIndex((item) => item === currentTag); |
| | | // const prevTag = tagList[currentIndex - 1]; |
| | | // const nextTag = tagList[currentIndex + 1]; |
| | | if (firstTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = 0; |
| | | } else if (lastTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth; |
| | | } else { |
| | | // find preTag and nextTag |
| | | const currentIndex = tagList.findIndex((item) => item === currentTag); |
| | | const prevTag = tagList[currentIndex - 1]; |
| | | const nextTag = tagList[currentIndex + 1]; |
| | | |
| | | // // the tag's offsetLeft after of nextTag |
| | | // const afterNextTagOffsetLeft = |
| | | // nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing; |
| | | // the tag's offsetLeft after of nextTag |
| | | const afterNextTagOffsetLeft = |
| | | nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing; |
| | | |
| | | // // the tag's offsetLeft before of prevTag |
| | | // const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing; |
| | | // the tag's offsetLeft before of prevTag |
| | | const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing; |
| | | |
| | | // if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { |
| | | // $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth; |
| | | // } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { |
| | | // $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft; |
| | | // } |
| | | // } |
| | | // } |
| | | if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { |
| | | $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth; |
| | | } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { |
| | | $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft; |
| | | } |
| | | } |
| | | } |
| | | defineExpose({ |
| | | moveToTarget, |
| | | }); |
| | | </script> |
| | | <template> |
| | | <el-scrollbar |
| | |
| | | }); |
| | | } |
| | | function closeSelectedTag(view) { |
| | | closeMenu(); |
| | | delView(view).then(({ visitedViews }) => { |
| | | if (isActive(view)) { |
| | | toLastView(visitedViews, view); |
| | |
| | | }); |
| | | } |
| | | function closeOthersTags() { |
| | | closeMenu(); |
| | | $router.push(gData.selectedTag); |
| | | delOthersViews(gData.selectedTag).then(() => { |
| | | moveToCurrentTag(); |
| | | }); |
| | | } |
| | | function closeAllTags(view) { |
| | | closeMenu(); |
| | | delAllViews().then(({ visitedViews }) => { |
| | | if (gData.affixTags.some((tag) => tag.path === view.path)) { |
| | | return; |
| | |
| | | const offsetLeft = wraper.value.getBoundingClientRect().left; // container margin left |
| | | const offsetWidth = wraper.value.offsetWidth; // container width |
| | | const maxLeft = offsetWidth - menuMinWidth; // left boundary |
| | | let left = e.clientX - offsetLeft + 15; // 15: margin right |
| | | let _left = e.clientX - offsetLeft + 15; // 15: margin right |
| | | |
| | | if (left > maxLeft) { |
| | | left = maxLeft; |
| | | |
| | | if (_left > maxLeft) { |
| | | left.value = maxLeft; |
| | | } else { |
| | | left = left; |
| | | left.value = _left; |
| | | } |
| | | |
| | | top.value = 10; |
| | |
| | | ref="scrollPane" |
| | | class="tags-view-wrapper" |
| | | @scroll="handleScroll" |
| | | :tagRefs="tagRefs" |
| | | > |
| | | <!-- tag="span" --> |
| | | <router-link |
| | |
| | | |
| | | function typeChange() { |
| | | chooseDev(resList.value[0]); |
| | | testDatas.value = []; |
| | | updateChart([]); |
| | | } |
| | | |
| | | function getList() { |
| | |
| | | let type = ""; |
| | | switch (v) { |
| | | case "chr": |
| | | type = "充电测试"; |
| | | type = devType.value == 1 ? "充电测试" : "充电"; |
| | | break; |
| | | case "dis": |
| | | type = "放电测试"; |
| | | type = devType.value == 1 ? "放电测试" : "放电"; |
| | | break; |
| | | case "jun": |
| | | type = "均衡"; |
| | | break; |
| | | } |
| | | let label = type; |
| | |
| | | |
| | | // 设置柱状图 |
| | | function setBarChart(dataList) { |
| | | if (!dataList.length) { |
| | | return false; |
| | | } |
| | | // if (!dataList.length) { |
| | | // return false; |
| | | // } |
| | | |
| | | let unit = "V"; |
| | | let fixed = 3; |
| | |
| | | let index = getDataIndex(dataList.length, slideValue.value); |
| | | let labels = [], |
| | | datas = []; |
| | | if (index != -1) { |
| | | if (dataList.length && index != -1) { |
| | | let data = dataList[index]; |
| | | let batNum = getBarNum(data); |
| | | title = |
| | |
| | | |
| | | function selectRecord() { |
| | | let res = testRecordCode.value[1]; |
| | | console.log("res", res, "============="); |
| | | // console.log("res", res, "============="); |
| | | |
| | | getRecordInf(currentDevId.value, res) |
| | | .then((res) => { |
| | |
| | | <div class="content">{{ formatSeconds(testObj.testTimelong) }}</div> |
| | | <div class="label">数据类型</div> |
| | | <div class="content"> |
| | | {{ { 2: "充电数据", 3: "放电数据" }[testInf.testType] }} |
| | | {{ |
| | | { 2: "充电数据", 3: "放电数据", 4: "均衡数据" }[testInf.testType] |
| | | }} |
| | | </div> |
| | | <!-- <div class="label">标称容量</div> |
| | | <div class="content">4444444</div> |
| | |
| | | return new Date(a).getTime() - new Date(b).getTime(); |
| | | }).forEach((v) => { |
| | | let item = actm[v]; |
| | | // 2 放电 3充电 |
| | | jhyData[0].data.push(item[3]); |
| | | jhyData[1].data.push(item[2]); |
| | | // 3 放电 2充电 |
| | | jhyData[0].data.push(item[2]); |
| | | jhyData[1].data.push(item[3]); |
| | | |
| | | dates.push(v); |
| | | }); |
| | |
| | | return new Date(a).getTime() - new Date(b).getTime(); |
| | | }).forEach((v) => { |
| | | let item = a200[v]; |
| | | // 2 放电 3充电 |
| | | ytjData[0].data.push(item[3]); |
| | | ytjData[1].data.push(item[2]); |
| | | // 3 放电 2充电 |
| | | ytjData[0].data.push(item[2]); |
| | | ytjData[1].data.push(item[3]); |
| | | }); |
| | | |
| | | } |
| | |
| | | }); |
| | | |
| | | const testDatas = computed(() => { |
| | | // 2 放电 3 充电 |
| | | let labels = ["放电测试", "充电测试"], |
| | | // 3 放电 2 充电 |
| | | let labels_yt = ["放电测试", "充电测试"], |
| | | labels_jh = ["放电", "充电", '均衡'], |
| | | ytjMonthData = [], |
| | | ytjYearData = [], |
| | | jhyMonthData = [], |
| | |
| | | }, |
| | | } = JSON.parse(message.value); |
| | | |
| | | ytjMonthData.push(a200Map["a200MonthMap"][2], a200Map["a200MonthMap"][3]); |
| | | ytjYearData.push(a200Map["a200YearMap"][2], a200Map["a200YearMap"][3]); |
| | | jhyMonthData.push(actmMap["actmMonthMap"][2], actmMap["actmMonthMap"][3]); |
| | | jhyYearData.push(actmMap["actmYearMap"][2], actmMap["actmYearMap"][3]); |
| | | ytjMonthData.push(a200Map["a200MonthMap"][3], a200Map["a200MonthMap"][2]); |
| | | ytjYearData.push(a200Map["a200YearMap"][3], a200Map["a200YearMap"][2]); |
| | | jhyMonthData.push(actmMap["actmMonthMap"][3], actmMap["actmMonthMap"][2], actmMap["actmMonthMap"][4]); |
| | | jhyYearData.push(actmMap["actmYearMap"][3], actmMap["actmYearMap"][2], actmMap["actmYearMap"][4]); |
| | | } |
| | | return { |
| | | labels, |
| | | labels_jh, |
| | | labels_yt, |
| | | ytjMonthData, |
| | | ytjYearData, |
| | | jhyMonthData, |
| | |
| | | ytjTestType.value == 0 |
| | | ? testDatas.value.ytjMonthData |
| | | : testDatas.value.ytjYearData; |
| | | testBar.value?.updateChart(testDatas.value.labels, datas); |
| | | testBar.value?.updateChart(testDatas.value.labels_yt, datas); |
| | | } |
| | | function updateJhTest() { |
| | | let datas = |
| | | jhTestType.value == 0 |
| | | ? testDatas.value.jhyMonthData |
| | | : testDatas.value.jhyYearData; |
| | | jhTestBar.value?.updateChart(testDatas.value.labels, datas); |
| | | jhTestBar.value?.updateChart(testDatas.value.labels_jh, datas); |
| | | } |
| | | function updateMap() { |
| | | const getColor = (onLine) => ["#aaa", "#0f0"][onLine]; |
| | |
| | | return currentDev.value.state[0].batteryCount == 1; |
| | | }); |
| | | |
| | | |
| | | // 正在测试中 获取测试类型 是充电还是放电 |
| | | const currentType = computed(() => { |
| | | return currentDev.state?.testType || 1; |
| | | }); |
| | | |
| | | const resList = computed(() => { |
| | | let _list = list.value[devType.value]; |
| | | return _list.filter((v) => ("" + v.devIdcode).indexOf(keyWord.value) > -1); |
| | |
| | | v-model="testVisible" |
| | | v-if="testVisible" |
| | | :isUpdate="isUpdateParam" |
| | | :testType="currentType" |
| | | :devs="currentDev" |
| | | ></param-content> |
| | | </template> |
| | |
| | | v-if="testVisible" |
| | | :isUpdate="isUpdateParam" |
| | | :grpIdx="testGroupIdx" |
| | | :testType="currentType" |
| | | :devs="currentDev" |
| | | ></jh-param-content> |
| | | </template> |
| | |
| | | import formatSeconds from "@/assets/js/tools/formatSeconds"; |
| | | import toFixed from "@/assets/js/tools/toFixed.js"; |
| | | import const_digits from "@/assets/js/const/const_digits"; |
| | | import IconAvg from "@/components/icons/IconAvg.vue"; |
| | | const { VOL, GROUPVOL, CURR_YT, CURR_JH } = const_digits; |
| | | const props = defineProps({ |
| | | datas: { |
| | |
| | | <div class="value">{{toFixed(datas.minBatteryVoltage, VOL) }} V</div> |
| | | </div> |
| | | <div class="item"> |
| | | <div class="label">ΔU</div> |
| | | <div class="label"><el-icon><icon-avg class="avg-icon" /></el-icon>U</div> |
| | | <div class="value">{{ toFixed(datas.avgBatteryVoltage, VOL) }} V</div> |
| | | </div> |
| | | <div class="item"> |
| | |
| | | }, |
| | | isUpdate: { |
| | | type: Boolean, |
| | | }, |
| | | testType: { |
| | | type: Number, |
| | | } |
| | | }); |
| | | |
| | |
| | | } |
| | | |
| | | onMounted(() => { |
| | | params.testType = props.testType; |
| | | getParams(); |
| | | }); |
| | | </script> |
| | |
| | | } |
| | | }); |
| | | |
| | | |
| | | const logList = computed(() => { |
| | | let _list = rtDatas.value.eventList; |
| | | let resObj = {}; |
| | |
| | | <div class="value">{{ toFixed(rtDatas.devStates.avgMonVol, VOL) }}V</div> |
| | | </div> |
| | | <div class="item-big"> |
| | | {{ toFixed(rtDatas.devStates.storageVoltage, VOL) }} |
| | | {{ toFixed(rtDatas.devStates.storageVoltage, GROUPVOL) }} |
| | | <div class="unit">V</div> |
| | | </div> |
| | | |
| | |
| | | text-align: center; |
| | | background: #02a7f0; |
| | | &.max { |
| | | background: #d9001b; |
| | | background: #438D29; |
| | | } |
| | | &.min { |
| | | background: #f59a23; |
| | | background: #DBD608; |
| | | } |
| | | } |
| | | } |
| | |
| | | text-align: center; |
| | | background: #02a7f0; |
| | | &.max { |
| | | background: #d9001b; |
| | | background: #438D29; |
| | | } |
| | | &.min { |
| | | background: #f59a23; |
| | | background: #DBD608; |
| | | } |
| | | } |
| | | } |
| | |
| | | padding: 2px 10px; |
| | | border-radius: 6px; |
| | | &.max { |
| | | background: #d9001b; |
| | | background: #438D29; |
| | | } |
| | | &.min { |
| | | background: #f59a23; |
| | | background: #DBD608; |
| | | } |
| | | } |
| | | } |