From 47ed1ba420ed01ea50e7f9a09247abd0deb531e1 Mon Sep 17 00:00:00 2001 From: hwh <332078369@qq.com> Date: 星期五, 30 八月 2024 16:55:16 +0800 Subject: [PATCH] Reapply "报警页面和首页设备实时通讯" --- Admin.NET/WCS.Application/Hub/IPlcHub.cs | 7 + Web/src/views/device/deviceInfo/index.vue | 52 ++++++++-- Web/src/views/device/alarmManage/index.vue | 53 +++++++++- Web/src/views/device/alarmManage/signalR.ts | 37 +++++++ Admin.NET/WCS.Application/Hub/TaskLogHub.cs | 66 ++++++------ Web/src/views/wcs/wcsTask/signalR.ts | 2 Admin.NET/WCS.Application/PLC/PLCTaskAction.cs | 2 Admin.NET/WCS.Application/Service/WcsAlarmInfo/WcsAlarmInfoService.cs | 14 ++ Web/src/views/device/deviceInfo/signalR.ts | 37 +++++++ Admin.NET/WCS.Application/Hub/PlcHub.cs | 20 +++- 10 files changed, 230 insertions(+), 60 deletions(-) diff --git a/Admin.NET/WCS.Application/Hub/IPlcHub.cs b/Admin.NET/WCS.Application/Hub/IPlcHub.cs index f55c14a..a026a67 100644 --- a/Admin.NET/WCS.Application/Hub/IPlcHub.cs +++ b/Admin.NET/WCS.Application/Hub/IPlcHub.cs @@ -21,5 +21,12 @@ /// <param name="context"></param> /// <returns></returns> //Task PublicStationStatus(List<WcsDevice> context); + + /// <summary> + /// 涓嬪彂鎶ヨ淇℃伅 + /// </summary> + /// <param name="context"></param> + /// <returns></returns> + Task PublicAlarm(WcsAlarmInfoOutput context); } } diff --git a/Admin.NET/WCS.Application/Hub/PlcHub.cs b/Admin.NET/WCS.Application/Hub/PlcHub.cs index b6dbb86..31d652c 100644 --- a/Admin.NET/WCS.Application/Hub/PlcHub.cs +++ b/Admin.NET/WCS.Application/Hub/PlcHub.cs @@ -4,7 +4,7 @@ namespace WCS.Application; /// <summary> -/// 浠诲姟鏃ュ織闆嗙嚎鍣� +/// PLC闆嗙嚎鍣� /// </summary> [MapHub("/hubs/Plc")] public class PlcHub : Hub<IPlcHub> @@ -20,10 +20,10 @@ /// </summary> /// <param name="context"></param> /// <returns></returns> - public async Task PublicPlcConn(WcsPlc context) - { - await _plcHubContext.Clients.All.PublicPlcConn(context); - } + //public async Task PublicPlcConn(WcsPlc context) + //{ + // await _plcHubContext.Clients.All.PublicPlcConn(context); + //} /// <summary> /// 涓嬪彂宸ヤ綅鐘舵�� @@ -34,4 +34,14 @@ //{ // await _plcHubContext.Clients.All.PublicStationStatus(context); //} + + /// <summary> + /// 涓嬪彂鎶ヨ淇℃伅 + /// </summary> + /// <param name="context"></param> + /// <returns></returns> + //public async Task PublicAlarm(WcsAlarmInfoOutput context) + //{ + // await _plcHubContext.Clients.All.PublicAlarm(context); + //} } diff --git a/Admin.NET/WCS.Application/Hub/TaskLogHub.cs b/Admin.NET/WCS.Application/Hub/TaskLogHub.cs index b4d018c..141e246 100644 --- a/Admin.NET/WCS.Application/Hub/TaskLogHub.cs +++ b/Admin.NET/WCS.Application/Hub/TaskLogHub.cs @@ -16,41 +16,41 @@ _taskLogHubContext = taskLogHubContext; } - /// <summary> - /// 杩炴帴 - /// </summary> - /// <returns></returns> - public override async Task OnConnectedAsync() - { - await base.OnConnectedAsync(); - } + ///// <summary> + ///// 杩炴帴 + ///// </summary> + ///// <returns></returns> + //public override async Task OnConnectedAsync() + //{ + // await base.OnConnectedAsync(); + //} - /// <summary> - /// 鏂紑 - /// </summary> - /// <param name="exception"></param> - /// <returns></returns> - public override async Task OnDisconnectedAsync(Exception exception) - { - await base.OnDisconnectedAsync(exception); - } + ///// <summary> + ///// 鏂紑 + ///// </summary> + ///// <param name="exception"></param> + ///// <returns></returns> + //public override async Task OnDisconnectedAsync(Exception exception) + //{ + // await base.OnDisconnectedAsync(exception); + //} - /// <summary> - /// 涓嬪彂浠诲姟 - /// </summary> - /// <returns></returns> - public async Task PublicTask(WcsTaskOutput context) - { - await _taskLogHubContext.Clients.All.PublicTask(context); - } + ///// <summary> + ///// 涓嬪彂浠诲姟 + ///// </summary> + ///// <returns></returns> + //public async Task PublicTask(WcsTaskOutput context) + //{ + // await _taskLogHubContext.Clients.All.PublicTask(context); + //} - /// <summary> - /// 涓嬪彂浠诲姟鏄庣粏 - /// </summary> - /// <returns></returns> - public async Task PublicTaskMonitor(WcsTaskMonitorOutput context) - { - await _taskLogHubContext.Clients.All.PublicTaskMonitor(context); - } + ///// <summary> + ///// 涓嬪彂浠诲姟鏄庣粏 + ///// </summary> + ///// <returns></returns> + //public async Task PublicTaskMonitor(WcsTaskMonitorOutput context) + //{ + // await _taskLogHubContext.Clients.All.PublicTaskMonitor(context); + //} } diff --git a/Admin.NET/WCS.Application/PLC/PLCTaskAction.cs b/Admin.NET/WCS.Application/PLC/PLCTaskAction.cs index 47c28e2..5907b0e 100644 --- a/Admin.NET/WCS.Application/PLC/PLCTaskAction.cs +++ b/Admin.NET/WCS.Application/PLC/PLCTaskAction.cs @@ -14,7 +14,7 @@ private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); private static readonly SysCacheService sysCacheService = App.GetRequiredService<SysCacheService>(); - private static readonly IHubContext<PlcHub, IPlcHub> _plcHubContext; + private static readonly IHubContext<PlcHub, IPlcHub> _plcHubContext = App.GetService<IHubContext<PlcHub, IPlcHub>>(); private static List<WcsPlc> listPlc; private static List<WcsDevice> listPlcDevice; diff --git a/Admin.NET/WCS.Application/Service/WcsAlarmInfo/WcsAlarmInfoService.cs b/Admin.NET/WCS.Application/Service/WcsAlarmInfo/WcsAlarmInfoService.cs index 09b5112..5860a85 100644 --- a/Admin.NET/WCS.Application/Service/WcsAlarmInfo/WcsAlarmInfoService.cs +++ b/Admin.NET/WCS.Application/Service/WcsAlarmInfo/WcsAlarmInfoService.cs @@ -1,4 +1,6 @@ -锘縩amespace WCS.Application; +锘縰sing Microsoft.AspNetCore.SignalR; + +namespace WCS.Application; /// <summary> /// 鎶ヨ淇℃伅琛ㄦ湇鍔� @@ -7,9 +9,12 @@ public class WcsAlarmInfoService : IDynamicApiController, ITransient { private readonly SqlSugarRepository<WcsAlarmInfo> _wcsAlarmInfoRep; - public WcsAlarmInfoService(SqlSugarRepository<WcsAlarmInfo> wcsAlarmInfoRep) + private readonly IHubContext<PlcHub, IPlcHub> _plcHubContext; + + public WcsAlarmInfoService(SqlSugarRepository<WcsAlarmInfo> wcsAlarmInfoRep, IHubContext<PlcHub, IPlcHub> plcHubContext) { _wcsAlarmInfoRep = wcsAlarmInfoRep; + _plcHubContext = plcHubContext; } /// <summary> @@ -118,7 +123,10 @@ [DisplayName("澶嶄綅鎶ヨ")] public async Task Reset() { - throw Oops.Bah("寮�鍙戜腑"); + //娴嬭瘯鎺ㄦ暟鎹敤鐨� + await _plcHubContext.Clients.All.PublicAlarm(new WcsAlarmInfoOutput() { Id = new Random().Next(), StationNum = "205", AlarmCode = "MB102", AlarmName = "鏈夌墿鍝侀伄鎸�", AlarmTime = DateTime.Now }); + //throw Oops.Bah("寮�鍙戜腑"); + } diff --git a/Web/src/views/device/alarmManage/index.vue b/Web/src/views/device/alarmManage/index.vue index af81810..a0b20b3 100644 --- a/Web/src/views/device/alarmManage/index.vue +++ b/Web/src/views/device/alarmManage/index.vue @@ -5,13 +5,16 @@ <el-row style="display: flex;text-align: center;justify-content: center;height: 40px;"> <el-button type="warning" style="width: 95%;height: 30px;" @click="reset">鎶ヨ澶嶄綅</el-button> </el-row> - <el-table :data="tableData" border style="width: 100%" v-loading="loading" + <el-table :data="paginatedData" border style="width: 100%" v-loading="loading" :default-sort="{ prop: 'date', order: 'descending' }"> <el-table-column prop="alarmCode" label="鍙橀噺" align="center"></el-table-column> <el-table-column prop="alarmName" label="鎻忚堪" align="center"></el-table-column> <el-table-column prop="stationNum" label="浣嶇疆" align="center"></el-table-column> <el-table-column prop="alarmTime" label="鏃堕棿" align="center"></el-table-column> </el-table> + <el-pagination v-model:currentPage="tableParams.page" v-model:page-size="tableParams.pageSize" + :total="tableParams.total" :page-sizes="[10, 20, 50, 100, 200, 500]" size="small" background="" + @size-change="handleSizeChange" @current-change="handleCurrentChange" layout="prev, pager, next" /> </el-col> <el-col :span="19"> <div class="card-page"> @@ -48,18 +51,23 @@ </template> <script lang="ts" setup> -import { ref, reactive } from 'vue'; -import { Splitpanes, Pane } from 'splitpanes'; +import { ref, reactive, onMounted, computed } from 'vue'; import 'splitpanes/dist/splitpanes.css'; -import { Vue2 } from 'vue-demi'; import { listWcsAlarmInfo, resetWcsAlarmInfo } from '/@/api/wcs/wcsAlarmInfo'; - +import { signalR } from './signalR'; +const tableParams = ref({ + page: 1, + pageSize: 10, + total: 0, +}); const loading = ref(false); const tableData = ref<any>([]); const handleQuery = async () => { loading.value = true; var res = await listWcsAlarmInfo({ status: 1 }); tableData.value = res.data.result; + tableParams.value.total = tableData.value.length; + console.log(tableParams.value.total); loading.value = false; }; handleQuery(); @@ -67,8 +75,41 @@ //澶嶄綅鎶ヨ const reset = async () => { await resetWcsAlarmInfo(); - await handleQuery(); } +//杩炴帴signalR 鐩戝惉鍙樻洿 +onMounted(async () => { + signalR.off('PublicAlarm'); + signalR.on('PublicAlarm', (data: any) => { + console.log(data) + var listAlarm = tableData.value.filter(t => t.id == data.id); + if (listAlarm.length == 0) { + tableData.value.unshift(data) + tableParams.value.total = tableData.value.length; + } + else { + //濡傛灉宸茬粡瀛樺湪灏辨洿鏂版暟鎹� + const index = tableData.value.findIndex(t => t.id == data.id); + tableData.value.splice(index, 1, data); + } + }); +}); + +// 鏀瑰彉椤甸潰瀹归噺 +const handleSizeChange = (val: number) => { + tableParams.value.pageSize = val; +}; + +// 鏀瑰彉椤电爜搴忓彿 +const handleCurrentChange = (val: number) => { + tableParams.value.page = val; +}; +//琛ㄦ牸鏄剧ず鏁版嵁 +const paginatedData = computed(() => { + const start = (tableParams.value.page - 1) * tableParams.value.pageSize + const end = start + tableParams.value.pageSize + return tableData.value.slice(start, end) +}) + //鍫嗗灈鏈烘暟鎹� const cellsDataLine = [ diff --git a/Web/src/views/device/alarmManage/signalR.ts b/Web/src/views/device/alarmManage/signalR.ts new file mode 100644 index 0000000..f734b9f --- /dev/null +++ b/Web/src/views/device/alarmManage/signalR.ts @@ -0,0 +1,37 @@ +import * as SignalR from '@microsoft/signalr'; +import { getToken } from '/@/utils/axios-utils'; + +// 鍒濆鍖朣ignalR瀵硅薄 +const connection = new SignalR.HubConnectionBuilder() + .configureLogging(SignalR.LogLevel.Information) + .withUrl(`${window.__env__.VITE_API_URL}/hubs/Plc?token=${getToken()}`, { transport: SignalR.HttpTransportType.WebSockets, skipNegotiation: true }) + .withAutomaticReconnect({ + nextRetryDelayInMilliseconds: () => { + return 5000; // 姣�5绉掗噸杩炰竴娆� + }, + }) + .build(); + +connection.keepAliveIntervalInMilliseconds = 15 * 1000; // 蹇冭烦妫�娴�15s +connection.serverTimeoutInMilliseconds = 30 * 60 * 1000; // 瓒呮椂鏃堕棿30m + +// 鍚姩杩炴帴 +connection.start().then(() => { + console.log('鍚姩杩炴帴plc'); +}); +// 鏂紑杩炴帴 +connection.onclose(async () => { + console.log('鏂紑杩炴帴plc'); +}); +// 閲嶈繛涓� +connection.onreconnecting(() => { + console.log('鏈嶅姟鍣ㄥ凡鏂嚎plc'); +}); +// 閲嶈繛鎴愬姛 +connection.onreconnected(() => { + console.log('閲嶈繛鎴愬姛plc'); +}); + +// connection.on('PublicAlarm', () => {}); + +export { connection as signalR }; diff --git a/Web/src/views/device/deviceInfo/index.vue b/Web/src/views/device/deviceInfo/index.vue index b4dd519..45aa157 100644 --- a/Web/src/views/device/deviceInfo/index.vue +++ b/Web/src/views/device/deviceInfo/index.vue @@ -18,14 +18,14 @@ <el-collapse-item title="鍫嗗灈鏈�" name="2"> <div style="overflow-x: auto;white-space: nowrap;"> <el-card v-for="(stacker, index) in stackers" :key="index" class="box-card" shadow="hover"> - <el-switch v-model="stacker.isConn" :inactive-text="`${stacker.text}`"></el-switch> + <el-switch disabled v-model="stacker.isConn" :inactive-text="`${stacker.text}`"></el-switch> </el-card> </div> </el-collapse-item> <el-collapse-item title="杈撻�佺嚎" name="3"> <el-card v-for="(conveyor, index) in conveyors" :key="index" class="box-card" shadow="hover"> - <el-switch v-model="conveyor.isConn" :inactive-text="`${conveyor.text}`"></el-switch> + <el-switch disabled v-model="conveyor.isConn" :inactive-text="`${conveyor.text}`"></el-switch> </el-card> </el-collapse-item> </el-collapse> @@ -65,9 +65,10 @@ </template> <script lang="ts" setup> -import { ref, reactive } from 'vue'; -import { Vue2 } from 'vue-demi'; +import { ref, reactive, onMounted } from 'vue'; import { listStatus } from '/@/api/wcs/wcsPlc'; +import { signalR } from './signalR'; + const state = ref<any>({}); const stackers = ref<any>({}); @@ -80,6 +81,28 @@ conveyors.value = res.data.result.listPlc.filter(s => s.type == 1 || s.type == 4); }; handleQuery(); + +//杩炴帴signalR 鐩戝惉鍙樻洿 +onMounted(async () => { + signalR.off('PublicPlcConn'); + signalR.on('PublicPlcConn', (data: any) => { + console.log(data) + if (data.type === 0) { + // 鏇挎崲 stackers 涓殑鐩稿簲椤� + const index = stackers.value.findIndex(item => item.id === data.id); + if (index !== -1) { + stackers.value[index] = data; + } + } else if (data.type === 1 || data.type === 4) { + // 鏇挎崲 conveyors 涓殑鐩稿簲椤� + const index = conveyors.value.findIndex(item => item.id === data.id); + if (index !== -1) { + conveyors.value[index] = data; + } + } + console.log(stackers.value[0].isConn) + }); +}); const activeName = ['1', '2', '3']; const value1 = ref(false); @@ -1949,12 +1972,16 @@ .grid-container-line { display: grid; - grid-template-columns: repeat(51, 1fr); /* 鑷�傚簲鍒楀 */ - grid-template-rows: 1fr; /* 鑷�傚簲琛岄珮 */ + grid-template-columns: repeat(51, 1fr); + /* 鑷�傚簲鍒楀 */ + grid-template-rows: 1fr; + /* 鑷�傚簲琛岄珮 */ gap: 0; margin-top: 25px; - width: 100%; /* 瀹藉害鑷�傚簲 */ - height: 1fr; /* 楂樺害鑷�傚簲 */ + width: 100%; + /* 瀹藉害鑷�傚簲 */ + height: 1fr; + /* 楂樺害鑷�傚簲 */ } .grid-item-line { @@ -2031,9 +2058,12 @@ background-color: #9c9c9c; border: 1px solid #797777; text-align: center; - line-height: 1.4vw; /* 琛岄珮 */ - width: 100%; /* 鑷�傚簲瀹藉害 */ - height: 100%; /* 鑷�傚簲楂樺害 */ + line-height: 1.4vw; + /* 琛岄珮 */ + width: 100%; + /* 鑷�傚簲瀹藉害 */ + height: 100%; + /* 鑷�傚簲楂樺害 */ color: #fff; font-size: 0.7vw; } diff --git a/Web/src/views/device/deviceInfo/signalR.ts b/Web/src/views/device/deviceInfo/signalR.ts new file mode 100644 index 0000000..6196950 --- /dev/null +++ b/Web/src/views/device/deviceInfo/signalR.ts @@ -0,0 +1,37 @@ +import * as SignalR from '@microsoft/signalr'; +import { getToken } from '/@/utils/axios-utils'; + +// 鍒濆鍖朣ignalR瀵硅薄 +const connection = new SignalR.HubConnectionBuilder() + .configureLogging(SignalR.LogLevel.Information) + .withUrl(`${window.__env__.VITE_API_URL}/hubs/Plc?token=${getToken()}`, { transport: SignalR.HttpTransportType.WebSockets, skipNegotiation: true }) + .withAutomaticReconnect({ + nextRetryDelayInMilliseconds: () => { + return 5000; // 姣�5绉掗噸杩炰竴娆� + }, + }) + .build(); + +connection.keepAliveIntervalInMilliseconds = 15 * 1000; // 蹇冭烦妫�娴�15s +connection.serverTimeoutInMilliseconds = 30 * 60 * 1000; // 瓒呮椂鏃堕棿30m + +// 鍚姩杩炴帴 +connection.start().then(() => { + console.log('鍚姩杩炴帴plc'); +}); +// 鏂紑杩炴帴 +connection.onclose(async () => { + console.log('鏂紑杩炴帴plc'); +}); +// 閲嶈繛涓� +connection.onreconnecting(() => { + console.log('鏈嶅姟鍣ㄥ凡鏂嚎plc'); +}); +// 閲嶈繛鎴愬姛 +connection.onreconnected(() => { + console.log('閲嶈繛鎴愬姛plc'); +}); + +// connection.on('PublicPlcConn', () => {}); + +export { connection as signalR }; diff --git a/Web/src/views/wcs/wcsTask/signalR.ts b/Web/src/views/wcs/wcsTask/signalR.ts index 42c93f8..6e9eed8 100644 --- a/Web/src/views/wcs/wcsTask/signalR.ts +++ b/Web/src/views/wcs/wcsTask/signalR.ts @@ -32,6 +32,6 @@ console.log('閲嶈繛鎴愬姛task'); }); -connection.on('PublicTask', () => {}); +// connection.on('PublicTask', () => {}); export { connection as signalR }; -- Gitblit v1.8.0