Browse Source

响应设备工作状态

master
zhangjiming 5 months ago
parent
commit
27a948d0b8
  1. 4
      src/App.vue
  2. 11
      src/components/FooterBar.vue
  3. 11
      src/services/globalCmd/globalCmd.ts
  4. 18
      src/services/wsTypes.ts
  5. 9
      src/stores/equipmentStatus.ts
  6. 8
      src/style.css
  7. 52
      src/views/HomeView.vue
  8. 38
      src/views/PreSpray.vue
  9. 14
      src/views/SprayView.vue

4
src/App.vue

@ -13,7 +13,9 @@ const router = useRouter();
const wsClient = createWebSocket(sharedWsUrl);
wsClient.dataOb.subscribe(data => {
if (data.type === "status") {
if (data.type === "ing") {
equipmentStatusStore.setWorkStatus(data.data.workStatus);
} else if (data.type === "status") {
equipmentStatusStore.setEquipmentStatus(data["data"]);
} else if (data.type === "warn") {
if (data.data.code === "wash_complete") {

11
src/components/FooterBar.vue

@ -1,7 +1,12 @@
<template>
<header class="h-[--headerHeight] bg-primary flex items-center text-white px-[--borderWidth]">
<section class="bg-[#335AA5] px-4 py-2 rounded flex items-center gap-4">
<span>当前湿度{{ equipmentStore.equipmentStatus.humidity }}%RH</span>
<span>当前湿度{{ statusStore.equipmentStatus.humidity }}%RH</span>
<!-- <span>当前温度18</span> -->
</section>
<section class="bg-[#335AA5] ml-6 px-4 py-2 rounded flex items-center gap-4">
<span>当前设备{{ workStatusDescMap[statusStore.workStatus] }}</span>
<!-- <span>当前温度18</span> -->
</section>
<Time class="ml-auto text-lg"></Time>
@ -25,10 +30,10 @@
import { useRoute, useRouter } from "vue-router";
import Time from "./Time.vue";
import { useEquipmentStatusStore } from "@/stores/equipmentStatus";
import { workStatusDescMap } from "@/services/wsTypes";
const route = useRoute();
const router = useRouter();
const equipmentStore = useEquipmentStatusStore();
const statusStore = useEquipmentStatusStore();
function onMenuBtnClick() {
if (route.path !== "/") {

11
src/services/globalCmd/globalCmd.ts

@ -71,15 +71,22 @@ export type SprayParam = {
} & WorkType;
export function startSpray(params: SprayParam) {
return httpRequest<BaseResponse>({ url: "/api/cmd/startWork", params, method: "POST" });
return httpRequest<BaseResponse>({ url: "/api/cmd/startWork", params: { params }, method: "POST" });
}
export function startWash(params: Record<string, any>) {
export type WashType = "injector" | "nozzle";
export function startWash(params: { type: WashType }) {
return httpRequest<BaseResponse>({ url: "/api/cmd/startWash", params, method: "POST" });
}
export function stopWash(params: Record<string, any>) {
return httpRequest<BaseResponse>({ url: "/api/cmd/stopWash", params, method: "POST" });
}
export function startPrefill(params: Record<string, any>) {
return httpRequest<BaseResponse>({ url: "/api/cmd/startPrefill", params, method: "POST" });
}
export function stopPrefill(params: Record<string, any>) {
return httpRequest<BaseResponse>({ url: "/api/cmd/stopPrefill", params, method: "POST" });
}
export function startDehumidify(params: { humidity: number }) {
return httpRequest<BaseResponse>({ url: "/api/cmd/startDehumidify", params, method: "POST" });
}

18
src/services/wsTypes.ts

@ -19,6 +19,22 @@ export type WarnDatagram = {
};
};
export type WorkStatus = "idle" | "washing" | "prefilling" | "dehumidifying" | "spraying";
export type DoingStatusDatagram = {
type: "ing";
data: {
workStatus: WorkStatus;
};
};
export const workStatusDescMap: { [k in WorkStatus]: string } = {
idle: "空闲",
washing: "正在清洗",
prefilling: "正在预充",
dehumidifying: "正在除湿",
spraying: "正在喷涂",
};
export type StatusDatagram = {
type: "status"; // 状态
data: EquipmentStatusType;
@ -102,4 +118,4 @@ export const defaultStatus: EquipmentStatusType = {
syringePumpNormal: false,
};
export type Datagram = CmdDatagram | WarnDatagram | StatusDatagram;
export type Datagram = CmdDatagram | WarnDatagram | StatusDatagram | DoingStatusDatagram;

9
src/stores/equipmentStatus.ts

@ -1,7 +1,7 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import * as R from "ramda";
import { defaultStatus, type EquipmentStatusType } from "@/services/wsTypes";
import { defaultStatus, type EquipmentStatusType, type WorkStatus } from "@/services/wsTypes";
export const useEquipmentStatusStore = defineStore("equipmentStatus", () => {
const equipmentStatus = ref<EquipmentStatusType>(defaultStatus);
@ -11,8 +11,15 @@ export const useEquipmentStatusStore = defineStore("equipmentStatus", () => {
}
};
const workStatus = ref<WorkStatus>("idle");
const setWorkStatus = (s: WorkStatus) => {
workStatus.value = s;
};
return {
equipmentStatus,
setEquipmentStatus,
workStatus,
setWorkStatus
};
});

8
src/style.css

@ -20,6 +20,10 @@
border-radius: 4px;
color: white;
}
.btn-dark:disabled {
background: #ccc;
}
.btn-light {
display: flex;
justify-content: center;
@ -29,6 +33,10 @@
border-radius: 4px;
color: var(--primaryColor);
}
.btn-light:disabled {
background: #ccc;
color: #fff;
}
.main-page {
/* height: calc(100vh - var(--headerHeight));
background: linear-gradient(180deg, #dfe8f7 0%, #ffffff 100%); */

52
src/views/HomeView.vue

@ -32,6 +32,30 @@
<img src="@/assets/entry/entry_icon_5.svg" alt="icon" class="w-[80px] absolute right-4 top-4" />
</div>
</div>
<van-overlay v-if="showWashDialog" :show="true">
<div class="flex justify-center items-center h-full">
<div class="min-w-[480px] max-w-[540px] text-primary bg-white rounded-lg">
<h1 class="my-8 text-lg font-medium text-center px-8">提示</h1>
<div class="text-lg px-4 text-center">
{{ statusStore.workStatus === "washing" ? "设备正在清洗中,是否停止清洗" : "请选择清洗类型:" }}
</div>
<footer v-if="statusStore.workStatus === 'washing'" class="flex justify-center items-center gap-6 py-10">
<button class="btn-dark px-8 py-2 text-lg min-w-[120px]" @click="onStopWash">停止清洗</button>
<button class="btn-light px-8 py-2 text-lg min-w-[120px]" @click="showWashDialog = false">取消</button>
</footer>
<footer v-else class="flex flex-col justify-center items-center gap-6 py-10">
<button class="btn-dark px-8 py-2 text-lg min-w-[120px]" @click="onStartWash('injector')">
清洗注射器管路
</button>
<button class="btn-dark px-8 py-2 text-lg min-w-[120px]" @click="onStartWash('nozzle')">
清洗喷涂部分
</button>
<button class="btn-light px-8 py-2 text-lg min-w-[120px]" @click="showWashDialog = false">取消</button>
</footer>
</div>
</div>
</van-overlay>
<van-overlay v-if="showDialog" :show="true">
<div class="flex justify-center items-center h-full">
<Dialog
@ -49,11 +73,15 @@
<script setup lang="ts">
import type { DialogParam } from "@/components/Dialog.vue";
import { startWash } from "@/services/globalCmd/globalCmd";
import { startWash, stopWash, type WashType } from "@/services/globalCmd/globalCmd";
import { ElMessage } from "element-plus";
import { ref } from "vue";
import { useRouter } from "vue-router";
import Dialog from "@/components/Dialog.vue";
import { useEquipmentStatusStore } from "@/stores/equipmentStatus";
const router = useRouter();
const statusStore = useEquipmentStatusStore();
const dialogContent = ref<DialogParam>({
title: "提示",
@ -65,8 +93,8 @@ const dialogContent = ref<DialogParam>({
});
const showDialog = ref(false);
const showWashDialog = ref(false);
const router = useRouter();
function onEnvironmentEntryClick() {
router.push("/environment");
}
@ -86,11 +114,27 @@ function onPrintEntryClick() {
router.push("/print");
}
function onWashEntryClick() {
showDialog.value = true;
if (statusStore.workStatus === "idle" || statusStore.workStatus === "washing") {
showWashDialog.value = true;
} else {
ElMessage.warning("设备正在工作中,请稍候清洗");
}
}
function onOk() {
showDialog.value = false;
startWash({}).then(res => {
}
function onStartWash(type: WashType) {
showWashDialog.value = false;
startWash({ type }).then(res => {
if (res.success) {
} else {
ElMessage.error(res.msg);
}
});
}
function onStopWash() {
showWashDialog.value = false;
stopWash({}).then(res => {
if (res.success) {
} else {
ElMessage.error(res.msg);

38
src/views/PreSpray.vue

@ -4,7 +4,9 @@
<main class="mt-[43px] border border-[#D6D6D6] bg-white rounded-b-md rounded-tr-md px-6 py-6">
<div class="flex items-center gap-6">
<p class="text-lg">清洗管道</p>
<button class="btn-dark px-8 py-2 text-lg" @click="onStartWash">开始清洗</button>
<button :disabled="statusStore.workStatus !== 'idle'" class="btn-dark px-8 py-2 text-lg" @click="onStartWash('injector')">清洗注射器管路</button>
<button :disabled="statusStore.workStatus !== 'idle'" class="btn-dark px-8 py-2 text-lg" @click="onStartWash('nozzle')">清洗喷涂部分</button>
<button :disabled="statusStore.workStatus !== 'washing'" class="btn-dark px-8 py-2 text-lg" @click="onStopWash">停止清洗</button>
</div>
</main>
<header
@ -18,7 +20,8 @@
<main class="mt-[43px] border border-[#D6D6D6] bg-white rounded-b-md rounded-tr-md px-6 py-6">
<div class="flex items-center gap-6">
<p class="text-lg">预充管道</p>
<button class="btn-dark px-8 py-2 text-lg" @click="onStartPrefill">开始预充</button>
<button :disabled="statusStore.workStatus !== 'idle'" class="btn-dark px-8 py-2 text-lg" @click="onStartPrefill">开始预充</button>
<button :disabled="statusStore.workStatus !== 'prefilling'" class="btn-dark px-8 py-2 text-lg" @click="onStopPrefill">结束预充</button>
</div>
</main>
<header
@ -31,7 +34,9 @@
<section class="flex flex-col relative text-primary mb-4">
<main class="mt-[43px] border border-[#D6D6D6] bg-white rounded-b-md rounded-tr-md px-6 py-6">
<div class="flex items-center">
<p class="text-lg">当前湿度 <span class="text-[28px] font-semibold">50</span> %RH</p>
<p class="text-lg">
当前湿度 <span class="text-[28px] font-semibold">{{ statusStore.equipmentStatus.humidity }}</span> %RH
</p>
<p class="text-lg mx-6">
要求湿度<input
type="number"
@ -39,7 +44,7 @@
class="border-none outline-none h-[32px] w-[60px] mx-2 bg-[#E8ECF7] text-primary font-medium rounded-md text-lg text-center" />%RH
</p>
<button class="btn-dark px-8 py-2 text-lg" @click="onStartDehumidify">开始除湿</button>
<button :disabled="statusStore.workStatus !== 'idle'" class="btn-dark px-8 py-2 text-lg" @click="onStartDehumidify">开始除湿</button>
</div>
</main>
<header
@ -107,8 +112,10 @@ import { ref } from "vue";
import Dialog, { type DialogParam } from "@/components/Dialog.vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import { startDehumidify, startPrefill, startWash } from "@/services/globalCmd/globalCmd";
import { startDehumidify, startPrefill, startWash, stopPrefill, stopWash, type WashType } from "@/services/globalCmd/globalCmd";
import { useEquipmentStatusStore } from "@/stores/equipmentStatus";
const router = useRouter();
const statusStore = useEquipmentStatusStore();
const dialogContent = ref<DialogParam>({
title: "已完成",
@ -161,8 +168,17 @@ function onGoSpray() {
showDialog.value = true;
}
function onStartWash() {
startWash({}).then(res => {
function onStartWash(type: WashType) {
startWash({ type }).then(res => {
if (res.success) {
} else {
ElMessage.error(res.msg);
}
});
}
function onStopWash() {
stopWash({}).then(res => {
if (res.success) {
} else {
ElMessage.error(res.msg);
@ -178,5 +194,13 @@ function onStartPrefill() {
}
});
}
function onStopPrefill() {
stopPrefill({}).then(res => {
if (res.success) {
} else {
ElMessage.error(res.msg);
}
});
}
</script>
<style lang="scss" scoped></style>

14
src/views/SprayView.vue

@ -2,8 +2,15 @@
<div class="px-6 pt-4 pb-3 flex justify-between">
<div class="w-full">
<div class="flex items-center mb-3 gap-5">
<button class="btn-dark px-8 py-2 text-lg" @click="onStartSpray">开始喷涂</button>
<button class="btn-light px-8 py-2 text-lg" @click="onStopSpray">停止喷涂</button>
<button :disabled="statusStore.workStatus !== 'idle'" class="btn-dark px-8 py-2 text-lg" @click="onStartSpray">
开始喷涂
</button>
<button
:disabled="statusStore.workStatus !== 'spraying'"
class="btn-light px-8 py-2 text-lg"
@click="onStopSpray">
停止喷涂
</button>
<section class="flex items-center gap-3 px-4 text-base ml-auto">
<div class="flex items-center">
<span class="self-center text-right text-primary font-medium mr-3">选择基质</span>
@ -119,6 +126,7 @@ import { useSettingStore } from "@/stores/setting";
import type { CraftItem } from "@/services/matrix/type";
import { createCraft, getListByMatrixId, updateCraft } from "@/services/matrix/craft";
import SprayParam from "@/components/SprayParam.vue";
import { useEquipmentStatusStore } from "@/stores/equipmentStatus";
const defaultCraft: Partial<CraftItem> = {
id: 0,
@ -137,7 +145,7 @@ const defaultCraft: Partial<CraftItem> = {
};
const settingStore = useSettingStore();
const statusStore = useEquipmentStatusStore();
const selectMatrixId = ref<number>(settingStore.matrixList.length > 0 ? settingStore.matrixList[0].id : 0);
const craftList = ref<CraftItem[]>([]);

Loading…
Cancel
Save