hwh
2024-08-28 bebfcf25bea32eb6d61e1da608adf72e15b3665f
Merge branch 'hwh'
5个文件已修改
3个文件已添加
226 ■■■■ 已修改文件
Admin.NET/WCS.Application/Hub/ITaskLogHub.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Hub/TaskLogHub.cs 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/PLCJob.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/PLCService.cs 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/PLCTaskAction.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsDevice/component/editDialog.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsTask/index.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsTask/signalR.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Hub/ITaskLogHub.cs
New file
@@ -0,0 +1,25 @@

namespace WCS.Application;
public interface ITaskLogHub
{
    /// <summary>
    /// 下发任务
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    Task PublicTask(WcsTaskOutput context);
    /// <summary>
    /// 下发任务明细
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    Task PublicTaskMonitor(WcsTaskMonitorOutput context);
    /// <summary>
    /// 接收消息
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    Task ReceiveMessage(object context);
}
Admin.NET/WCS.Application/Hub/TaskLogHub.cs
New file
@@ -0,0 +1,56 @@
using Furion.InstantMessaging;
using Microsoft.AspNetCore.SignalR;
namespace WCS.Application;
/// <summary>
/// 任务日志集线器
/// </summary>
[MapHub("/hubs/TaskLog")]
public class TaskLogHub : Hub<ITaskLogHub>
{
    private readonly IHubContext<TaskLogHub, ITaskLogHub> _taskLogHubContext;
    public TaskLogHub(IHubContext<TaskLogHub, ITaskLogHub> taskLogHubContext)
    {
        _taskLogHubContext = taskLogHubContext;
    }
    /// <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>
    /// <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);
    }
}
Admin.NET/WCS.Application/PLC/PLCJob.cs
@@ -1,4 +1,5 @@
using Furion.Schedule;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
namespace WCS.Application;
Admin.NET/WCS.Application/PLC/PLCService.cs
@@ -1,12 +1,19 @@

using Furion.Logging;
using IoTClient;
using Microsoft.AspNetCore.SignalR;
using System.Data;
namespace WCS.Application;
public static class PLCService
{
    private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);
    private static readonly IHubContext<TaskLogHub, ITaskLogHub> _taskLogHubContext;
    static PLCService()
    {
        _taskLogHubContext = App.GetService<IHubContext<TaskLogHub, ITaskLogHub>>();
    }
    public static void OnChangeEvent(object sender, EventArgs e)
    {
@@ -107,12 +114,8 @@
                                    modTaskMonitor.InteractiveMsg = "起始储位为空!";
                                    _db.Insertable(modTaskMonitor).ExecuteCommand();
                                    // 通知任务界面任务已存在更新 请更新界面
                                    //if (TaskAction.refresh)
                                    //{
                                    //    wSChat.AlarmInformation("1");
                                    //}
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                    break;
                                }
                                //给PLC写入任务数据
@@ -165,11 +168,8 @@
                                        EndLocat = outStationNum,
                                    };
                                    _db.Insertable(modInsertTaskMonitor).ExecuteCommand();
                                    // 通知任务界面任务已存在更新 请更新界面
                                    //if (TaskAction.refresh)
                                    //{
                                    //    wSChat.AlarmInformation("1");
                                    //}
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modInsertTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                    //修改led屏信息
                                    //LedDisplay(modDevice.LedIP, "工位:" + modTask.EndLocate, "出库中 " + $"储位地址:{modTask.StartLocate}", "托盘号:" + modTask.PalletNo);
                                }
@@ -236,11 +236,8 @@
                            Status = TaskStatusEnum.Complete
                        };
                        _db.Insertable(modTaskMonitor).ExecuteCommand();
                        //通知任务界面任务已存在更新 请更新界面
                        //if (TaskAction.refresh)
                        //{
                        //    wSChat.AlarmInformation("1");
                        //}
                        //下发任务日志
                        _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                    }
                    else if (modTask.TaskType.Value == TaskTypeEnum.Out)
@@ -277,11 +274,8 @@
                            Status = TaskStatusEnum.Complete
                        };
                        _db.Insertable(modTaskMonitor).ExecuteCommand();
                        //通知任务界面任务已存在更新 请更新界面
                        //if (TaskAction.refresh)
                        //{
                        //    wSChat.AlarmInformation("1");
                        //}
                        //下发任务日志
                        _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                    }
                }
                break;
@@ -344,11 +338,8 @@
                                        Status = TaskStatusEnum.Complete
                                    };
                                    _db.Insertable(modTaskMonitor).ExecuteCommand();
                                    // 通知任务界面任务已存在更新 请更新界面
                                    //if (TaskAction.refresh)
                                    //{
                                    //    wSChat.AlarmInformation("1");
                                    //}
                                    //下发任务日志
                                    _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                }
                                else
                                {
@@ -427,11 +418,8 @@
                                };
                                _db.Insertable(modTaskMonitor).ExecuteCommand();
                                // 通知任务界面任务已存在更新 请更新界面
                                //if (TaskAction.refresh)
                                //{
                                //    wSChat.AlarmInformation("1");
                                //}
                                //下发任务日志
                                _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>());
                                //todo:垛机出库不空跑
                            }
Admin.NET/WCS.Application/PLC/PLCTaskAction.cs
@@ -1,5 +1,5 @@
using Admin.NET.Core.Service;
using Furion.Logging;
using Furion.Logging;
using Microsoft.AspNetCore.SignalR;
namespace WCS.Application;
public static class PLCTaskAction
Web/src/views/wcs/wcsDevice/component/editDialog.vue
@@ -138,6 +138,10 @@
const ruleForm = ref<any>({});
//自行添加其他规则
const rules = ref<FormRules>({
    dbNumber: [{ required: true, message: '请输入DB区域!', trigger: 'blur', },],
    stationNum: [{ required: true, message: '请输入工位号!', trigger: 'blur', },],
    plcPos: [{ required: true, message: '请输入PLC偏移量!', trigger: 'blur', },],
    wcsPos: [{ required: true, message: '请输入WCS偏移量!', trigger: 'blur', },],
});
// 页面加载时
Web/src/views/wcs/wcsTask/index.vue
@@ -4,8 +4,9 @@
      <el-col :span="12" :xs="24" style="display: flex; height: 100%; flex: 1">
        <el-card class="full-table" shadow="hover" ::body-style="{ height: 'calc(100% - 51px)' }">
          <template #header>
                        <el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Collection /></el-icon>任务日志
                    </template>
            <el-icon size="16"
              style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Collection /></el-icon>任务日志
          </template>
          <el-form :model="queryParams" ref="queryForm" labelWidth="90">
            <el-row>
              <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10">
@@ -53,8 +54,8 @@
              </el-col>
            </el-row>
          </el-form>
          <el-table :data="tableData" style="width: 100%" v-loading="loading" tooltip-effect="light" row-key="id" @row-click="handleClick"
            @sort-change="sortChange" border="">
          <el-table :data="tableData" style="width: 100%" v-loading="loading" tooltip-effect="light" row-key="id"
            @row-click="handleClick" @sort-change="sortChange" border="">
            <el-table-column type="index" label="序号" width="55" align="center" />
            <el-table-column prop="taskNo" label="任务号" show-overflow-tooltip="" />
            <el-table-column prop="taskType" width="85" label="任务类型" show-overflow-tooltip="">
@@ -104,8 +105,9 @@
      <el-col :span="12" :xs="24" style="display: flex; height: 100%; flex: 1">
        <el-card class="full-table" shadow="hover" :body-style="{ height: 'calc(100% - 51px)' }">
          <template #header>
                        <el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Collection /></el-icon>任务详情
                    </template>
            <el-icon size="16"
              style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Collection /></el-icon>任务详情
          </template>
          <el-form :model="queryParams2" ref="queryForm2" labelWidth="90">
            <el-row>
              <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10">
@@ -122,7 +124,8 @@
              </el-col>
            </el-row>
          </el-form>
          <el-table :data="tableData2" style="width: 100%" v-loading="loading" tooltip-effect="light" row-key="id" border="">
          <el-table :data="tableData2" style="width: 100%" v-loading="loading" tooltip-effect="light" row-key="id"
            border="">
            <el-table-column type="index" label="序号" width="55" align="center" />
            <el-table-column prop="taskNo" label="任务号" show-overflow-tooltip="" />
            <el-table-column prop="plcId" label="交互工位号" show-overflow-tooltip="" />
@@ -146,22 +149,18 @@
<script lang="ts" setup="" name="wcsTask">
import ModifyRecord from '/@/components/table/modifyRecord.vue';
import { ref } from "vue";
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from "element-plus";
import { auth } from '/@/utils/authFunction';
import { getDictDataItem as di, getDictDataList as dl } from '/@/utils/dict-utils';
import { getDictLabelByVal as dv } from '/@/utils/dict-utils';
import { formatDate } from '/@/utils/formatTime';
import printDialog from '/@/views/system/print/component/hiprint/preview.vue'
import editDialog from '/@/views/wcs/wcsTask/component/editDialog.vue'
import { pageWcsTask, deleteWcsTask } from '/@/api/wcs/wcsTask';
import { pageWcsMonitorTask } from '/@/api/wcs/wcsTaskMonitor';
import { getAPI } from '/@/utils/axios-utils';
import { SysEnumApi } from '/@/api-services/api';
import commonFunction from '/@/utils/commonFunction';
import { signalR } from './signalR';
const showAdvanceQueryUI = ref(false);
const printDialogRef = ref();
@@ -183,7 +182,25 @@
});
const printWcsTaskTitle = ref("");
const editWcsTaskTitle = ref("");
//连接signalR 监听后台任务日志变更
onMounted(async () => {
  signalR.off('PublicTask');
  signalR.on('PublicTask', (data: any) => {
    console.log(data)
    if (tableData.value.filter(t => t.id == data.id).length == 0) {
      tableData.value.unshift(data)
    }
  });
  signalR.off('PublicTaskMonitor');
  signalR.on('PublicTaskMonitor', async (data: any) => {
    console.log(data);
    if (queryParams2.value.taskNo == undefined || queryParams2.value.taskNo == data.taskNo) {
      if (tableData2.value.filter(t => t.id == data.id).length == 0) {
        tableData2.value.unshift(data)
      }
    }
  });
});
// 改变高级查询的控件显示状态
const changeAdvanceQueryUI = () => {
  showAdvanceQueryUI.value = !showAdvanceQueryUI.value;
@@ -239,8 +256,8 @@
}
// 点击表格
const handleClick = (row: any, event: any, column: any) => {
    queryParams2.value.taskNo = row.taskNo;
    handleQuery2();
  queryParams2.value.taskNo = row.taskNo;
  handleQuery2();
};
// 删除
const delWcsTask = (row: any) => {
Web/src/views/wcs/wcsTask/signalR.ts
New file
@@ -0,0 +1,37 @@
import * as SignalR from '@microsoft/signalr';
import { getToken } from '/@/utils/axios-utils';
// 初始化SignalR对象
const connection = new SignalR.HubConnectionBuilder()
    .configureLogging(SignalR.LogLevel.Information)
    .withUrl(`${window.__env__.VITE_API_URL}/hubs/TaskLog?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('启动连接task');
});
// 断开连接
connection.onclose(async () => {
    console.log('断开连接task');
});
// 重连中
connection.onreconnecting(() => {
    console.log('服务器已断线task');
});
// 重连成功
connection.onreconnected(() => {
    console.log('重连成功task');
});
connection.on('PublicTask', () => {});
export { connection as signalR };