123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- <template>
- <a-spin tip="Loading..." :spinning="loading">
- <div class="monitor-container">
- <div class="lr left-box">
- <Transition enter-active-class="animate__animated animate__fadeInLeft" leave-active-class="animate__animated animate__fadeOutLeft">
- <ventBox1 v-if="showModules">
- <template #title>
- <div>均压与低氧参数监测与设置</div>
- </template>
- <template #container>
- <div class="vent-flex-row-between auto-control mt-10px mb-10px">
- <div class="title">自动调节:</div>
- <a-radio-group :value="avePressSetting.isAuto" name="radioGroup" @change="changeAvePressState($event, 'isAuto')">
- <a-radio :value="false">关闭</a-radio>
- <a-radio :value="true">开启</a-radio>
- </a-radio-group>
- </div>
- <div class="vent-flex-row-between auto-control mt-10px mb-10px">
- <div class="title">调节类型:</div>
- <a-radio-group :value="avePressSetting.controlType" name="radioGroup" @change="changeAvePressState($event, 'controlType')">
- <a-radio value="o2">氧气</a-radio>
- <a-radio value="pressure">压差</a-radio>
- </a-radio-group>
- </div>
- <div>
- <!-- <div class="divider-line">开始条件</div>
- <div v-for="(item, index) in settingParam1" class="input-item" :key="index">
- <div class="title">{{ item.title }}:</div>
- <a-input-number class="input-value" v-model:value="formData[item.code]" placeholder="" />
- <div class="unit">{{ item.unit }}</div>
- </div> -->
- <div class="divider-line"></div>
- <div v-for="(item, index) in settingParam4" class="input-item" :key="index">
- <div class="title">{{ item.title }}:</div>
- <a-input-number class="input-value" v-model:value="avePressSetting[item.code]" placeholder="" :disabled="settingFormDisabled" />
- <div class="unit"> {{ item.unit }}</div>
- </div>
- <!-- <div class="divider-line">结束时间</div>
- <div v-for="(item, index) in settingParam3" class="input-item" :key="index">
- <div class="title">{{ item.title }}:</div>
- <a-input-number class="input-value" v-model:value="formData[item.code]" placeholder="" />
- <div class="unit">{{ item.unit }}</div>
- </div> -->
- </div>
- <div class="btn-box flex" style="text-align: center">
- <div class="btn btn1 flex-1" @click="editSettingForm">{{ settingFormDisabled ? '编辑' : '取消' }}</div>
- <div class="btn btn1 flex-1" @click="submitSettingForm">提交</div>
- </div>
- </template>
- </ventBox1>
- </Transition>
- <Transition enter-active-class="animate__animated animate__fadeInLeft" leave-active-class="animate__animated animate__fadeOutLeft">
- <ventBox1 v-if="showModules" class="mt-10px">
- <template #title>
- <div>均压工作面联动控制</div>
- </template>
- <template #container>
- <div class="vent-flex-row-between auto-control mt-10px mb-10px">
- <div class="title">风门与风门自动调节:</div>
- <a-radio-group :value="gateLinkage.isAuto" name="radioGroup" @change="changeIsAuto($event, gateLinkage.id)">
- <a-radio :value="false">关闭</a-radio>
- <a-radio :value="true">开启</a-radio>
- </a-radio-group>
- <div class="btn btn1" @click="() => openModal(false, { id: gateLinkage.id })">密码修改</div>
- </div>
- <div class="vent-flex-row-between auto-control mt-10px mb-10px">
- <div class="title">风机与风门自动调节:</div>
- <a-radio-group :value="avePressLinkage.isAuto" name="radioGroup" @change="changeIsAuto($event, avePressLinkage.id)">
- <a-radio :value="false">关闭</a-radio>
- <a-radio :value="true">开启</a-radio>
- </a-radio-group>
- <div class="btn btn1" @click="() => openModal(false, { id: avePressLinkage.id })">密码修改</div>
- </div>
- <!-- <div class="btn-box" style="text-align: center">
- </div> -->
- </template>
- </ventBox1>
- </Transition>
- </div>
- <ModuleCommon
- v-for="(cfg, index) in configs"
- :key="`svvmbcb${index}`"
- :show-style="cfg.showStyle"
- :module-data="cfg.moduleData"
- :module-name="cfg.moduleName"
- :device-type="cfg.deviceType"
- :data="selectData"
- :visible="showModules"
- />
- </div>
- <PasswordModal z-index="2000" :modal-is-show="modalVisible" modal-title="提交" @handle-ok="handleResolve" @handle-cancel="handleReject" />
- <UpdatePassword @register="updatePwdRegister" @submit="handleChangePassword" />
- <!-- <BasicModal title="风门状态监测" :mask="false" :bodyStyle="{ height: '50px' }" style="top: 20px" :show-ok-btn="false" @register="warnRegister2">
- {{ warnModalText2 }}
- </BasicModal>
- <BasicModal
- title="压差状态监测"
- :mask="false"
- :bodyStyle="{ height: '50px' }"
- centered
- ok-text="下发联动控制指令"
- @ok="autoControl"
- @register="warnRegister1"
- >
- {{ warnModalText1 }}
- </BasicModal>
- <BasicModal title="局扇状态监测" :mask="false" :bodyStyle="{ height: '50px' }" style="top: 420px" :show-ok-btn="false" @register="warnRegister3">
- {{ warnModalText3 }}
- </BasicModal> -->
- <div class="switch-button icon-goto right-10px top-70px" :class="{ 'right-390px': showModules }" @click="showModules = !showModules"></div>
- <!-- <div v-else class="switch-button icon-goto right-10px top-70px" @click="showModules = true"></div> -->
- </a-spin>
- </template>
- <script setup lang="ts">
- import { ref, onMounted, onUnmounted, defineProps, h } from 'vue';
- import { mountedThree, destroy, setModelType, updateText, play } from '../balancePress.threejs';
- import { list } from '../balancePress.api';
- import ModuleCommon from '../../../home/configurable/components/ModuleCommon.vue';
- import { useInitConfigs } from '../../../home/configurable/hooks/useInit';
- import { useGlobSetting } from '/@/hooks/setting';
- import { settingParam4 } from '../balancePress.data';
- import { Modal } from 'ant-design-vue';
- import ventBox1 from '/@/components/vent/ventBox1.vue';
- import PasswordModal from '../../comment/components/PasswordModal.vue';
- import UpdatePassword from '../../comment/components/UpdatePassword.vue';
- import { useModal } from '/@/components/Modal';
- import { connectWebSocket, onWebSocket } from '/@/hooks/web/useWebSocket';
- import { getToken } from '/@/utils/auth';
- import { useUserStore } from '/@/store/modules/user';
- import { usePressControl } from '../hooks/useControl';
- import dayjs from 'dayjs';
- // import { Config } from '../../../deviceManager/configurationTable/types';
- const props = defineProps({
- deviceId: {
- type: String,
- require: true,
- },
- });
- const { sysOrgCode } = useGlobSetting();
- const loading = ref(false);
- const showModules = ref(true);
- // 监测数据
- const selectData = ref();
- // https获取监测数据
- let timer: any = null;
- function getMonitor(flag?) {
- if (Object.prototype.toString.call(timer) === '[object Null]') {
- timer = setTimeout(
- async () => {
- if (props.deviceId) {
- const data = await getDataSource(props.deviceId);
- // Object.assign(selectData, data);
- updateText(selectData);
- selectData.value = data;
- }
- if (timer) {
- timer = null;
- }
- await getMonitor();
- },
- flag ? 0 : 1000
- );
- }
- }
- async function getDataSource(systemID) {
- const res = await list({ devicetype: 'sys', systemID });
- const result = Array.from(res.msgTxt).reduce(
- (obj: any, e: any) => {
- obj[e.type] = e;
- // if (true) {
- if (sysOrgCode === 'sdmtjtswmk') {
- if (e.type.startsWith('fanlocal')) {
- obj.fanlocal.datalist.push(...e.datalist);
- }
- if (e.type.startsWith('safetymonitor')) {
- e.datalist.forEach((ele) => {
- if (ele.strinstallpos.includes('风门')) {
- obj.gate.datalist.push(ele);
- } else if (ele.strinstallpos.includes('风窗')) {
- obj.window.datalist.push(ele);
- } else if (ele.strinstallpos.includes('工作面')) {
- obj.work_surface.datalist.push(ele);
- } else {
- obj.others.datalist.push(ele);
- }
- });
- }
- }
- return obj;
- },
- {
- /** 用于归类fanlocal */
- fanlocal: { datalist: [] },
- /** 用于归类gate */
- gate: { datalist: [] },
- /** 用于归类window */
- window: { datalist: [] },
- /** 用于归类work_surface */
- work_surface: { datalist: [] },
- others: { datalist: [] },
- }
- );
- return result;
- }
- const {
- avePressSetting,
- avePressLinkage,
- gateLinkage,
- formData,
- getAvePress,
- changePassword,
- linkageControl,
- settingControl,
- autoControl,
- cancelControl,
- } = usePressControl();
- const modalVisible = ref(false);
- const { configs, fetchConfigs } = useInitConfigs();
- const [updatePwdRegister, { openModal, closeModal, setModalProps }] = useModal();
- function handleChangePassword(values) {
- setModalProps({ confirmLoading: true });
- changePassword(values).finally(() => {
- setModalProps({ confirmLoading: false });
- closeModal();
- });
- }
- function changeIsAuto({ target }, id) {
- formData.value.isAuto = target.value;
- modalVisible.value = true;
- resolver = (password) => {
- linkageControl(
- { password, id },
- {
- isAuto: formData.value.isAuto,
- }
- ).finally(() => {
- modalVisible.value = false;
- });
- };
- }
- function changeAvePressState({ target }, key) {
- formData.value.temp = target.value;
- modalVisible.value = true;
- resolver = (password) => {
- settingControl(
- { password, id: avePressSetting.value.id },
- {
- [key]: formData.value.temp,
- }
- ).finally(() => {
- modalVisible.value = false;
- });
- };
- }
- // function submitLinkageForm(password) {}
- function submitSettingForm() {
- modalVisible.value = true;
- resolver = (password) => {
- settingControl({ password, id: avePressSetting.value.id }, avePressSetting.value).finally(() => {
- modalVisible.value = false;
- settingFormDisabled.value = true;
- });
- };
- }
- let resolver: any = null;
- let rejecter: any = null;
- function handleResolve(password) {
- if (resolver) {
- resolver(password);
- } else {
- modalVisible.value = false;
- }
- resolver = null;
- rejecter = null;
- }
- function handleReject() {
- if (rejecter) {
- rejecter();
- } else {
- modalVisible.value = false;
- }
- resolver = null;
- rejecter = null;
- }
- // const [warnRegister1, warnModal1] = useModal();
- // const [warnRegister2, warnModal2] = useModal();
- // const [warnRegister3, warnModal3] = useModal();
- let warnModal1: { destroy: () => void } | null = null;
- let warnModal2: { destroy: () => void } | null = null;
- let warnModal3: { destroy: () => void } | null = null;
- // const warnModalText1 = ref('');
- // const warnModalText2 = ref('');
- // const warnModalText3 = ref('');
- // 初始化 WebSocket
- function initWebSocket() {
- const token = getToken();
- const userStore = useUserStore();
- const glob = useGlobSetting();
- // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
- const url = `${glob.wsUrl?.replace('https://', 'wss://').replace('http://', 'ws://')}/websocket/${userStore.getUserInfo.id}?token=${token}`;
- connectWebSocket(url);
- onWebSocket((data: any) => {
- if (data.cmd !== 'topic' || data.topic !== 'warn') return;
- if (!data.msgTxt) return;
- const { info = '', type = '', avgPressureLogId, date } = JSON.parse(data.msgTxt);
- const datestr = dayjs(date).format('YYYY-MM-DD HH:mm:ss');
- switch (type) {
- case 'o2':
- // 如果已经存在报警模态框,则不需要处理
- if (warnModal1) break;
- warnModal1 = Modal.confirm({
- title: data.msgTitle,
- content: h('div', { style: { color: '#fff' } }, [h('p', datestr), h('p', info)]),
- centered: true,
- okText: '下发调节指令',
- mask: true,
- class: 'balancePress',
- onOk() {
- // 点击确定按钮后,执行调节指令。调节指令需要确认密码,所以需要先弹出密码框
- return new Promise((resolve, reject) => {
- modalVisible.value = true;
- // 弹出密码框后,输入密码并验证成功则关闭密码弹窗和报警弹窗,失败则关闭密码弹窗但不关闭报警弹窗
- resolver = (password) => {
- autoControl({ password, id: avePressSetting.value.id }, { avgPressLogId: avgPressureLogId })
- .then(() => {
- modalVisible.value = false;
- resolve(true);
- warnModal1?.destroy();
- warnModal1 = null;
- })
- .catch(() => {
- modalVisible.value = false;
- reject();
- });
- };
- // 弹出密码框取消操作则关闭密码弹窗但不关闭报警弹窗
- rejecter = () => {
- modalVisible.value = false;
- reject();
- };
- });
- },
- onCancel() {
- return cancelControl({}, { avgPressLogId: avgPressureLogId }).finally(() => {
- warnModal1?.destroy();
- warnModal1 = null;
- });
- },
- });
- // warnModalText1.value = info;
- // warnModal1.openModal();
- break;
- case 'pressure':
- // warnModalText1.value = info;
- // warnModal1.openModal();
- if (warnModal1) break;
- warnModal1 = Modal.confirm({
- title: data.msgTitle,
- content: h('div', { style: { color: '#fff' } }, [h('p', datestr), h('p', info)]),
- centered: true,
- okText: '下发调节指令',
- mask: true,
- class: 'balancePress',
- onOk() {
- // 点击确定按钮后,执行调节指令。调节指令需要确认密码,所以需要先弹出密码框
- return new Promise((resolve, reject) => {
- modalVisible.value = true;
- // 弹出密码框后,输入密码并验证成功则关闭密码弹窗和报警弹窗,失败则关闭密码弹窗但不关闭报警弹窗
- resolver = (password) => {
- autoControl({ password, id: avePressSetting.value.id }, { avgPressLogId: avgPressureLogId })
- .then(() => {
- modalVisible.value = false;
- resolve(true);
- warnModal1?.destroy();
- warnModal1 = null;
- })
- .catch(() => {
- modalVisible.value = false;
- reject();
- });
- };
- // 弹出密码框取消操作则关闭密码弹窗但不关闭报警弹窗
- rejecter = () => {
- modalVisible.value = false;
- reject();
- };
- });
- },
- onCancel() {
- return cancelControl({}, { avgPressLogId: avgPressureLogId }).finally(() => {
- warnModal1?.destroy();
- warnModal1 = null;
- });
- },
- });
- break;
- case 'gate':
- if (warnModal2) break;
- warnModal2 = Modal.warning({
- title: data.msgTitle,
- content: info,
- mask: true,
- class: 'balancePress',
- onOk: () => {
- warnModal2?.destroy();
- warnModal2 = null;
- },
- });
- break;
- case 'fansys':
- if (warnModal3) break;
- warnModal3 = Modal.warning({
- title: data.msgTitle,
- content: info,
- mask: true,
- class: 'balancePress',
- style: 'top: 700px',
- onOk: () => {
- warnModal3?.destroy();
- warnModal3 = null;
- },
- });
- break;
- default:
- break;
- }
- });
- }
- const settingFormDisabled = ref(true);
- function editSettingForm() {
- settingFormDisabled.value = !settingFormDisabled.value;
- /** 如果取消了编辑模式,那么需要重置表单 */
- if (settingFormDisabled.value) {
- getAvePress();
- }
- }
- onMounted(() => {
- initWebSocket();
- // getMonitor()
- fetchConfigs('balancePressHome');
- getAvePress();
- loading.value = true;
- mountedThree().then(async () => {
- await setModelType('balancePressTun'); //balancePressBase
- loading.value = false;
- timer = null;
- await getMonitor(true);
- play('startSmoke', 'top', 30, 'open', 0);
- });
- // loading.value = false;
- // timer = null;
- // getMonitor(true);
- });
- onUnmounted(() => {
- destroy();
- if (timer) {
- clearTimeout(timer);
- }
- });
- </script>
- <style lang="less" scoped>
- @import '/@/design/vent/modal.less';
- @import '../../comment/less/workFace.less';
- @ventSpace: zxm;
- .monitor-container {
- margin-top: 60px;
- }
- .switch-button {
- width: 34px;
- height: 34px;
- position: fixed;
- // right: 5px;
- // bottom: 300px;
- z-index: 1000;
- background-repeat: no-repeat;
- background-size: 100% 100%;
- pointer-events: auto;
- transition: right 1s;
- }
- .icon-goto {
- --image-monitor-goto: url('/@/assets/images/company/monitor-goto.png');
- background-image: var(--image-monitor-goto);
- }
- .divider-line {
- border-bottom: 1px solid white;
- }
- </style>
- <style>
- /* .balancePress .zxm-modal-confirm-title {
- font-size: 20px;
- } */
- .balancePress .zxm-modal-confirm-content {
- font-size: 22px;
- }
- </style>
|