Browse Source

命令状态

master
zhangjiming 5 months ago
parent
commit
8c38b94b58
  1. 1
      src/assets/icon_operation.svg
  2. 9
      src/services/txn.ts
  3. 10
      src/stores/status.ts
  4. 110
      src/views/components/Footer.vue
  5. 1480
      src/views/graphite/index.vue

1
src/assets/icon_operation.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="36" height="36" viewBox="0 0 36 36"><g><path d="M0.0338876,21.6006C0.791888,25.2568,2.6603,28.5461,5.43529,31.1111C5.80569,31.454,6.31565,31.6116,6.8194,31.5389C7.3235,31.4665,7.76624,31.1719,8.02131,30.7391L10.1884,27.0549C10.5503,26.4391,10.4661,25.6645,9.97991,25.1375C8.84698,23.9069,8.02102,22.4346,7.56723,20.8368C7.36685,20.128,6.70975,19.6374,5.96078,19.6374L1.66693,19.6374C1.16648,19.6372,0.692517,19.8581,0.376395,20.2389C0.0591609,20.619,-0.0666573,21.1192,0.0338876,21.6006ZM22.0852,29.174C21.7232,28.5559,20.9949,28.2395,20.2854,28.3921C18.4901,28.7781,16.6239,28.7054,14.8655,28.1807C14.1235,27.9594,13.3239,28.2689,12.9355,28.9278L10.808,32.5469C10.5628,32.9646,10.5176,33.4671,10.6845,33.9204C10.8509,34.3741,11.2133,34.7322,11.6745,34.8985C13.6899,35.6293,15.8187,36,17.9994,36C19.8024,36,21.5824,35.7444,23.2887,35.2393C23.7758,35.0946,24.1692,34.7399,24.3574,34.2758C24.545,33.8109,24.5056,33.2873,24.2505,32.8545L22.0852,29.174ZM29.7455,4.17944C29.4462,3.9339,29.0685,3.79934,28.6784,3.79924C28.5817,3.79924,28.4831,3.80922,28.3864,3.82559C27.9025,3.91049,27.4815,4.20075,27.2359,4.61875L25.1037,8.24068C24.7167,8.90032,24.8432,9.73465,25.4092,10.255C26.8597,11.5847,27.9059,13.2833,28.4313,15.1619C28.6304,15.8724,29.2886,16.3647,30.0393,16.3649L34.3337,16.3649C34.8331,16.3646,35.3062,16.1445,35.6226,15.7652C35.9401,15.3857,36.0664,14.886,35.9664,14.4048C35.1469,10.4185,32.9378,6.78689,29.7455,4.17944ZM24.3574,1.72602C24.1697,1.26149,23.7761,0.906541,23.2887,0.762205C21.5731,0.255605,19.791,-0.00119639,17.9994,0.00000381258C15.8187,0.00000381258,13.6899,0.370486,11.6745,1.10122C10.7057,1.45352,10.2924,2.57637,10.808,3.45511L12.9355,7.07371C13.3239,7.73262,14.1235,8.04214,14.8655,7.82082C15.8814,7.51699,16.9376,7.3629,17.9996,7.3636C18.7626,7.3636,19.5323,7.44547,20.2854,7.60794C20.9944,7.76016,21.7222,7.44468,22.0852,6.82783L24.2508,3.1468C24.5058,2.71413,24.5451,2.1907,24.3574,1.72602ZM34.3337,19.6371L30.0393,19.6371C29.2884,19.6367,28.63,20.1292,28.4313,20.8399C27.9057,22.7185,26.8595,24.4171,25.4092,25.747C24.8431,26.2665,24.7165,27.1004,25.1037,27.7593L27.2359,31.3828C27.4812,31.8011,27.9024,32.0915,28.3864,32.1762C28.4832,32.1926,28.5817,32.2008,28.6784,32.2008C29.0683,32.2013,29.446,32.0673,29.7455,31.8223C32.9378,29.2131,35.1469,25.583,35.9665,21.5972C36.0665,21.1161,35.9402,20.6163,35.6226,20.2368C35.3066,19.857,34.8333,19.6368,34.3337,19.6371ZM0.376135,15.7632C0.692116,16.1438,1.16603,16.3647,1.66666,16.3647L5.96105,16.3647C6.71021,16.3644,7.36726,15.8738,7.5675,15.1652C8.02109,13.5669,8.84706,12.0941,9.98017,10.863C10.4664,10.3367,10.5507,9.56236,10.1887,8.9471L8.02157,5.263C7.76613,4.8302,7.3237,4.53522,6.81966,4.46166C6.73946,4.45042,6.65853,4.44495,6.57751,4.44528C6.1568,4.44528,5.746,4.60263,5.43555,4.89099C2.6603,7.45571,0.791888,10.7448,0.0338876,14.4012C-0.0665431,14.8826,0.0591547,15.3828,0.376135,15.7632Z" fill="#4F85FB" fill-opacity="1"/></g></svg>

9
src/services/txn.ts

@ -59,3 +59,12 @@ export function getTxnRecord(txn: string, category: TxnRecord["category"]) {
}
return undefined;
}
export function peekTxnRecord(txn: string, category: TxnRecord["category"]) {
const record = txnCmdMap[txn];
// 只有属于指定category时,才返回,且返回后删除记录,节约内存
if (record.category === category) {
return record;
}
return undefined;
}

10
src/stores/status.ts

@ -2,6 +2,7 @@ import { ref, computed } from "vue";
import { defineStore } from "pinia";
import * as R from "ramda";
import type { StatusDatagram } from "@/services/socket";
import { BehaviorSubject, Subject } from "rxjs";
export const useStatusStore = defineStore("status", () => {
const status = ref<StatusDatagram["data"] | undefined>();
@ -14,3 +15,12 @@ export const useStatusStore = defineStore("status", () => {
return { status, setStatus };
});
// 进行中状态
export type OnGoingStatus = "idle" | "doorOpening" | "doorClosing" | "shaking" | "injecting" | "movingToAct" | "movingToHeat";
const onGoingStatusSub = new BehaviorSubject<OnGoingStatus>('idle');
export const onGoingStatusOb = onGoingStatusSub.asObservable();
export function setOnGoingStatus(status: OnGoingStatus) {
onGoingStatusSub.next(status)
}

110
src/views/components/Footer.vue

@ -1,16 +1,24 @@
<template>
<div class="h-[--footerHeight] bg-[--bgColor] footer">
<div class="footer_ins">
<van-icon name="discount-o" size="20" style="padding: 5px" />
<span class="ins_text text_size">等待指令</span>
<img
class="w-[18px] mx-4"
:class="statusStr !== '等待指令' ? 'ani' : ''"
src="@/assets/icon_operation.svg"
alt="op" />
<span class="ins_text text_size" @click="testStatus">{{ statusStr }}</span>
</div>
<div class="footer_normal">
<van-popover v-model:show="showWastePopover" placement="top-end" class="waste_popover">
<template #reference>
<div class="footer_container">
<div class="circle"></div>
<div class="waste_status text_size font-medium underline text-primary">溶液正常</div>
<div class="circle" :class="!!hasLowLiquid ? 'bg-[#EE8223]' : 'bg-[#26d574]'"></div>
<div
class="waste_status text_size font-medium underline"
:class="!!hasLowLiquid ? 'text-[#EE8223]' : 'text-primary'">
{{ !!hasLowLiquid ? "溶液余量低" : "溶液正常" }}
</div>
<div class="waste_detail">
<button class="text_size"><van-icon name="arrow" /></button>
</div>
@ -22,10 +30,74 @@
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, onUnmounted, computed } from "vue";
import Liquid from "./Liquid.vue";
const showContainerPopover = ref(false);
import { onGoingStatusOb, setOnGoingStatus } from "@/stores/status";
import { createWebSocket, sharedWsUrl } from "@/services/socket";
import { peekTxnRecord } from "@/services/txn";
import { useSettingStore } from "@/stores/setting";
const settingStore = useSettingStore();
const hasLowLiquid = computed(() => {
return settingStore.heatContainers.find(
c => c.capacityTotal - c.capacityUsed < (settingStore.liquidWarningSetting ? +settingStore.liquidWarningSetting.value : 0)
);
});
const showWastePopover = ref(false);
const statusStr = ref<string>("");
function testStatus() {
if (statusStr.value === "等待指令") {
setOnGoingStatus("doorOpening");
} else {
setOnGoingStatus("idle");
}
}
onMounted(() => {
const wsClient = createWebSocket(sharedWsUrl);
const subscription = wsClient.dataOb.subscribe(data => {
if (data.type === "cmd") {
const cmdInfo = peekTxnRecord(data.data.commandId, "task");
if (cmdInfo) {
if (
cmdInfo.command === "openDoor" ||
cmdInfo.command === "closeDoor" ||
cmdInfo.command === "startShakeUp" ||
cmdInfo.command === "injectFluid" ||
cmdInfo.command === "moveToActionArea" ||
cmdInfo.command === "moveToHeatArea"
) {
setOnGoingStatus("idle");
}
}
}
});
wsClient.connect();
const subscription2 = onGoingStatusOb.subscribe(status => {
if (status === "idle") {
statusStr.value = "等待指令";
} else if (status === "doorOpening") {
statusStr.value = "正在开门";
} else if (status === "doorClosing") {
statusStr.value = "正在关门";
} else if (status === "shaking") {
statusStr.value = "正在摇匀";
} else if (status === "injecting") {
statusStr.value = "正在加液";
} else if (status === "movingToAct") {
statusStr.value = "正在移至加液";
} else if (status === "movingToHeat") {
statusStr.value = "正在移至加热";
}
});
onUnmounted(() => {
subscription.unsubscribe();
subscription2.unsubscribe();
});
});
</script>
<style lang="scss" scoped>
@use "@/assets/style/mixin.scss" as *;
@ -33,14 +105,28 @@ const showWastePopover = ref(false);
.footer {
display: flex;
align-items: center;
justify-content: flex-end;
}
@keyframes rotateAnimation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.ani {
animation: rotateAnimation 3s linear infinite;
}
.footer_ins {
flex: 1 1 auto;
display: flex;
align-items: center;
border-radius: 5px;
border-radius: 4px;
background: #ffffff;
height: 2.5rem;
width: 39.625rem;
margin-left: 1.5rem;
@media (min-width: $lg) {
margin-left: 11.875rem;
}
@ -48,15 +134,16 @@ const showWastePopover = ref(false);
.footer_waste {
display: flex;
align-items: center;
border-radius: 5px;
border-radius: 4px;
min-width: 13.4375rem;
height: 2.5rem;
background: #ffffff;
margin-left: 1.5rem;
margin: 0 1.5rem;
}
.footer_normal {
margin-left: 3.125rem;
margin-left: 3rem;
margin-right: 1.5rem;
}
.text_size {
@ -67,13 +154,12 @@ const showWastePopover = ref(false);
display: flex;
align-items: center;
border-radius: 5px;
width: 15.625rem;
width: 13.75rem;
height: 2.5rem;
background: #ffffff;
.circle {
width: 1rem;
height: 1rem;
background-color: #26D574;
border-radius: 50%;
margin-left: 10px;
}

1480
src/views/graphite/index.vue
File diff suppressed because it is too large
View File

Loading…
Cancel
Save