From 97dc174b26461df1395394c02401bb51dd6376bc Mon Sep 17 00:00:00 2001
From: bsw215583320 <baoshiwei121@163.com>
Date: 星期一, 04 十二月 2023 08:03:53 +0800
Subject: [PATCH] 增加opc设备维护和控制功能
---
src/views/dashboard/control/api.ts | 14
src/views/dry/components/DryOpcDeviceModal.vue | 66 ++++
src/views/dry/DryOpcDeviceList.vue | 174 +++++++++++
src/assets/images/dry/control/light.png | 0
src/assets/images/dry/control/cam0.png | 0
src/views/dashboard/control/index.vue | 296 +++++++++++++++++++
src/views/dry/sql/DryOpcDevice_menu_insert.sql | 26 +
src/assets/images/dry/control/light-close.png | 0
src/views/dry/api/DryOpcDevice.api.ts | 64 ++++
src/views/dry/components/DryOpcDeviceForm.vue | 70 ++++
src/views/dry/dataDefine/DryOpcDevice.data.ts | 109 +++++++
src/assets/images/dry/control/cam1.png | 0
src/views/dry/bigScreen/BigWorkShop.vue | 51 ++
src/assets/images/dry/control/cam.png | 0
src/assets/images/dry/control/cam-close.png | 0
15 files changed, 850 insertions(+), 20 deletions(-)
diff --git a/src/assets/images/dry/control/cam-close.png b/src/assets/images/dry/control/cam-close.png
new file mode 100644
index 0000000..0218b87
--- /dev/null
+++ b/src/assets/images/dry/control/cam-close.png
Binary files differ
diff --git a/src/assets/images/dry/control/cam.png b/src/assets/images/dry/control/cam.png
new file mode 100644
index 0000000..bb963f1
--- /dev/null
+++ b/src/assets/images/dry/control/cam.png
Binary files differ
diff --git a/src/assets/images/dry/control/cam0.png b/src/assets/images/dry/control/cam0.png
new file mode 100644
index 0000000..1f285b9
--- /dev/null
+++ b/src/assets/images/dry/control/cam0.png
Binary files differ
diff --git a/src/assets/images/dry/control/cam1.png b/src/assets/images/dry/control/cam1.png
new file mode 100644
index 0000000..c3a2695
--- /dev/null
+++ b/src/assets/images/dry/control/cam1.png
Binary files differ
diff --git a/src/assets/images/dry/control/light-close.png b/src/assets/images/dry/control/light-close.png
new file mode 100644
index 0000000..9c64966
--- /dev/null
+++ b/src/assets/images/dry/control/light-close.png
Binary files differ
diff --git a/src/assets/images/dry/control/light.png b/src/assets/images/dry/control/light.png
new file mode 100644
index 0000000..057ead2
--- /dev/null
+++ b/src/assets/images/dry/control/light.png
Binary files differ
diff --git a/src/views/dashboard/control/api.ts b/src/views/dashboard/control/api.ts
index 76a5c9f..703be84 100644
--- a/src/views/dashboard/control/api.ts
+++ b/src/views/dashboard/control/api.ts
@@ -2,6 +2,8 @@
enum Api {
sendCommand = '/dry/real/sendCommand',
+ sendWriteCommand = '/dry/opc/sendWriteCommand',
+ listAll = '/dry/dryOpcDevice/listAll'
}
/**
* 鍙戦�佸懡浠�
@@ -9,3 +11,15 @@
*/
export const sendCommand = (params) => defHttp.post({ url: Api.sendCommand, params },{ isTransformResponse: false });
+/**
+ * 鍙戦�丱PC鍐欐寚浠�
+ */
+
+export const sendWriteCommand = (params) => defHttp.post({url: Api.sendWriteCommand, params},{isTransformResponse: false})
+
+/**
+ * 鏌ヨ鎵�鏈塐PC璁惧
+ */
+
+export const listAll = (params) => defHttp.get({url:Api.listAll, params})
+
diff --git a/src/views/dashboard/control/index.vue b/src/views/dashboard/control/index.vue
index 5085e12..e9d321d 100644
--- a/src/views/dashboard/control/index.vue
+++ b/src/views/dashboard/control/index.vue
@@ -7,12 +7,125 @@
</a-modal>
<div class="app">
- <a-card title="鎸囦护">
+ <a-row>
+ <a-card title="鐓ф槑" style="width: 60%">
+ <div class="light-box">
+ <div v-for="item in lightList" :key="item.identifier" class="center">
+ <!-- <a-button v-if="item.type == 0" type="primary" class="com-btn"
+ @click="deviceClick(item)">
+ {{ item.name }}
+ </a-button> -->
+ <div v-if="item.type==0" @click="deviceClick(item)">
+ <div :class="[ item.value?'lightOn':'lightOff' ,'device']">
+
+
+ </div>
+ <div class="text-center">{{ item.name }}</div>
+
+ </div>
+ </div>
+
+ </div>
+ </a-card>
+ <a-card title="鐩戞帶" style="width: 35%; margin-left: 10px;">
+ <div class="monitor-box">
+ <div v-for="item in lightList" :key="item.identifier" class="center" >
+ <div v-if="item.type==1" @click="deviceClick(item)">
+ <div :class="[ item.value?'camOn':'camOff' ,'device']">
+
+
+ </div>
+ <div class="text-center">{{ item.name }}</div>
+ </div>
+ </div>
+ </div>
+ </a-card>
+
+ </a-row>
+
+ <a-card title="鎸囦护" style="margin-top: 10px">
<div class="com-box">
- <a-button v-for="item in comList" :key="item.id" type="primary" class="com-btn"
+ <!-- <a-button v-for="item in comList" :key="item.id" type="primary" class="com-btn"
@click="comClick(item)">
{{ item.title }}
+ </a-button> -->
+ <div style="width: 500px;">
+
+ <a-row class="button-row">
+ <a-button type="primary" @click="clickButton(1010, '骞茬嚗鍚姩')" class="com-btn">
+ <div> <PlayCircleOutlined style="font-size: 20px;" /> </div>
+ <div> 骞茬嚗鍚姩 </div>
+
</a-button>
+ <!-- <a-button type="normal" @click="clickButton(1012)" class="com-btn">
+ <div> <SplitCellsOutlined style="font-size: 20px;" /> </div>
+ <div> 鍚庨棬寮�鍏� </div>
+
+ </a-button> -->
+ <a-button type="default" @click="clickButton(1003,'婊氱瓛鍗�')" class="com-btn w300">
+ <div> <UpCircleOutlined style="font-size: 20px;" /> </div>
+ <div> 婊氱瓛鍗� </div>
+
+ </a-button>
+ <a-button type="info" @click="clickButton(1014, '寮�闂ㄨ瀵�')" class="com-btn">
+ <div> <SettingOutlined style="font-size: 20px;" /> </div>
+ <div> 寮�闂ㄨ瀵� </div>
+
+ </a-button>
+ </a-row>
+ <a-row class="button-row">
+ <a-button type="normal" @click="clickButton(1005,'婊氱瓛姝h浆')" class="com-btn h100">
+ <div> <RedoOutlined style="font-size: 20px;" /> </div>
+ <div> 婊氱瓛姝h浆 </div>
+ </a-button>
+ <a-button type="danger" @click="clickButton(1007,'鍋滄')" class="com-btn h100 w300 " >
+ <div> <PauseCircleOutlined style="font-size: 20px;" /> </div>
+ <div> 鍋滄 </div>
+ </a-button>
+ <a-button type="normal" @click="clickButton(1006,'婊氱瓛鍙嶈浆')" class="com-btn h100">
+ <div> <UndoOutlined style="font-size: 20px;" /> </div>
+ <div> 婊氱瓛鍙嶈浆 </div>
+ </a-button>
+ </a-row>
+ <a-row class="button-row">
+ <a-button type="success" @click="clickButton(1015,'鍑烘枡')" class="com-btn">
+ <div> <DownloadOutlined style="font-size: 20px;" /> </div>
+ <div> 鍑烘枡 </div>
+
+ </a-button>
+ <!-- <a-button type="normal" @click="clickButton(1010)" class="com-btn">
+ <div> <SplitCellsOutlined style="font-size: 20px;" /> </div>
+ <div> 鍓嶉棬寮�鍏� </div>
+ </a-button> -->
+ <a-button type="normal" @click="clickButton(1004,'婊氱瓛闄�')" class="com-btn w300">
+ <div> <DownCircleOutlined style="font-size: 20px;" /> </div>
+ <div> 婊氱瓛闄� </div>
+ </a-button>
+ <a-button type="normal" @click="clickButton(1013,'鐑鍚姩')" class="com-btn">
+ <div> <FireOutlined style="font-size: 20px;" /> </div>
+ <div> 鐑鍚姩 </div>
+
+ </a-button>
+ </a-row>
+
+ </div>
+ <div style="margin-left: 100px;">
+ <div>
+ <a-button type="warning" @click="clickButton(1017,'鎵嬪姩/鑷姩')" class="com-btn">
+ <div> <SyncOutlined style="font-size: 20px;" /> </div>
+ <div> 鎵嬪姩/鑷姩 </div>
+
+ </a-button>
+ </div>
+ <div>
+ <a-button type="normal" @click="clickButton(1016,'娓呴櫎')" class="com-btn">
+ <div> <ClearOutlined style="font-size: 20px;" /> </div>
+ <div> 娓呴櫎 </div>
+
+ </a-button>
+ </div>
+ </div>
+
</div>
</a-card>
<a-card title="鎺у埗鍙�" style="margin-top: 10px">
@@ -26,16 +139,28 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
-import { sendCommand } from "./api";
+import { sendCommand, sendWriteCommand, listAll } from "./api";
+import { useGlobSetting } from '/@/hooks/setting';
+import { connectWebSocket, onWebSocket } from '/@/hooks/web/useWebSocket';
+import { useUserStore } from '/@/store/modules/user';
+import { RedoOutlined ,SettingOutlined, UndoOutlined,FireOutlined, SplitCellsOutlined, DownloadOutlined, PauseCircleOutlined,ClearOutlined, SyncOutlined,PlayCircleOutlined, SwapOutlined , UpCircleOutlined, DownCircleOutlined, LeftCircleOutlined, RightCircleOutlined} from '@ant-design/icons-vue';
+
const visible = ref<boolean>(false);
-
+ const glob = useGlobSetting();
interface Commant {
id: number;
title: string;
icon: string;
}
+interface Device {
+ name: string;
+ identifier: string;
+ value: boolean;
+ sort_order: number;
+}
+const userStore = useUserStore();
const logList = ref<string[]>([]);
const comList = ref<Commant[]>([
{
@@ -88,6 +213,9 @@
icon: "caret-right-outlined"
}]);
+
+const lightList = ref<Device[]>([]);
+const monitorList = ref<Device[]>([]);
function comClick(item) {
addLog("鍙戦��", item.title);
//鍙戦�佹寚浠�
@@ -133,9 +261,81 @@
visible.value = false;
};
+/**
+ * 鏌ヨ鐏拰鎽勫儚澶村垪琛�
+ */
+function queryDevice() {
+ listAll({}).then(res => {
+ console.log("ress000:",res);
+ lightList.value = res
+ })
+
+
+}
+
+function clickButton(cmd, msg) {
+ console.log("target::::",cmd);
+ var params = { msg: msg, code: cmd, tenantId: 1003, machineId: "GM001" };
+ sendCommand(params).then(res => {
+ if (res.success) {
+ addLog("鍝嶅簲", res.message);
+ console.info(res);
+ } else {
+ console.info(res);
+ addLog("鍝嶅簲", res.message);
+ }
+
+ });
+}
+
+
+
+
+function deviceClick(item) {
+ //console.log("item===",item.value);
+ let params = {code: item.identifier, msg: !item.value}
+ sendWriteCommand(params).then(res => {
+ console.log("鍐欐寚浠ょ粨鏋滐細锛�", res)
+ if(res.success) {
+ lightList.value.forEach(device => {
+ if(device.identifier == item.identifier) {
+ device.value = !item.value
+ }
+ })
+ }
+ })
+
+}
+
+ // 鍒濆鍖� WebSocket
+ function initWebSocket() {
+
+ let user = userStore.getUserInfo;
+ let tenantId = user.loginTenantId;
+
+ console.log(user);
+ // WebSocket涓庢櫘閫氱殑璇锋眰鎵�鐢ㄥ崗璁湁鎵�涓嶅悓锛寃s绛夊悓浜巋ttp锛寃ss绛夊悓浜巋ttps
+ let url = glob.domainUrl?.replace('https://', 'wss://').replace('http://', 'ws://') + '/drySocket/' + tenantId;
+
+ connectWebSocket(url);
+ onWebSocket(onWebSocketMessage);
+ }
+
+ function onWebSocketMessage(data) {
+ console.log("drysocket:data::",data)
+ lightList.value.forEach(item => {
+ if(item.identifier == data.identifier) {
+ item.value = data.value
+ }
+ })
+ }
+
onMounted(() => {
showModal();
+ initWebSocket();
});
+
+queryDevice()
</script>
@@ -146,23 +346,101 @@
}
.com-box {
- display: flex;
- flex-wrap: wrap;
+ // margin-left: 200px;
+ display: flex;
+
+
.com-btn {
+ border-radius: 5px;
+ width: 100px;
margin: 10px;
+ height: 70px;
}
}
+.button-row {
+ display: flex; justify-content: space-between;
+}
+
.log-box {
- min-height: 200px;
- max-height: 300px;
- overflow-y: scroll;
+ min-height: 150px;
+ max-height: 150px;
+ overflow-y: auto;
}
.indented-text {
text-indent: 20px;
font-size: 16px;
}
+.light-box {
+ display: flex;
+ justify-items: center;
+justify-content: center;
+ flex-wrap: wrap;
+
+}
+.center {
+ display: flex;
+justify-items: center;
+justify-content: center;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.lightOn {
+ background-image: url(/src/assets/images/dry/control/light.png);
+ background-repeat: no-repeat;
+ background-size: 50px;
+ /* border-radius: 10px; */
+ background-position: 48px 0px;
+ }
+ .lightOff {
+ background-image: url(/src/assets/images/dry/control/light-close.png);
+ background-repeat: no-repeat;
+ background-size: 50px;
+ /* border-radius: 10px; */
+ background-position: 48px 0px;
+ }
+
+ .camOn {
+ background-image: url(/src/assets/images/dry/control/cam1.png);
+ background-repeat: no-repeat;
+ background-size: 50px;
+ /* border-radius: 10px; */
+ background-position: 48px 0px;
+ }
+ .camOff {
+ background-image: url(/src/assets/images/dry/control/cam0.png);
+ background-repeat: no-repeat;
+ background-size: 50px;
+ /* border-radius: 10px; */
+ background-position: 48px 0px;
+ }
+
+
+.device {
+ width: 150px; height: 60px;
+
+}
+
+.h100 {
+ height: 70px !important;
+}
+
+.w300 {
+ width: 100px !important;
+}
+
+.monitor-box {
+ display: flex;
+ justify-items: center;
+justify-content: center;
+flex-wrap: wrap;
+
+}
+
</style>
diff --git a/src/views/dry/DryOpcDeviceList.vue b/src/views/dry/DryOpcDeviceList.vue
new file mode 100644
index 0000000..f0b4892
--- /dev/null
+++ b/src/views/dry/DryOpcDeviceList.vue
@@ -0,0 +1,174 @@
+<template>
+ <div>
+ <!--寮曠敤琛ㄦ牸-->
+ <BasicTable @register="registerTable" :rowSelection="rowSelection">
+ <!--鎻掓Ы:table鏍囬-->
+ <template #tableTitle>
+ <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 鏂板</a-button>
+ <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 瀵煎嚭</a-button>
+ <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">瀵煎叆</j-upload-button>
+ <a-dropdown v-if="selectedRowKeys.length > 0">
+ <template #overlay>
+ <a-menu>
+ <a-menu-item key="1" @click="batchHandleDelete">
+ <Icon icon="ant-design:delete-outlined"></Icon>
+ 鍒犻櫎
+ </a-menu-item>
+ </a-menu>
+ </template>
+ <a-button>鎵归噺鎿嶄綔
+ <Icon icon="mdi:chevron-down"></Icon>
+ </a-button>
+ </a-dropdown>
+ </template>
+ <!--鎿嶄綔鏍�-->
+ <template #action="{ record }">
+ <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
+ </template>
+ <!--瀛楁鍥炴樉鎻掓Ы-->
+ <template #htmlSlot="{text}">
+ <div v-html="text"></div>
+ </template>
+ <!--鐪佸競鍖哄瓧娈靛洖鏄炬彃妲�-->
+ <template #pcaSlot="{text}">
+ {{ getAreaTextByCode(text) }}
+ </template>
+ <template #fileSlot="{text}">
+ <span v-if="!text" style="font-size: 12px;font-style: italic;">鏃犳枃浠�</span>
+ <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">涓嬭浇</a-button>
+ </template>
+ </BasicTable>
+ <!-- 琛ㄥ崟鍖哄煙 -->
+ <DryOpcDeviceModal @register="registerModal" @success="handleSuccess"></DryOpcDeviceModal>
+ </div>
+</template>
+
+<script lang="ts" name="dry-dryOpcDevice" setup>
+ import {ref, computed, unref} from 'vue';
+ import {BasicTable, useTable, TableAction} from '/@/components/Table';
+ import {useModal} from '/@/components/Modal';
+ import { useListPage } from '/@/hooks/system/useListPage'
+ import DryOpcDeviceModal from './components/DryOpcDeviceModal.vue'
+ import {columns, searchFormSchema} from './dataDefine/DryOpcDevice.data';
+ import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './api/DryOpcDevice.api';
+ import { downloadFile } from '/@/utils/common/renderUtils';
+ const checkedKeys = ref<Array<string | number>>([]);
+ //娉ㄥ唽model
+ const [registerModal, {openModal}] = useModal();
+ //娉ㄥ唽table鏁版嵁
+ const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
+ tableProps:{
+ title: 'dry_opc_device',
+ api: list,
+ columns,
+ canResize:false,
+ formConfig: {
+ //labelWidth: 120,
+ schemas: searchFormSchema,
+ autoSubmitOnEnter:true,
+ showAdvancedButton:true,
+ fieldMapToNumber: [
+ ],
+ fieldMapToTime: [
+ ],
+ },
+ actionColumn: {
+ width: 120,
+ fixed:'right'
+ },
+ },
+ exportConfig: {
+ name:"dry_opc_device",
+ url: getExportUrl,
+ },
+ importConfig: {
+ url: getImportUrl,
+ success: handleSuccess
+ },
+ })
+
+ const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
+
+ /**
+ * 鏂板浜嬩欢
+ */
+ function handleAdd() {
+ openModal(true, {
+ isUpdate: false,
+ showFooter: true,
+ });
+ }
+ /**
+ * 缂栬緫浜嬩欢
+ */
+ function handleEdit(record: Recordable) {
+ openModal(true, {
+ record,
+ isUpdate: true,
+ showFooter: true,
+ });
+ }
+ /**
+ * 璇︽儏
+ */
+ function handleDetail(record: Recordable) {
+ openModal(true, {
+ record,
+ isUpdate: true,
+ showFooter: false,
+ });
+ }
+ /**
+ * 鍒犻櫎浜嬩欢
+ */
+ async function handleDelete(record) {
+ console.log(record);
+ await deleteOne({id: record.id}, handleSuccess);
+ }
+ /**
+ * 鎵归噺鍒犻櫎浜嬩欢
+ */
+ async function batchHandleDelete() {
+ await batchDelete({ids: selectedRowKeys.value}, handleSuccess);
+ }
+ /**
+ * 鎴愬姛鍥炶皟
+ */
+ function handleSuccess() {
+ (selectedRowKeys.value = []) && reload();
+ }
+ /**
+ * 鎿嶄綔鏍�
+ */
+ function getTableAction(record){
+ return [
+ {
+ label: '缂栬緫',
+ onClick: handleEdit.bind(null, record),
+ }
+ ]
+ }
+ /**
+ * 涓嬫媺鎿嶄綔鏍�
+ */
+ function getDropDownAction(record){
+ return [
+ {
+ label: '璇︽儏',
+ onClick: handleDetail.bind(null, record),
+ }, {
+ label: '鍒犻櫎',
+ popConfirm: {
+ title: '鏄惁纭鍒犻櫎',
+ confirm: handleDelete.bind(null, record),
+ }
+ }
+ ]
+ }
+
+
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/src/views/dry/api/DryOpcDevice.api.ts b/src/views/dry/api/DryOpcDevice.api.ts
new file mode 100644
index 0000000..21ed673
--- /dev/null
+++ b/src/views/dry/api/DryOpcDevice.api.ts
@@ -0,0 +1,64 @@
+import {defHttp} from '/@/utils/http/axios';
+import { useMessage } from "/@/hooks/web/useMessage";
+
+const { createConfirm } = useMessage();
+
+enum Api {
+ list = '/dry/dryOpcDevice/list',
+ save='/dry/dryOpcDevice/add',
+ edit='/dry/dryOpcDevice/edit',
+ deleteOne = '/dry/dryOpcDevice/delete',
+ deleteBatch = '/dry/dryOpcDevice/deleteBatch',
+ importExcel = '/dry/dryOpcDevice/importExcel',
+ exportXls = '/dry/dryOpcDevice/exportXls',
+}
+/**
+ * 瀵煎嚭api
+ * @param params
+ */
+export const getExportUrl = Api.exportXls;
+/**
+ * 瀵煎叆api
+ */
+export const getImportUrl = Api.importExcel;
+/**
+ * 鍒楄〃鎺ュ彛
+ * @param params
+ */
+export const list = (params) =>
+ defHttp.get({url: Api.list, params});
+
+/**
+ * 鍒犻櫎鍗曚釜
+ */
+export const deleteOne = (params,handleSuccess) => {
+ return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
+ handleSuccess();
+ });
+}
+/**
+ * 鎵归噺鍒犻櫎
+ * @param params
+ */
+export const batchDelete = (params, handleSuccess) => {
+ createConfirm({
+ iconType: 'warning',
+ title: '纭鍒犻櫎',
+ content: '鏄惁鍒犻櫎閫変腑鏁版嵁',
+ okText: '纭',
+ cancelText: '鍙栨秷',
+ onOk: () => {
+ return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
+ handleSuccess();
+ });
+ }
+ });
+}
+/**
+ * 淇濆瓨鎴栬�呮洿鏂�
+ * @param params
+ */
+export const saveOrUpdate = (params, isUpdate) => {
+ let url = isUpdate ? Api.edit : Api.save;
+ return defHttp.post({url: url, params});
+}
diff --git a/src/views/dry/bigScreen/BigWorkShop.vue b/src/views/dry/bigScreen/BigWorkShop.vue
index 9c9db95..c5c59a1 100644
--- a/src/views/dry/bigScreen/BigWorkShop.vue
+++ b/src/views/dry/bigScreen/BigWorkShop.vue
@@ -19,12 +19,12 @@
<div style="display: flex; width: 120px">
<Icon style="color: #ba9853" icon="mdi:home-temperature-outline" :size="28" />
- <div style="font-size: 20px; line-height: 26px"> 26 鈩� </div>
+ <div style="font-size: 20px; line-height: 26px"> {{envTemp}} 鈩� </div>
</div>
<div style="display: flex">
<Icon style="color: #ba9853" icon="wi:humidity" :size="28" />
- <div style="font-size: 20px; line-height: 26px"> 53 %rh </div>
+ <div style="font-size: 20px; line-height: 26px"> {{envHum}} %rh </div>
</div>
</div>
<div class="feed">
@@ -58,7 +58,7 @@
鐢甸噺娑堣��
</div>
<div class="stat_value">
- 462
+ {{dianneng.toFixed(2)}}
<span class="font16">
Kwh
</span>
@@ -79,7 +79,7 @@
钂告苯娑堣��
</div>
<div class="stat_value">
- 683
+ {{zhengqi.toFixed(2)}}
<span class="font16">
m鲁
</span>
@@ -285,6 +285,7 @@
</div>
</div>
</div>
+
<div class="footer">
<div >{{ nowDate }}</div>
@@ -311,6 +312,13 @@
const eqps = ref([] as dryEquipment[])
const title = ref("鍏版郸鏅鸿兘骞茬嚗杞﹂棿")
const userStore = useUserStore()
+ const envHum = ref();
+ const envTemp = ref();
+ const zhengqi = ref();
+ const dianneng = ref()
+
+ const steam = ref();
+ const watt = ref()
console.log(userStore.dictItems.title)
userStore.dictItems.title?.forEach(element => {
if (element.value === "bigscreentitle") {
@@ -343,18 +351,34 @@
function updateRealTime() {
//console.log(`output->瀹氭椂鍒锋柊鏁版嵁`)
- eqps.value.forEach((item) => {
- queryRealTime(item)
+ zhengqi.value = 0;
+ dianneng.value = 0
+
+ new Promise(async function(resolve){
+
+ await eqps.value.forEach(async (item) => {
+ await queryRealTime(item)
+ })
+ resolve()
+
+ console.log("鎵ц瀹屾垚");
+ }).then(()=>{
+ console.log("then:::::" + dianneng.value,zhengqi.value );
+
+ steam.value = zhengqi.value
+ watt.value = dianneng.value
})
+
+
}
- function queryRealTime(eqp: dryEquipment) {
-
+ async function queryRealTime(eqp: dryEquipment) {
+ console.log("sdkfjlasjdflkajsldfjlsd")
let tenantId = userStore.getTenant
let eqpCode = eqp.code
let queryRealTimeUrl = '/dry/real/getRealTimeData'
- defHttp.get({ url: queryRealTimeUrl, params: { tenantid: tenantId, machineid: eqpCode } }).then((res) => {
- //console.log(`output->res`, res)
+ await defHttp.get({ url: queryRealTimeUrl, params: { tenantid: tenantId, machineid: eqpCode } }).then( async (res) => {
+ console.log(`output->res`, res)
if (res && res.trendVo) {
res.tempValue = [res.windTemp, 100]
res.totalRemain = res.remain
@@ -367,6 +391,11 @@
}
res.percent = ((res.dryTime / (res.dryTime + res.totalRemain)) * 100).toFixed(2)
+ envHum.value = res.envHum
+ envTemp.value = res.envTemp
+ zhengqi.value += res.steam
+ dianneng.value += res.watt
+ console.log("zhengqi:::" , res.steam);
} else {
res = {
tempValue: [0, 100],
@@ -627,7 +656,7 @@
}
.stat_value {
- font-size: 32px
+ font-size: 28px
}
.herb_weight {
diff --git a/src/views/dry/components/DryOpcDeviceForm.vue b/src/views/dry/components/DryOpcDeviceForm.vue
new file mode 100644
index 0000000..fbd7533
--- /dev/null
+++ b/src/views/dry/components/DryOpcDeviceForm.vue
@@ -0,0 +1,70 @@
+<template>
+ <div style="min-height: 400px">
+ <BasicForm @register="registerForm"></BasicForm>
+ <div style="width: 100%;text-align: center" v-if="!formDisabled">
+ <a-button @click="submitForm" pre-icon="ant-design:check" type="primary">鎻� 浜�</a-button>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+ import {BasicForm, useForm} from '/@/components/Form/index';
+ import {computed, defineComponent} from 'vue';
+ import {defHttp} from '/@/utils/http/axios';
+ import { propTypes } from '/@/utils/propTypes';
+ import {getBpmFormSchema} from '../dataDefine/DryOpcDevice.data';
+ import {saveOrUpdate} from '../api/DryOpcDevice.api';
+
+ export default defineComponent({
+ name: "DryOpcDeviceForm",
+ components:{
+ BasicForm
+ },
+ props:{
+ formData: propTypes.object.def({}),
+ formBpm: propTypes.bool.def(true),
+ },
+ setup(props){
+ const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
+ labelWidth: 150,
+ schemas: getBpmFormSchema(props.formData),
+ showActionButtonGroup: false,
+ baseColProps: {span: 24}
+ });
+
+ const formDisabled = computed(()=>{
+ if(props.formData.disabled === false){
+ return false;
+ }
+ return true;
+ });
+
+ let formData = {};
+ const queryByIdUrl = '/dry/dryOpcDevice/queryById';
+ async function initFormData(){
+ let params = {id: props.formData.dataId};
+ const data = await defHttp.get({url: queryByIdUrl, params});
+ formData = {...data}
+ //璁剧疆琛ㄥ崟鐨勫��
+ await setFieldsValue(formData);
+ //榛樿鏄鐢�
+ await setProps({disabled: formDisabled.value})
+ }
+
+ async function submitForm() {
+ let data = getFieldsValue();
+ let params = Object.assign({}, formData, data);
+ console.log('琛ㄥ崟鏁版嵁', params)
+ await saveOrUpdate(params, true)
+ }
+
+ initFormData();
+
+ return {
+ registerForm,
+ formDisabled,
+ submitForm,
+ }
+ }
+ });
+</script>
\ No newline at end of file
diff --git a/src/views/dry/components/DryOpcDeviceModal.vue b/src/views/dry/components/DryOpcDeviceModal.vue
new file mode 100644
index 0000000..96d8c7c
--- /dev/null
+++ b/src/views/dry/components/DryOpcDeviceModal.vue
@@ -0,0 +1,66 @@
+<template>
+ <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
+ <BasicForm @register="registerForm"/>
+ </BasicModal>
+</template>
+
+<script lang="ts" setup>
+ import {ref, computed, unref} from 'vue';
+ import {BasicModal, useModalInner} from '/@/components/Modal';
+ import {BasicForm, useForm} from '/@/components/Form/index';
+ import {formSchema} from '../dataDefine/DryOpcDevice.data';
+ import {saveOrUpdate} from '../api/DryOpcDevice.api';
+ // Emits澹版槑
+ const emit = defineEmits(['register','success']);
+ const isUpdate = ref(true);
+ //琛ㄥ崟閰嶇疆
+ const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
+ //labelWidth: 150,
+ schemas: formSchema,
+ showActionButtonGroup: false,
+ baseColProps: {span: 24}
+ });
+ //琛ㄥ崟璧嬪��
+ const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
+ //閲嶇疆琛ㄥ崟
+ await resetFields();
+ setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
+ isUpdate.value = !!data?.isUpdate;
+ if (unref(isUpdate)) {
+ //琛ㄥ崟璧嬪��
+ await setFieldsValue({
+ ...data.record,
+ });
+ }
+ // 闅愯棌搴曢儴鏃剁鐢ㄦ暣涓〃鍗�
+ setProps({ disabled: !data?.showFooter })
+ });
+ //璁剧疆鏍囬
+ const title = computed(() => (!unref(isUpdate) ? '鏂板' : '缂栬緫'));
+ //琛ㄥ崟鎻愪氦浜嬩欢
+ async function handleSubmit(v) {
+ try {
+ let values = await validate();
+ setModalProps({confirmLoading: true});
+ //鎻愪氦琛ㄥ崟
+ await saveOrUpdate(values, isUpdate.value);
+ //鍏抽棴寮圭獥
+ closeModal();
+ //鍒锋柊鍒楄〃
+ emit('success');
+ } finally {
+ setModalProps({confirmLoading: false});
+ }
+ }
+</script>
+
+<style lang="less" scoped>
+ /** 鏃堕棿鍜屾暟瀛楄緭鍏ユ鏍峰紡 */
+ :deep(.ant-input-number){
+ width: 100%
+ }
+
+ :deep(.ant-calendar-picker){
+ width: 100%
+ }
+</style>
\ No newline at end of file
diff --git a/src/views/dry/dataDefine/DryOpcDevice.data.ts b/src/views/dry/dataDefine/DryOpcDevice.data.ts
new file mode 100644
index 0000000..ccb1c0d
--- /dev/null
+++ b/src/views/dry/dataDefine/DryOpcDevice.data.ts
@@ -0,0 +1,109 @@
+import {BasicColumn} from '/@/components/Table';
+import {FormSchema} from '/@/components/Table';
+import { rules} from '/@/utils/helper/validator';
+import { render } from '/@/utils/common/renderUtils';
+//鍒楄〃鏁版嵁
+export const columns: BasicColumn[] = [
+ {
+ title: '鍚嶇О',
+ align:"center",
+ dataIndex: 'name'
+ },
+ {
+ title: '鐐逛綅鏍囪瘑',
+ align:"center",
+ dataIndex: 'identifier'
+ },
+ {
+ title: '鎺掑簭',
+ align:"center",
+ dataIndex: 'sortOrder'
+ },
+ {
+ title: '绫诲瀷',
+ align:"center",
+ dataIndex: 'type_dictText'
+ },
+];
+//鏌ヨ鏁版嵁
+export const searchFormSchema: FormSchema[] = [
+ {
+ label: "鍚嶇О",
+ field: 'name',
+ component: 'Input',
+ colProps: {span: 6},
+ },
+ {
+ label: "绫诲瀷",
+ field: 'type',
+ component: 'JDictSelectTag',
+ componentProps:{
+ dictCode:"device_type"
+ },
+ colProps: {span: 6},
+ },
+];
+//琛ㄥ崟鏁版嵁
+export const formSchema: FormSchema[] = [
+ {
+ label: '鍚嶇О',
+ field: 'name',
+ component: 'Input',
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '璇疯緭鍏ュ悕绉�!'},
+ ];
+ },
+ },
+ {
+ label: '鐐逛綅鏍囪瘑',
+ field: 'identifier',
+ component: 'Input',
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '璇疯緭鍏ョ偣浣嶆爣璇�!'},
+ ];
+ },
+ },
+ {
+ label: '鎺掑簭',
+ field: 'sortOrder',
+ component: 'InputNumber',
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '璇疯緭鍏ユ帓搴�!'},
+ ];
+ },
+ },
+ {
+ label: '绫诲瀷',
+ field: 'type',
+ component: 'JDictSelectTag',
+ componentProps:{
+ dictCode:"device_type"
+ },
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '璇疯緭鍏ョ被鍨�!'},
+ ];
+ },
+ },
+ // TODO 涓婚敭闅愯棌瀛楁锛岀洰鍓嶅啓姝讳负ID
+ {
+ label: '',
+ field: 'id',
+ component: 'Input',
+ show: false
+ },
+];
+
+
+
+/**
+* 娴佺▼琛ㄥ崟璋冪敤杩欎釜鏂规硶鑾峰彇formSchema
+* @param param
+*/
+export function getBpmFormSchema(_formData): FormSchema[]{
+ // 榛樿鍜屽師濮嬭〃鍗曚繚鎸佷竴鑷� 濡傛灉娴佺▼涓厤缃簡鏉冮檺鏁版嵁锛岃繖閲岄渶瑕佸崟鐙鐞唂ormSchema
+ return formSchema;
+}
\ No newline at end of file
diff --git a/src/views/dry/sql/DryOpcDevice_menu_insert.sql b/src/views/dry/sql/DryOpcDevice_menu_insert.sql
new file mode 100644
index 0000000..c30a1b8
--- /dev/null
+++ b/src/views/dry/sql/DryOpcDevice_menu_insert.sql
@@ -0,0 +1,26 @@
+-- 娉ㄦ剰锛氳椤甸潰瀵瑰簲鐨勫墠鍙扮洰褰曚负views/dry鏂囦欢澶逛笅
+-- 濡傛灉浣犳兂鏇存敼鍒板叾浠栫洰褰曪紝璇蜂慨鏀箂ql涓璫omponent瀛楁瀵瑰簲鐨勫��
+
+
+INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external)
+VALUES ('2023112802425240080', NULL, 'dry_opc_device', '/dry/dryOpcDeviceList', 'dry/DryOpcDeviceList', NULL, NULL, 0, NULL, '1', 0.00, 0, NULL, 1, 0, 0, 0, 0, NULL, '1', 0, 0, 'admin', '2023-11-28 14:42:08', NULL, NULL, 0);
+
+-- 鏉冮檺鎺у埗sql
+-- 鏂板
+INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
+VALUES ('2023112802425240081', '2023112802425240080', '娣诲姞dry_opc_device', NULL, NULL, 0, NULL, NULL, 2, 'dry:dry_opc_device:add', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2023-11-28 14:42:08', NULL, NULL, 0, 0, '1', 0);
+-- 缂栬緫
+INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
+VALUES ('2023112802425240082', '2023112802425240080', '缂栬緫dry_opc_device', NULL, NULL, 0, NULL, NULL, 2, 'dry:dry_opc_device:edit', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2023-11-28 14:42:08', NULL, NULL, 0, 0, '1', 0);
+-- 鍒犻櫎
+INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
+VALUES ('2023112802425240083', '2023112802425240080', '鍒犻櫎dry_opc_device', NULL, NULL, 0, NULL, NULL, 2, 'dry:dry_opc_device:delete', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2023-11-28 14:42:08', NULL, NULL, 0, 0, '1', 0);
+-- 鎵归噺鍒犻櫎
+INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
+VALUES ('2023112802425240084', '2023112802425240080', '鎵归噺鍒犻櫎dry_opc_device', NULL, NULL, 0, NULL, NULL, 2, 'dry:dry_opc_device:deleteBatch', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2023-11-28 14:42:08', NULL, NULL, 0, 0, '1', 0);
+-- 瀵煎嚭excel
+INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
+VALUES ('2023112802425240085', '2023112802425240080', '瀵煎嚭excel_dry_opc_device', NULL, NULL, 0, NULL, NULL, 2, 'dry:dry_opc_device:exportXls', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2023-11-28 14:42:08', NULL, NULL, 0, 0, '1', 0);
+-- 瀵煎叆excel
+INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external)
+VALUES ('2023112802425240086', '2023112802425240080', '瀵煎叆excel_dry_opc_device', NULL, NULL, 0, NULL, NULL, 2, 'dry:dry_opc_device:importExcel', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2023-11-28 14:42:08', NULL, NULL, 0, 0, '1', 0);
\ No newline at end of file
--
Gitblit v1.9.3