bklLiudl
2024-09-11 5999e9c77ee30a7090ed7f6cdd07d82fe9a4015b
Merge branch 'master' into liudl
10个文件已修改
11个文件已添加
1705 ■■■■■ 已修改文件
Admin.NET/WCS.Application/Entity/WcsMateialPzInfo.cs 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Hub/IPlcDeviceHub.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Hub/PlcDeviceHub.cs 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsCheckTask/WcsCheckTaskService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceInput.cs 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceOutput.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceTaskOrderDto.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsDevice/WcsDeviceService.cs 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsMateialPzInfo/Dto/WcsMateialPzInfoDto.cs 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsMateialPzInfo/Dto/WcsMateialPzInfoInput.cs 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsMateialPzInfo/Dto/WcsMateialPzInfoOutput.cs 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsMateialPzInfo/WcsMateialPzInfoService.cs 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/api/wcs/wcsDevice.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/api/wcs/wcsMateialPzInfo.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/device/deviceMonitor/component/setting.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/device/deviceMonitor/index.vue 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/device/deviceMonitor/signalR.ts 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/device/sortPallet/index.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/device/wcsOderTask/component/editDialog.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsMateialPzInfo/component/editDialog.vue 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsMateialPzInfo/index.vue 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Entity/WcsMateialPzInfo.cs
New file
@@ -0,0 +1,83 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core;
namespace WCS.Application.Entity;
/// <summary>
/// 物料品种信息维护表
/// </summary>
[SugarTable("WCSMateialPZInfo","物料品种信息维护表")]
[Tenant("1300000000001")]
public class WcsMateialPzInfo  : EntityBaseData
{
    /// <summary>
    /// 物料编码
    /// </summary>
    [SugarColumn(ColumnName = "SkuNo", ColumnDescription = "物料编码", Length = 20)]
    public string? SkuNo { get; set; }
    /// <summary>
    /// 物料名称
    /// </summary>
    [SugarColumn(ColumnName = "SkuName", ColumnDescription = "物料名称", Length = 20)]
    public string? SkuName { get; set; }
    /// <summary>
    /// 长
    /// </summary>
    [SugarColumn(ColumnName = "Length", ColumnDescription = "长", Length = 20)]
    public string? Length { get; set; }
    /// <summary>
    /// 宽
    /// </summary>
    [SugarColumn(ColumnName = "Width", ColumnDescription = "宽", Length = 20)]
    public string? Width { get; set; }
    /// <summary>
    /// 高
    /// </summary>
    [SugarColumn(ColumnName = "Height", ColumnDescription = "高", Length = 20)]
    public string? Height { get; set; }
    /// <summary>
    /// 品种号
    /// </summary>
    [SugarColumn(ColumnName = "PZNo", ColumnDescription = "品种号", Length = 10)]
    public string? PZNo { get; set; }
    /// <summary>
    /// 备用字段1
    /// </summary>
    [SugarColumn(ColumnName = "UDF1", ColumnDescription = "备用字段1", Length = 20)]
    public string? UDF1 { get; set; }
    /// <summary>
    /// 备用字段2
    /// </summary>
    [SugarColumn(ColumnName = "UDF2", ColumnDescription = "备用字段2", Length = 20)]
    public string? UDF2 { get; set; }
    /// <summary>
    /// 备用字段3
    /// </summary>
    [SugarColumn(ColumnName = "UDF3", ColumnDescription = "备用字段3", Length = 20)]
    public string? UDF3 { get; set; }
    /// <summary>
    /// 备用字段4
    /// </summary>
    [SugarColumn(ColumnName = "UDF4", ColumnDescription = "备用字段4", Length = 20)]
    public string? UDF4 { get; set; }
    /// <summary>
    /// 备用字段5
    /// </summary>
    [SugarColumn(ColumnName = "UDF5", ColumnDescription = "备用字段5", Length = 20)]
    public string? UDF5 { get; set; }
}
Admin.NET/WCS.Application/Hub/IPlcDeviceHub.cs
New file
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WCS.Application;
public interface IPlcDeviceHub
{
    /// <summary>
    /// 下发设备信息
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    Task PublicPlcDevice(WcsDeviceOutput context);
}
Admin.NET/WCS.Application/Hub/PlcDeviceHub.cs
New file
@@ -0,0 +1,206 @@
using Admin.NET.Core.Service;
using DocumentFormat.OpenXml.Office2010.ExcelAc;
using Furion.InstantMessaging;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WCS.Application;
/// <summary>
/// 任务日志集线器
/// </summary>
[MapHub("/hubs/PlcDevice")]
public class PlcDeviceHub : Hub<IPlcDeviceHub>
{
    private static readonly IHubContext<PlcDeviceHub, IPlcDeviceHub> _plcDeviceHubContext = App.GetService<IHubContext<PlcDeviceHub, IPlcDeviceHub>>();
    private static readonly SysCacheService _sysCacheService = App.GetRequiredService<SysCacheService>();
    private static bool boRunningState = false;
    private static CancellationTokenSource cts;//取消线程标识
    private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);
    public PlcDeviceHub()
    {
    }
    /// <summary>
    /// 连接
    /// </summary>
    /// <returns></returns>
    public override async Task OnConnectedAsync()
    {
        var httpContext = Context.GetHttpContext();
        var userId = (httpContext.User.FindFirst(ClaimConst.UserId)?.Value).ToLong();
        _sysCacheService.Set("PlcDeviceHub:" + Context.ConnectionId, userId);
        if (!boRunningState)
        {
            //开启读取服务线程
            boRunningState = true;
            cts = new CancellationTokenSource();//取消线程标识
            StartRead();
        }
        await base.OnConnectedAsync();
    }
    /// <summary>
    /// 断开
    /// </summary>
    /// <param name="exception"></param>
    /// <returns></returns>
    public override async Task OnDisconnectedAsync(Exception exception)
    {
        _sysCacheService.Remove("PlcDeviceHub:" + Context.ConnectionId);
        //如果没有连接了 就关闭线程不读了
        if (_sysCacheService.GetKeysByPrefixKey("PlcDeviceHub").Count == 0)
        {
            cts.Cancel();
            boRunningState = false;
        }
        await base.OnDisconnectedAsync(exception);
    }
    /// <summary>
    /// 开启读取plc线程
    /// </summary>
    public static void StartRead()
    {
        Task.Run(() =>
        {
            // 用于保存每个设备的初始状态
            var initialStates = new Dictionary<long, WcsDeviceOutput>();
            var listPlc = _db.Queryable<WcsPlc>().Where(s => s.Type == PLCTypeEnum.StackingMachine || s.Type == PLCTypeEnum.ConveyorLine).ToList();
            var listPlcId = listPlc.Select(s => s.Id).ToList();
            var listPlcDevice = _db.Queryable<WcsDevice>().Where(s => s.DeviceType == DeviceTypeEnum.Business && listPlcId.Contains(s.PlcId)).Select<WcsDeviceOutput>().ToList();
            var listPlcDeviceId = listPlcDevice.Select(s => s.Id).ToList();
            var listPlcStation = _db.Queryable<WcsPosition>().Where(s => listPlcDeviceId.Contains(s.DeviceId)).ToList();
            while (true)
            {
                try
                {
                    //获取跺机的状态
                    foreach (var modDevice in listPlcDevice)
                    {
                        //取消线程
                        if (cts.Token.IsCancellationRequested)
                        {
                            throw new OperationCanceledException();
                        }
                        var modPlc = listPlc.Where(s => s.Id == modDevice.PlcId).FirstOrDefault();
                        modDevice.Type = modPlc.Type;
                        //读取plc的值
                        var modConn = PLCTaskAction.listPlcConn.FirstOrDefault(s => s != null && s.PlcId == modDevice.PlcId);
                        if (modConn == null)
                        {
                            modDevice.Status = false;
                            continue;
                        }
                        else
                        {
                            modDevice.Status = modConn.Connected;
                        }
                        if (modConn.Connected)
                        {
                            var listPosition = listPlcStation.Where(s => s.DeviceId == modDevice.Id).ToList();
                            (var result, var plc) = modConn.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos);
                            modDevice.Plc = Convert.ToString(plc);
                            (result, var wcs) = modConn.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos);
                            modDevice.Wcs = Convert.ToString(wcs);
                            //任务号
                            var modPositionTask = listPosition.FirstOrDefault(s => s.Text == "任务号");
                            (result, var taskNo) = modConn.GetPlcDBValue(modPositionTask.PosType, modDevice.DbNumber, modPositionTask.PlcPos, modPositionTask.StringLength);
                            modDevice.TaskNo = Convert.ToString(taskNo);
                            //任务类型
                            var modPositionTaskType = listPosition.FirstOrDefault(s => s.Text == "任务类型");
                            (result, var taskType) = modConn.GetPlcDBValue(modPositionTaskType.PosType, modDevice.DbNumber, modPositionTaskType.PlcPos);
                            modDevice.TaskType = (TaskTypeEnum)Convert.ToInt32(taskType);
                            //起始工位
                            var modPositionStartLocatNo = listPosition.FirstOrDefault(s => s.Text == "起始工位");
                            (result, var startLocatNo) = modConn.GetPlcDBValue(modPositionStartLocatNo.PosType, modDevice.DbNumber, modPositionStartLocatNo.PlcPos);
                            modDevice.StartLocatNo = Convert.ToString(startLocatNo);
                            //目的工位
                            var modPositionEndLocatNo = listPosition.FirstOrDefault(s => s.Text == "目的工位");
                            (result, var endLocatNo) = modConn.GetPlcDBValue(modPositionEndLocatNo.PosType, modDevice.DbNumber, modPositionEndLocatNo.PlcPos);
                            modDevice.EndLocatNo = Convert.ToString(endLocatNo);
                            //托盘码
                            var modPositionPalletNo = listPosition.FirstOrDefault(s => s.Text == "托盘码");
                            (result, var palletNo) = modConn.GetPlcDBValue(modPositionPalletNo.PosType, modDevice.DbNumber, modPositionPalletNo.PlcPos, modPositionPalletNo.StringLength);
                            modDevice.PalletNo = Convert.ToString(palletNo);
                            if (modPlc.Type == PLCTypeEnum.ConveyorLine)
                            {
                                //放货排
                                var modPositionReleaseRow = listPosition.FirstOrDefault(s => s.Text == "放货排");
                                (result, var releaseRow) = modConn.GetPlcDBValue(modPositionReleaseRow.PosType, modDevice.DbNumber, modPositionReleaseRow.PlcPos);
                                modDevice.ReleaseRow = Convert.ToInt32(releaseRow);
                                //放货列
                                var modPositionReleaseCol = listPosition.FirstOrDefault(s => s.Text == "放货列");
                                (result, var releaseCol) = modConn.GetPlcDBValue(modPositionReleaseCol.PosType, modDevice.DbNumber, modPositionReleaseCol.PlcPos);
                                modDevice.ReleaseCol = Convert.ToInt32(releaseCol);
                                //放货层
                                var modPositionReleaseStorey = listPosition.FirstOrDefault(s => s.Text == "放货层");
                                (result, var releaseStorey) = modConn.GetPlcDBValue(modPositionReleaseStorey.PosType, modDevice.DbNumber, modPositionReleaseStorey.PlcPos);
                                modDevice.ReleaseStorey = Convert.ToInt32(releaseStorey);
                                //取货排
                                var modPositionPickRow = listPosition.FirstOrDefault(s => s.Text == "取货排");
                                (result, var pickRow) = modConn.GetPlcDBValue(modPositionPickRow.PosType, modDevice.DbNumber, modPositionPickRow.PlcPos);
                                modDevice.PickRow = Convert.ToInt32(pickRow);
                                //取货列
                                var modPositionPickCol = listPosition.FirstOrDefault(s => s.Text == "取货列");
                                (result, var pickCol) = modConn.GetPlcDBValue(modPositionPickCol.PosType, modDevice.DbNumber, modPositionPickCol.PlcPos);
                                modDevice.PickCol = Convert.ToInt32(pickCol);
                                //取货层
                                var modPositionPickStorey = listPosition.FirstOrDefault(s => s.Text == "取货层");
                                (result, var pickStorey) = modConn.GetPlcDBValue(modPositionPickStorey.PosType, modDevice.DbNumber, modPositionPickStorey.PlcPos);
                                modDevice.PickStorey = Convert.ToInt32(pickStorey);
                            }
                        }
                        //else
                        //{
                        //    //测试
                        //    modDevice.TaskNo = "TK00001";
                        //    modDevice.TaskType = TaskTypeEnum.In;
                        //    modDevice.Wcs = new Random().Next(1000).ToString();
                        //    modDevice.Plc = new Random().Next(1000).ToString();
                        //    modDevice.Status = true;
                        //}
                        // 比较之前的状态
                        if (initialStates.TryGetValue(modDevice.Id, out var initialState))
                        {
                            if (modDevice.Status != initialState.Status ||
                                modDevice.Plc != initialState.Plc ||
                                modDevice.Wcs != initialState.Wcs ||
                                modDevice.TaskNo != initialState.TaskNo ||
                                modDevice.TaskType != initialState.TaskType ||
                                modDevice.StartLocatNo != initialState.StartLocatNo ||
                                modDevice.EndLocatNo != initialState.EndLocatNo ||
                                modDevice.PalletNo != initialState.PalletNo ||
                                (modPlc.Type == PLCTypeEnum.ConveyorLine &&
                                    (modDevice.ReleaseRow != initialState.ReleaseRow ||
                                     modDevice.ReleaseCol != initialState.ReleaseCol ||
                                     modDevice.ReleaseStorey != initialState.ReleaseStorey ||
                                     modDevice.PickRow != initialState.PickRow ||
                                     modDevice.PickCol != initialState.PickCol ||
                                     modDevice.PickStorey != initialState.PickStorey)))
                            {
                                // 通知用户变更
                                _plcDeviceHubContext.Clients.All.PublicPlcDevice(modDevice);
                            }
                        }
                        initialStates[modDevice.Id] = modDevice.Adapt<WcsDeviceOutput>();
                    }
                    Thread.Sleep(2000);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception)
                {
                }
            }
        }, cts.Token);
    }
}
Admin.NET/WCS.Application/Service/WcsCheckTask/WcsCheckTaskService.cs
@@ -20,11 +20,14 @@
    private readonly SqlSugarRepository<WcsCheckTask> _wcsCheckTaskRep;
    private readonly SqlSugarRepository<WcsDevice> _wcsDeviceRep;
    private readonly SqlSugarRepository<WcsOderTask> _wcsOderTaskRep;
    public WcsCheckTaskService(SqlSugarRepository<WcsCheckTask> wcsCheckTaskRep, SqlSugarRepository<WcsDevice> wcsDeviceRep, SqlSugarRepository<WcsOderTask> wcsOderTaskRep)
    private readonly SqlSugarRepository<WcsMateialPzInfo> _wcsMateialPzInfoRep;
    public WcsCheckTaskService(SqlSugarRepository<WcsCheckTask> wcsCheckTaskRep, SqlSugarRepository<WcsDevice> wcsDeviceRep, SqlSugarRepository<WcsOderTask> wcsOderTaskRep, SqlSugarRepository<WcsMateialPzInfo> wcsMateialPzInfoRep)
    {
        _wcsCheckTaskRep = wcsCheckTaskRep;
        _wcsDeviceRep = wcsDeviceRep;
        _wcsOderTaskRep = wcsOderTaskRep;
        _wcsMateialPzInfoRep = wcsMateialPzInfoRep;
    }
    /// <summary>
@@ -167,6 +170,12 @@
        {
            throw Oops.Oh("任务状态异常");
        }
        //物料品种信息
        var skuInfo = await _wcsMateialPzInfoRep.Context.Queryable<WcsMateialPzInfo>().Where(w => w.SkuNo == taskInfo.SkuNo).FirstAsync();
        if (skuInfo == null)
        {
            throw Oops.Oh("物料品种信息不存在");
        }
        //分拣任务信息
        var checkTaskInfo = await _wcsCheckTaskRep.Context.Queryable<WcsCheckTask>().Where(w => w.Port == deviceInfo.StationNum).FirstAsync();
        if (checkTaskInfo == null)
@@ -184,6 +193,7 @@
        checkTaskInfo.BoxType = taskInfo.BoxType;
        checkTaskInfo.Qty = taskInfo.Qty;
        checkTaskInfo.Status = "1";//已绑定
        checkTaskInfo.PZNo = skuInfo.PZNo;
        //更新分拣任务
        await _wcsCheckTaskRep.AsUpdateable(checkTaskInfo).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceInput.cs
@@ -232,4 +232,65 @@
    /// </summary>
    [Required(ErrorMessage = "起始点位不能为空")]
    public int Pos { get; set; }
}
/// <summary>
/// 写入参数
/// </summary>
public class WriteWcsDeviceInput : WcsDeviceBaseInput
{
    /// <summary>
    /// 主键Id
    /// </summary>
    [Required(ErrorMessage = "主键Id不能为空")]
    public long Id { get; set; }
    /// <summary>
    /// 任务号
    /// </summary>
    public string TaskNo { get; set; }
    /// <summary>
    /// 任务类型
    /// </summary>
    public TaskTypeEnum? TaskType { get; set; }
    /// <summary>
    /// 起始工位
    /// </summary>
    public string StartLocatNo { get; set; }
    /// <summary>
    /// 结束工位
    /// </summary>
    public string EndLocatNo { get; set; }
    /// <summary>
    /// 托盘码
    /// </summary>
    public string PalletNo { get; set; }
    public string Plc { get; set; }
    public string Wcs { get; set; }
    /// <summary>
    /// 连接状态
    /// </summary>
    public bool Status { get; set; } = false;
    /// <summary>
    /// 放货排
    /// </summary>
    public int ReleaseRow { get; set; }
    /// <summary>
    /// 放货列
    /// </summary>
    public int ReleaseCol { get; set; }
    /// <summary>
    /// 放货层
    /// </summary>
    public int ReleaseStorey { get; set; }
    /// <summary>
    /// 取货排
    /// </summary>
    public int PickRow { get; set; }
    /// <summary>
    /// 取货列
    /// </summary>
    public int PickCol { get; set; }
    /// <summary>
    /// 取货层
    /// </summary>
    public int PickStorey { get; set; }
}
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceOutput.cs
@@ -142,8 +142,30 @@
    /// 连接状态
    /// </summary>
    public bool Status { get; set; } = false;
    /// <summary>
    /// 放货排
    /// </summary>
    public int ReleaseRow { get; set; }
    /// <summary>
    /// 放货列
    /// </summary>
    public int ReleaseCol { get; set; }
    /// <summary>
    /// 放货层
    /// </summary>
    public int ReleaseStorey { get; set; }
    /// <summary>
    /// 取货排
    /// </summary>
    public int PickRow { get; set; }
    /// <summary>
    /// 取货列
    /// </summary>
    public int PickCol { get; set; }
    /// <summary>
    /// 取货层
    /// </summary>
    public int PickStorey { get; set; }
}
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceTaskOrderDto.cs
@@ -18,4 +18,6 @@
    /// 总箱数/计划箱数/预估箱数
    /// </summary>
    public int? Qty { get; set; }
    public string? LineNO { get; set; }
    public string? PZNo { get; set; }
}
Admin.NET/WCS.Application/Service/WcsDevice/WcsDeviceService.cs
@@ -251,6 +251,34 @@
                        var modPositionPalletNo = listPosition.FirstOrDefault(s => s.Text == "托盘码");
                        (result, var palletNo) = modConn.GetPlcDBValue(modPositionPalletNo.PosType, modDevice.DbNumber, modPositionPalletNo.PlcPos, modPositionPalletNo.StringLength);
                        modDevice.PalletNo = Convert.ToString(palletNo);
                        if (cachePlc.Type == PLCTypeEnum.ConveyorLine)
                        {
                            //放货排
                            var modPositionReleaseRow = listPosition.FirstOrDefault(s => s.Text == "放货排");
                            (result, var releaseRow) = modConn.GetPlcDBValue(modPositionReleaseRow.PosType, modDevice.DbNumber, modPositionReleaseRow.PlcPos);
                            modDevice.ReleaseRow = Convert.ToInt32(releaseRow);
                            //放货列
                            var modPositionReleaseCol = listPosition.FirstOrDefault(s => s.Text == "放货列");
                            (result, var releaseCol) = modConn.GetPlcDBValue(modPositionReleaseCol.PosType, modDevice.DbNumber, modPositionReleaseCol.PlcPos);
                            modDevice.ReleaseCol = Convert.ToInt32(releaseCol);
                            //放货层
                            var modPositionReleaseStorey = listPosition.FirstOrDefault(s => s.Text == "放货层");
                            (result, var releaseStorey) = modConn.GetPlcDBValue(modPositionReleaseStorey.PosType, modDevice.DbNumber, modPositionReleaseStorey.PlcPos);
                            modDevice.ReleaseStorey = Convert.ToInt32(releaseStorey);
                            //取货排
                            var modPositionPickRow = listPosition.FirstOrDefault(s => s.Text == "取货排");
                            (result, var pickRow) = modConn.GetPlcDBValue(modPositionPickRow.PosType, modDevice.DbNumber, modPositionPickRow.PlcPos);
                            modDevice.PickRow = Convert.ToInt32(pickRow);
                            //取货列
                            var modPositionPickCol = listPosition.FirstOrDefault(s => s.Text == "取货列");
                            (result, var pickCol) = modConn.GetPlcDBValue(modPositionPickCol.PosType, modDevice.DbNumber, modPositionPickCol.PlcPos);
                            modDevice.PickCol = Convert.ToInt32(pickCol);
                            //取货层
                            var modPositionPickStorey = listPosition.FirstOrDefault(s => s.Text == "取货层");
                            (result, var pickStorey) = modConn.GetPlcDBValue(modPositionPickStorey.PosType, modDevice.DbNumber, modPositionPickStorey.PlcPos);
                            modDevice.PickStorey = Convert.ToInt32(pickStorey);
                        }
                    }
                    catch (Exception)
                    {
@@ -274,6 +302,69 @@
        }
        return list;
    }
    [HttpPost]
    [ApiDescriptionSettings(Name = "WriteValue")]
    [DisplayName("写入值")]
    public async Task WriteValue(WriteWcsDeviceInput modDevice)
    {
        var modPlc = await _wcsDeviceRep.Context.Queryable<WcsPlc>().FirstAsync(s => s.Id == modDevice.PlcId);
        if (modPlc == null)
            throw Oops.Bah("找不到PLC信息");
        PLCUtil modUtil = new PLCUtil(modPlc);
        var listPosition = await _wcsDeviceRep.Context.Queryable<WcsPosition>().Where(s => s.DeviceId == modDevice.Id).ToListAsync();
        //(var result, var plc) = modConn.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos);
        //modDevice.Plc = Convert.ToString(plc);
        //任务号
        var modPositionTask = listPosition.FirstOrDefault(s => s.Text == "任务号");
        if (modPositionTask != null)
            modUtil.SetPlcDBValue(modPositionTask.PosType, modPositionTask.PlcPos, modDevice.TaskNo);
        //任务类型
        var modPositionTaskType = listPosition.FirstOrDefault(s => s.Text == "任务类型");
        if (modPositionTaskType != null)
            modUtil.SetPlcDBValue(modPositionTaskType.PosType, modPositionTaskType.PlcPos, modDevice.TaskType.ToString());
        //起始工位
        var modPositionStartLocatNo = listPosition.FirstOrDefault(s => s.Text == "起始工位");
        if (modPositionStartLocatNo != null)
            modUtil.SetPlcDBValue(modPositionStartLocatNo.PosType, modPositionStartLocatNo.PlcPos, modDevice.StartLocatNo.ToString());
        //目的工位
        var modPositionEndLocatNo = listPosition.FirstOrDefault(s => s.Text == "目的工位");
        if (modPositionEndLocatNo != null)
            modUtil.SetPlcDBValue(modPositionEndLocatNo.PosType, modPositionEndLocatNo.PlcPos, modDevice.EndLocatNo.ToString());
        //托盘码
        var modPositionPalletNo = listPosition.FirstOrDefault(s => s.Text == "托盘码");
        if (modPositionPalletNo != null)
            modUtil.SetPlcDBValue(modPositionPalletNo.PosType, modPositionPalletNo.PlcPos, modDevice.PalletNo.ToString());
        if (modPlc.Type == PLCTypeEnum.ConveyorLine)
        {
            //放货排
            var modPositionReleaseRow = listPosition.FirstOrDefault(s => s.Text == "放货排");
            if (modPositionReleaseRow != null)
                modUtil.SetPlcDBValue(modPositionReleaseRow.PosType, modPositionReleaseRow.PlcPos, modDevice.ReleaseRow.ToString());
            //放货列
            var modPositionReleaseCol = listPosition.FirstOrDefault(s => s.Text == "放货列");
            if (modPositionReleaseRow != null)
                modUtil.SetPlcDBValue(modPositionReleaseCol.PosType, modPositionReleaseCol.PlcPos, modDevice.ReleaseCol.ToString());
            //放货层
            var modPositionReleaseStorey = listPosition.FirstOrDefault(s => s.Text == "放货层");
            if (modPositionReleaseStorey != null)
                modUtil.SetPlcDBValue(modPositionReleaseStorey.PosType, modPositionReleaseStorey.PlcPos, modDevice.ReleaseStorey.ToString());
            //取货排
            var modPositionPickRow = listPosition.FirstOrDefault(s => s.Text == "取货排");
            if (modPositionPickRow != null)
                modUtil.SetPlcDBValue(modPositionPickRow.PosType, modPositionPickRow.PlcPos, modDevice.PickRow.ToString());
            //取货列
            var modPositionPickCol = listPosition.FirstOrDefault(s => s.Text == "取货列");
            if (modPositionPickCol != null)
                modUtil.SetPlcDBValue(modPositionPickCol.PosType, modPositionPickCol.PlcPos, modDevice.PickCol.ToString());
            //取货层
            var modPositionPickStorey = listPosition.FirstOrDefault(s => s.Text == "取货层");
            if (modPositionPickStorey != null)
                modUtil.SetPlcDBValue(modPositionPickStorey.PosType, modPositionPickStorey.PlcPos, modDevice.PickStorey.ToString());
        }
        modUtil.Close();
    }
    #region 分拣码垛
@@ -304,8 +395,8 @@
    [HttpGet]
    [ApiDescriptionSettings(Name = "WcsPackStationPlcList")]
    [DisplayName("获取设备对应工位列表")]
    public async Task<List<WcsDeviceTaskOrderDto>> WcsPackStationPlcList([FromQuery]WcsDeviceBaseInput entry)
    {
    public async Task<List<WcsDeviceTaskOrderDto>> WcsPackStationPlcList([FromQuery] WcsDeviceBaseInput entry)
    {
        return await _wcsDeviceRep.Context.Queryable<WcsDevice>()
                .LeftJoin<WcsCheckTask>((device, task) => device.StationNum == task.Port)
                .Where((device, task) => device.PlcId == entry.PlcId)
@@ -318,7 +409,9 @@
                    LotNo=task.LotNo,
                    SkuNo=task.SkuNo,
                    SkuName=task.SkuName,
                    Status=task.Status,
                    LineNO=task.LineNO,
                    Status =task.Status,
                    PZNo=task.PZNo,
                    Qty=task.Qty
                })
                .ToListAsync();
Admin.NET/WCS.Application/Service/WcsMateialPzInfo/Dto/WcsMateialPzInfoDto.cs
New file
@@ -0,0 +1,119 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace WCS.Application;
    /// <summary>
    /// 物料品种信息维护表输出参数
    /// </summary>
    public class WcsMateialPzInfoDto
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        public long Id { get; set; }
        /// <summary>
        /// 物料编码
        /// </summary>
        public string? SkuNo { get; set; }
        /// <summary>
        /// 物料名称
        /// </summary>
        public string? SkuName { get; set; }
        /// <summary>
        /// 长
        /// </summary>
        public string? Length { get; set; }
        /// <summary>
        /// 宽
        /// </summary>
        public string? Width { get; set; }
        /// <summary>
        /// 高
        /// </summary>
        public string? Height { get; set; }
        /// <summary>
        /// 品种号
        /// </summary>
        public string? PZNo { get; set; }
        /// <summary>
        /// 备用字段1
        /// </summary>
        public string? UDF1 { get; set; }
        /// <summary>
        /// 备用字段2
        /// </summary>
        public string? UDF2 { get; set; }
        /// <summary>
        /// 备用字段3
        /// </summary>
        public string? UDF3 { get; set; }
        /// <summary>
        /// 备用字段4
        /// </summary>
        public string? UDF4 { get; set; }
        /// <summary>
        /// 备用字段5
        /// </summary>
        public string? UDF5 { get; set; }
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime? CreateTime { get; set; }
        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime? UpdateTime { get; set; }
        /// <summary>
        /// 创建者Id
        /// </summary>
        public long? CreateUserId { get; set; }
        /// <summary>
        /// 创建者姓名
        /// </summary>
        public string? CreateUserName { get; set; }
        /// <summary>
        /// 修改者Id
        /// </summary>
        public long? UpdateUserId { get; set; }
        /// <summary>
        /// 修改者姓名
        /// </summary>
        public string? UpdateUserName { get; set; }
        /// <summary>
        /// 创建者部门Id
        /// </summary>
        public long? CreateOrgId { get; set; }
        /// <summary>
        /// 创建者部门名称
        /// </summary>
        public string? CreateOrgName { get; set; }
        /// <summary>
        /// 软删除
        /// </summary>
        public bool IsDelete { get; set; }
    }
Admin.NET/WCS.Application/Service/WcsMateialPzInfo/Dto/WcsMateialPzInfoInput.cs
New file
@@ -0,0 +1,200 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core;
using System.ComponentModel.DataAnnotations;
namespace WCS.Application;
    /// <summary>
    /// 物料品种信息维护表基础输入参数
    /// </summary>
    public class WcsMateialPzInfoBaseInput
    {
        /// <summary>
        /// 物料编码
        /// </summary>
        public virtual string? SkuNo { get; set; }
        /// <summary>
        /// 物料名称
        /// </summary>
        public virtual string? SkuName { get; set; }
        /// <summary>
        /// 长
        /// </summary>
        public virtual string? Length { get; set; }
        /// <summary>
        /// 宽
        /// </summary>
        public virtual string? Width { get; set; }
        /// <summary>
        /// 高
        /// </summary>
        public virtual string? Height { get; set; }
        /// <summary>
        /// 品种号
        /// </summary>
        public virtual string? PZNo { get; set; }
        /// <summary>
        /// 备用字段1
        /// </summary>
        public virtual string? UDF1 { get; set; }
        /// <summary>
        /// 备用字段2
        /// </summary>
        public virtual string? UDF2 { get; set; }
        /// <summary>
        /// 备用字段3
        /// </summary>
        public virtual string? UDF3 { get; set; }
        /// <summary>
        /// 备用字段4
        /// </summary>
        public virtual string? UDF4 { get; set; }
        /// <summary>
        /// 备用字段5
        /// </summary>
        public virtual string? UDF5 { get; set; }
        /// <summary>
        /// 创建时间
        /// </summary>
        public virtual DateTime? CreateTime { get; set; }
        /// <summary>
        /// 更新时间
        /// </summary>
        public virtual DateTime? UpdateTime { get; set; }
        /// <summary>
        /// 创建者Id
        /// </summary>
        public virtual long? CreateUserId { get; set; }
        /// <summary>
        /// 创建者姓名
        /// </summary>
        public virtual string? CreateUserName { get; set; }
        /// <summary>
        /// 修改者Id
        /// </summary>
        public virtual long? UpdateUserId { get; set; }
        /// <summary>
        /// 修改者姓名
        /// </summary>
        public virtual string? UpdateUserName { get; set; }
        /// <summary>
        /// 创建者部门Id
        /// </summary>
        public virtual long? CreateOrgId { get; set; }
        /// <summary>
        /// 创建者部门名称
        /// </summary>
        public virtual string? CreateOrgName { get; set; }
        /// <summary>
        /// 软删除
        /// </summary>
        public virtual bool IsDelete { get; set; }
    }
    /// <summary>
    /// 物料品种信息维护表分页查询输入参数
    /// </summary>
    public class PageWcsMateialPzInfoInput : BasePageInput
    {
        /// <summary>
        /// 关键字查询
        /// </summary>
        public string? SearchKey { get; set; }
        /// <summary>
        /// 物料编码
        /// </summary>
        public string? SkuNo { get; set; }
        /// <summary>
        /// 物料名称
        /// </summary>
        public string? SkuName { get; set; }
        /// <summary>
        /// 长
        /// </summary>
        public string? Length { get; set; }
        /// <summary>
        /// 宽
        /// </summary>
        public string? Width { get; set; }
        /// <summary>
        /// 高
        /// </summary>
        public string? Height { get; set; }
        /// <summary>
        /// 品种号
        /// </summary>
        public string? PZNo { get; set; }
    }
    /// <summary>
    /// 物料品种信息维护表增加输入参数
    /// </summary>
    public class AddWcsMateialPzInfoInput : WcsMateialPzInfoBaseInput
    {
        /// <summary>
        /// 软删除
        /// </summary>
        [Required(ErrorMessage = "软删除不能为空")]
        public override bool IsDelete { get; set; }
    }
    /// <summary>
    /// 物料品种信息维护表删除输入参数
    /// </summary>
    public class DeleteWcsMateialPzInfoInput : BaseIdInput
    {
    }
    /// <summary>
    /// 物料品种信息维护表更新输入参数
    /// </summary>
    public class UpdateWcsMateialPzInfoInput : WcsMateialPzInfoBaseInput
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        [Required(ErrorMessage = "主键Id不能为空")]
        public long Id { get; set; }
    }
    /// <summary>
    /// 物料品种信息维护表主键查询输入参数
    /// </summary>
    public class QueryByIdWcsMateialPzInfoInput : DeleteWcsMateialPzInfoInput
    {
    }
Admin.NET/WCS.Application/Service/WcsMateialPzInfo/Dto/WcsMateialPzInfoOutput.cs
New file
@@ -0,0 +1,121 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace WCS.Application;
/// <summary>
/// 物料品种信息维护表输出参数
/// </summary>
public class WcsMateialPzInfoOutput
{
    /// <summary>
    /// 主键Id
    /// </summary>
    public long Id { get; set; }
    /// <summary>
    /// 物料编码
    /// </summary>
    public string? SkuNo { get; set; }
    /// <summary>
    /// 物料名称
    /// </summary>
    public string? SkuName { get; set; }
    /// <summary>
    /// 长
    /// </summary>
    public string? Length { get; set; }
    /// <summary>
    /// 宽
    /// </summary>
    public string? Width { get; set; }
    /// <summary>
    /// 高
    /// </summary>
    public string? Height { get; set; }
    /// <summary>
    /// 品种号
    /// </summary>
    public string? PZNo { get; set; }
    /// <summary>
    /// 备用字段1
    /// </summary>
    public string? UDF1 { get; set; }
    /// <summary>
    /// 备用字段2
    /// </summary>
    public string? UDF2 { get; set; }
    /// <summary>
    /// 备用字段3
    /// </summary>
    public string? UDF3 { get; set; }
    /// <summary>
    /// 备用字段4
    /// </summary>
    public string? UDF4 { get; set; }
    /// <summary>
    /// 备用字段5
    /// </summary>
    public string? UDF5 { get; set; }
    /// <summary>
    /// 创建时间
    /// </summary>
    public DateTime? CreateTime { get; set; }
    /// <summary>
    /// 更新时间
    /// </summary>
    public DateTime? UpdateTime { get; set; }
    /// <summary>
    /// 创建者Id
    /// </summary>
    public long? CreateUserId { get; set; }
    /// <summary>
    /// 创建者姓名
    /// </summary>
    public string? CreateUserName { get; set; }
    /// <summary>
    /// 修改者Id
    /// </summary>
    public long? UpdateUserId { get; set; }
    /// <summary>
    /// 修改者姓名
    /// </summary>
    public string? UpdateUserName { get; set; }
    /// <summary>
    /// 创建者部门Id
    /// </summary>
    public long? CreateOrgId { get; set; }
    /// <summary>
    /// 创建者部门名称
    /// </summary>
    public string? CreateOrgName { get; set; }
    /// <summary>
    /// 软删除
    /// </summary>
    public bool IsDelete { get; set; }
    }
Admin.NET/WCS.Application/Service/WcsMateialPzInfo/WcsMateialPzInfoService.cs
New file
@@ -0,0 +1,128 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.Service;
using Microsoft.AspNetCore.Http;
using WCS.Application.Entity;
namespace WCS.Application;
/// <summary>
/// 物料品种信息维护表服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class WcsMateialPzInfoService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<WcsMateialPzInfo> _wcsMateialPzInfoRep;
    public WcsMateialPzInfoService(SqlSugarRepository<WcsMateialPzInfo> wcsMateialPzInfoRep)
    {
        _wcsMateialPzInfoRep = wcsMateialPzInfoRep;
    }
    /// <summary>
    /// 分页查询物料品种信息维护表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询物料品种信息维护表")]
    public async Task<SqlSugarPagedList<WcsMateialPzInfoOutput>> Page(PageWcsMateialPzInfoInput input)
    {
        input.SearchKey = input.SearchKey?.Trim();
        var query = _wcsMateialPzInfoRep.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
                u.SkuNo.Contains(input.SearchKey)
                || u.SkuName.Contains(input.SearchKey)
                || u.Length.Contains(input.SearchKey)
                || u.Width.Contains(input.SearchKey)
                || u.Height.Contains(input.SearchKey)
                || u.PZNo.Contains(input.SearchKey)
            )
            .WhereIF(!string.IsNullOrWhiteSpace(input.SkuNo), u => u.SkuNo.Contains(input.SkuNo.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.SkuName), u => u.SkuName.Contains(input.SkuName.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Length), u => u.Length.Contains(input.Length.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Width), u => u.Width.Contains(input.Width.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Height), u => u.Height.Contains(input.Height.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.PZNo), u => u.PZNo.Contains(input.PZNo.Trim()))
            .Select<WcsMateialPzInfoOutput>();
        return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
    }
    /// <summary>
    /// 增加物料品种信息维护表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    [DisplayName("增加物料品种信息维护表")]
    public async Task<long> Add(AddWcsMateialPzInfoInput input)
    {
        var entity = input.Adapt<WcsMateialPzInfo>();
        await _wcsMateialPzInfoRep.InsertAsync(entity);
        return entity.Id;
    }
    /// <summary>
    /// 删除物料品种信息维护表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除物料品种信息维护表")]
    public async Task Delete(DeleteWcsMateialPzInfoInput input)
    {
        var entity = await _wcsMateialPzInfoRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _wcsMateialPzInfoRep.FakeDeleteAsync(entity);   //假删除
        //await _wcsMateialPzInfoRep.DeleteAsync(entity);   //真删除
    }
    /// <summary>
    /// 更新物料品种信息维护表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新物料品种信息维护表")]
    public async Task Update(UpdateWcsMateialPzInfoInput input)
    {
        var entity = input.Adapt<WcsMateialPzInfo>();
        await _wcsMateialPzInfoRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }
    /// <summary>
    /// 获取物料品种信息维护表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取物料品种信息维护表")]
    public async Task<WcsMateialPzInfo> Detail([FromQuery] QueryByIdWcsMateialPzInfoInput input)
    {
        return await _wcsMateialPzInfoRep.GetFirstAsync(u => u.Id == input.Id);
    }
    /// <summary>
    /// 获取物料品种信息维护表列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取物料品种信息维护表列表")]
    public async Task<List<WcsMateialPzInfoOutput>> List([FromQuery] PageWcsMateialPzInfoInput input)
    {
        return await _wcsMateialPzInfoRep.AsQueryable().Select<WcsMateialPzInfoOutput>().ToListAsync();
    }
}
Web/src/api/wcs/wcsDevice.ts
@@ -8,6 +8,7 @@
  GetWcsPlcPlcIdDropdown = '/api/wcsDevice/WcsPlcPlcIdDropdown',
  GeneratePos = '/api/wcsDevice/GeneratePos',
  ListWcsDevice = '/api/wcsDevice/list',
  WriteValue = '/api/wcsdevice/writeValue',
  GetWcsPackPlcList='/api/wcsDevice/WcsPackPlcList',
  GetWcsPackStationPlcList='/api/wcsDevice/WcsPackStationPlcList',
@@ -101,4 +102,11 @@
        url: Api.CloseTaskForPLC,
        method: 'post',
        data: params,
});
//写入值
export const writeValue = (params?: any) =>
    request({
        url: Api.WriteValue,
        method: 'post',
        data: params,
});
Web/src/api/wcs/wcsMateialPzInfo.ts
New file
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
enum Api {
  AddWcsMateialPzInfo = '/api/wcsMateialPzInfo/add',
  DeleteWcsMateialPzInfo = '/api/wcsMateialPzInfo/delete',
  UpdateWcsMateialPzInfo = '/api/wcsMateialPzInfo/update',
  PageWcsMateialPzInfo = '/api/wcsMateialPzInfo/page',
  DetailWcsMateialPzInfo = '/api/wcsMateialPzInfo/detail',
}
// 增加物料品种信息维护表
export const addWcsMateialPzInfo = (params?: any) =>
    request({
        url: Api.AddWcsMateialPzInfo,
        method: 'post',
        data: params,
    });
// 删除物料品种信息维护表
export const deleteWcsMateialPzInfo = (params?: any) =>
    request({
            url: Api.DeleteWcsMateialPzInfo,
            method: 'post',
            data: params,
        });
// 编辑物料品种信息维护表
export const updateWcsMateialPzInfo = (params?: any) =>
    request({
            url: Api.UpdateWcsMateialPzInfo,
            method: 'post',
            data: params,
        });
// 分页查询物料品种信息维护表
export const pageWcsMateialPzInfo = (params?: any) =>
    request({
            url: Api.PageWcsMateialPzInfo,
            method: 'post',
            data: params,
        });
// 详情物料品种信息维护表
export const detailWcsMateialPzInfo = (id: any) =>
    request({
            url: Api.DetailWcsMateialPzInfo,
            method: 'get',
            data: { id },
        });
Web/src/views/device/deviceMonitor/component/setting.vue
@@ -10,7 +10,7 @@
            <el-card class="box-card" shadow="hover">
                <template #header>
                    <div class="card-header">
                        <div>
                            <span>工位号:</span>
                            <el-select v-model="stationValue" placeholder="请选择" filterable value-key="stationNum"
@@ -22,7 +22,8 @@
                            <el-button style="margin-left: 10px;">自动</el-button>
                        </div>
                        <div>
                            <div :class="['lineStatus', stationValue.status ? 'device-status-0' : 'device-status-1']"></div>
                            <div :class="['lineStatus', stationValue.status ? 'device-status-0' : 'device-status-1']">
                            </div>
                        </div>
                    </div>
                </template>
@@ -49,41 +50,41 @@
                                    <el-input v-model="stationValue.wcs"></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="取货排">
                                    <el-input ></el-input>
                                    <el-input></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="放货排">
                                    <el-input ></el-input>
                                    <el-input></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="取货列">
                                    <el-input ></el-input>
                                    <el-input></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="放货列">
                                    <el-input ></el-input>
                                    <el-input></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="取货层">
                                    <el-input ></el-input>
                                    <el-input></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="放货层">
                                    <el-input ></el-input>
                                    <el-input></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </el-form>
                    <div style="text-align: center;margin: 10px;">
                        <el-button class="button" size="large">写入数据</el-button>
                        <el-button class="button" size="large" @click="write(stationValue)">写入数据</el-button>
                    </div>
                </div>
                <template #footer>
@@ -107,6 +108,8 @@
<script lang="ts" setup>
import { ref, defineModel } from 'vue';
import { writeValue } from '/@/api/wcs/wcsDevice';
import { ElMessageBox,ElMessage } from 'element-plus';
const listStationsData = defineModel<any>("listStationsData")
const stationValue = defineModel<any>("stationValue")
@@ -122,7 +125,10 @@
//     emit('update:listStationsData', listStationsData.value);
//     emit('update:stationValue', stationValue);
// };
const write = async (row: any) => {
    await writeValue(row);
    ElMessage.success('写入成功!');
}
const isShowDialog = ref(false);
const openDialog = async (row: any) => {
@@ -181,18 +187,18 @@
}
.lineStatus {
    right: 0;
    height: 20px;
    width: 20px;
    border-radius: 50%;
    background-color: #67C23A;
    right: 0;
    height: 20px;
    width: 20px;
    border-radius: 50%;
    background-color: #67C23A;
}
.device-status-0 {
    background-color: #67C23A;
    background-color: #67C23A;
}
.device-status-1 {
    background-color: red;
    background-color: red;
}
</style>
Web/src/views/device/deviceMonitor/index.vue
@@ -52,7 +52,6 @@
                <div class="lineButtonfix">
                    <el-form label-position="left" label-width="80px">
                        <el-form-item>
                            <el-button>写入</el-button>
                            <el-button @click="openDialog">设置</el-button>
                        </el-form-item>
                    </el-form>
@@ -85,6 +84,9 @@
                            <el-form-item label="目的工位">
                                <el-input v-model="deviceInfo.endLocatNo"></el-input>
                            </el-form-item>
                            <el-form-item label="托盘码">
                                <el-input v-model="deviceInfo.palletNo"></el-input>
                            </el-form-item>
                            <el-form-item label="PLC">
                                <el-input v-model="deviceInfo.plc"></el-input>
                            </el-form-item>
@@ -99,24 +101,50 @@
                    <div class="otherButtonfix">
                        <el-form label-position="left">
                            <el-form-item>
                                <el-button>写入</el-button>
                                <el-button @click="write(deviceInfo)">写入</el-button>
                            </el-form-item>
                        </el-form>
                    </div>
                </el-card>
            </div>
        </el-main>
        <setting ref="settingDialogRef" :title="title" v-model:listStationsData="listStationsData" v-model:stationValue="stationValue" />
        <setting ref="settingDialogRef" :title="title" v-model:listStationsData="listStationsData"
            v-model:stationValue="stationValue" />
    </el-container>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { listWcsDevice } from '/@/api/wcs/wcsDevice';
import { ref, onMounted  } from 'vue';
import { listWcsDevice, writeValue } from '/@/api/wcs/wcsDevice';
import { getDictDataItem as di, getDictDataList as dl } from '/@/utils/dict-utils';
import { listWcsPlc } from '/@/api/wcs/wcsPlc';
import { ElMessageBox, ElMessage } from 'element-plus';
import setting from '/@/views/device/deviceMonitor/component/setting.vue'
import { signalR,stopConnection } from './signalR';
//连接signalR 监听变更
onMounted(async () => {
    signalR.off('PublicPlcDevice');
    signalR.on('PublicPlcDevice', (data: any) => {
        //todo 需要测试
        if (data.type == 0) {
            var index = listStackingMachineData.value.findIndex(s => s.id == data.id);
            if (index !== -1) {
                listStackingMachineData.value.splice(index, 1, data);
            }
        }
        else if (data.type == 1) {
            lineOptions.value.forEach(s => {
                var index = stations.value[s.id].findIndex(s => s.id == data.id);
                if (index !== -1) {
                    stations.value[s.id].splice(index, 1, data);
                }
            });
            if (stationValue.value.id == data.id) {
                stationValue.value = data;
            }
        }
    });
});
const stations = ref<any>([]);
const listStationsData = ref<any>([]);
@@ -138,12 +166,16 @@
const openDialog = async () => {
    settingDialogRef.value.openDialog(stationValue);
}
const write = async (row: any) => {
    await writeValue(row);
    ElMessage.success('写入成功!');
}
// 查询操作
const handleQuery = async () => {
    var listplc = await listWcsPlc({ type: 1 });
    const listplc = await listWcsPlc({ type: 1 });
    lineOptions.value = listplc.data.result;
    lineValue.value = listplc.data.result[0].id;
    var res = await listWcsDevice();
    const res = await listWcsDevice();
    listStackingMachineData.value = res.data.result.filter(s => s.type == 0);
    const listConveyorLineData = res.data.result.filter(s => s.type == 1);
    listplc.data.result.forEach(s => {
@@ -153,6 +185,19 @@
        listStationsData.value = stations.value[lineValue.value];
        stationValue.value = listStationsData.value[0];
    }
    else {
        listStationsData.value = [];
        stationValue.value = {
            stationNum: '',
            taskNo: '',
            taskType: '',
            startLocatNo: '',
            endLocatNo: '',
            plc: '',
            wcs: '',
            status: false
        };
    }
    title.value = listStationsData.value[0].text;
};
Web/src/views/device/deviceMonitor/signalR.ts
New file
@@ -0,0 +1,49 @@
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/PlcDevice?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(() => {
    debugger;
    console.log('启动连接plc');
});
// 断开连接
connection.onclose(async () => {
    debugger;
    console.log('断开连接plc');
});
// 重连中
connection.onreconnecting(() => {
    debugger;
    console.log('服务器已断线plc');
});
// 重连成功
connection.onreconnected(() => {
    debugger;
    console.log('重连成功plc');
});
// 关闭连接的方法
async function stopConnection() {
    try {
      await connection.stop();
      console.log('连接已关闭');
    } catch (error) {
      console.error('关闭连接时发生错误:', error);
    }
  }
// connection.on('PublicPlcConn', () => {});
export { connection as signalR,stopConnection };
Web/src/views/device/sortPallet/index.vue
@@ -39,11 +39,14 @@
                                <el-form-item label="物料名称">
                                    <el-input v-model="deviceInfo.skuName" readonly></el-input>
                                </el-form-item>
                                <el-form-item label="分拣线编号">
                                    <el-input v-model="deviceInfo.lineNO" readonly></el-input>
                                </el-form-item>
                                <el-form-item label="绑定状态">
                                    <el-input :value="deviceInfo.status === '0' ? '未绑定' : '已绑定'" readonly></el-input>
                                </el-form-item>
                                <el-form-item label="抓箱品种">
                                    <el-input readonly></el-input>
                                    <el-input v-model="deviceInfo.pzNo" readonly></el-input>
                                </el-form-item>
                                <el-form-item label="托盘号">
                                    <el-input readonly></el-input>
@@ -59,7 +62,7 @@
                                </el-form-item>
                            </el-form>
                        </div>
                        <div class="otherButtonfix">
                        <div v-if="!deviceInfo.text.includes('拆垛')" class="otherButtonfix">
                            <el-form label-position="left">
                                <el-form-item>
                                    <el-button type="primary" @click="openBindDialog(deviceInfo.id)">绑定</el-button>
@@ -274,5 +277,8 @@
        justify-content: flex-end;
        margin-top: 20px;
    }
    .divDisplay{
        display:none
    }
</style>
  
Web/src/views/device/wcsOderTask/component/editDialog.vue
@@ -71,7 +71,7 @@
                        </el-form-item>
                        
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                    <!-- <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="状态" prop="status">
                            <el-select clearable v-model="ruleForm.status" placeholder="请选择状态">
                                <el-option v-for="(item,index) in dl('TaskStatusEnum')" :key="index" :value="Number(item.value)" :label="`${item.name} (${item.code}) [${item.value}]`"></el-option>
@@ -80,7 +80,7 @@
                            
                        </el-form-item>
                        
                    </el-col>
                    </el-col> -->
                    <!-- <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="是否回馈成功" prop="isSuccess">
                            <el-select clearable v-model="ruleForm.isSuccess" placeholder="请选择是否回馈成功">
Web/src/views/wcs/wcsMateialPzInfo/component/editDialog.vue
New file
@@ -0,0 +1,191 @@
<template>
    <div class="wcsMateialPzInfo-container">
        <el-dialog v-model="isShowDialog" :width="800" draggable="" :close-on-click-modal="false">
            <template #header>
                <div style="color: #fff">
                    <!--<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>-->
                    <span>{{ props.title }}</span>
                </div>
            </template>
            <el-form :model="ruleForm" ref="ruleFormRef" label-width="auto" :rules="rules">
                <el-row :gutter="35">
                    <el-form-item v-show="false">
                        <el-input v-model="ruleForm.id" />
                    </el-form-item>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="物料编码" prop="skuNo">
                            <el-input v-model="ruleForm.skuNo" placeholder="请输入物料编码" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="物料名称" prop="skuName">
                            <el-input v-model="ruleForm.skuName" placeholder="请输入物料名称" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="长" prop="length">
                            <el-input v-model="ruleForm.length" placeholder="请输入长" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="宽" prop="width">
                            <el-input v-model="ruleForm.width" placeholder="请输入宽" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="高" prop="height">
                            <el-input v-model="ruleForm.height" placeholder="请输入高" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="品种号" prop="pZNo">
                            <el-input v-model="ruleForm.pzNo" placeholder="请输入品种号" maxlength="10" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="备用字段1" prop="uDF1">
                            <el-input v-model="ruleForm.uDF1" placeholder="请输入备用字段1" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="备用字段2" prop="uDF2">
                            <el-input v-model="ruleForm.uDF2" placeholder="请输入备用字段2" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="备用字段3" prop="uDF3">
                            <el-input v-model="ruleForm.uDF3" placeholder="请输入备用字段3" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="备用字段4" prop="uDF4">
                            <el-input v-model="ruleForm.uDF4" placeholder="请输入备用字段4" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="备用字段5" prop="uDF5">
                            <el-input v-model="ruleForm.uDF5" placeholder="请输入备用字段5" maxlength="20" show-word-limit clearable />
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="cancel">取 消</el-button>
                    <el-button type="primary" @click="submit">确 定</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<style lang="scss" scoped>
:deep(.el-select),
:deep(.el-input-number) {
    width: 100%;
}
</style>
<script lang="ts" setup>
    import { ref,onMounted } from "vue";
    import { ElMessage } from "element-plus";
    import type { FormRules } from "element-plus";
      import { formatDate } from '/@/utils/formatTime';
    import { addWcsMateialPzInfo, updateWcsMateialPzInfo, detailWcsMateialPzInfo } from "/@/api/wcs/wcsMateialPzInfo";
    //父级传递来的参数
    var props = defineProps({
        title: {
        type: String,
        default: "",
    },
    });
    //父级传递来的函数,用于回调
    const emit = defineEmits(["reloadTable"]);
    const ruleFormRef = ref();
    const isShowDialog = ref(false);
    const ruleForm = ref<any>({});
    //自行添加其他规则
    const rules = ref<FormRules>({
    });
    // 页面加载时
    onMounted(() => {
    });
    // 打开弹窗
    const openDialog = async (row: any) => {
        // ruleForm.value = JSON.parse(JSON.stringify(row));
        // 改用detail获取最新数据来编辑
        let rowData = JSON.parse(JSON.stringify(row));
        if (rowData.id)
            ruleForm.value = (await detailWcsMateialPzInfo(rowData.id)).data.result;
        else
            ruleForm.value = rowData;
        isShowDialog.value = true;
    };
    // 关闭弹窗
    const closeDialog = () => {
        emit("reloadTable");
        isShowDialog.value = false;
    };
    // 取消
    const cancel = () => {
        isShowDialog.value = false;
    };
    // 提交
    const submit = async () => {
        ruleFormRef.value.validate(async (isValid: boolean, fields?: any) => {
            if (isValid) {
                let values = ruleForm.value;
                if (ruleForm.value.id == undefined || ruleForm.value.id == null || ruleForm.value.id == "" || ruleForm.value.id == 0) {
                    await addWcsMateialPzInfo(values);
                } else {
                    await updateWcsMateialPzInfo(values);
                }
                closeDialog();
            } else {
                ElMessage({
                    message: `表单有${Object.keys(fields).length}处验证失败,请修改后再提交`,
                    type: "error",
                });
            }
        });
    };
    //将属性或者函数暴露给父组件
    defineExpose({ openDialog });
</script>
Web/src/views/wcs/wcsMateialPzInfo/index.vue
New file
@@ -0,0 +1,217 @@
<template>
  <div class="wcsMateialPzInfo-container">
    <el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
      <el-form :model="queryParams" ref="queryForm" labelWidth="90">
        <el-row>
          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10">
            <el-form-item label="关键字">
              <el-input v-model="queryParams.searchKey" clearable="" placeholder="请输入模糊查询关键字"/>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10" v-if="showAdvanceQueryUI">
            <el-form-item label="物料编码">
              <el-input v-model="queryParams.skuNo" clearable="" placeholder="请输入物料编码"/>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10" v-if="showAdvanceQueryUI">
            <el-form-item label="物料名称">
              <el-input v-model="queryParams.skuName" clearable="" placeholder="请输入物料名称"/>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10" v-if="showAdvanceQueryUI">
            <el-form-item label="长">
              <el-input v-model="queryParams.length" clearable="" placeholder="请输入长"/>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10" v-if="showAdvanceQueryUI">
            <el-form-item label="宽">
              <el-input v-model="queryParams.width" clearable="" placeholder="请输入宽"/>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10" v-if="showAdvanceQueryUI">
            <el-form-item label="高">
              <el-input v-model="queryParams.height" clearable="" placeholder="请输入高"/>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10" v-if="showAdvanceQueryUI">
            <el-form-item label="品种号">
              <el-input v-model="queryParams.pZNo" clearable="" placeholder="请输入品种号"/>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10">
            <el-form-item >
              <el-button-group style="display: flex; align-items: center;">
                <el-button type="primary"  icon="ele-Search" @click="handleQuery" v-auth="'wcsMateialPzInfo:page'"> 查询 </el-button>
                      <el-button icon="ele-Refresh" @click="() => queryParams = {}"> 重置 </el-button>
                        <el-button icon="ele-ZoomIn" @click="changeAdvanceQueryUI" v-if="!showAdvanceQueryUI" style="margin-left:5px;"> 高级查询 </el-button>
                        <el-button icon="ele-ZoomOut" @click="changeAdvanceQueryUI" v-if="showAdvanceQueryUI" style="margin-left:5px;"> 隐藏 </el-button>
                <el-button type="primary" style="margin-left:5px;" icon="ele-Plus" @click="openAddWcsMateialPzInfo" v-auth="'wcsMateialPzInfo:add'"> 新增 </el-button>
              </el-button-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </el-card>
    <el-card class="full-table" shadow="hover" style="margin-top: 5px">
      <el-table
                :data="tableData"
                style="width: 100%"
                v-loading="loading"
                tooltip-effect="light"
                                row-key="id"
                @sort-change="sortChange"
                border="">
        <el-table-column type="index" label="序号" width="55" align="center"/>
        <el-table-column prop="skuNo" label="物料编码"  show-overflow-tooltip="" />
        <el-table-column prop="skuName" label="物料名称"  show-overflow-tooltip="" />
        <el-table-column prop="length" label="长"  show-overflow-tooltip="" />
        <el-table-column prop="width" label="宽"  show-overflow-tooltip="" />
        <el-table-column prop="height" label="高"  show-overflow-tooltip="" />
        <el-table-column prop="pzNo" label="品种号"  show-overflow-tooltip="" />
        <el-table-column prop="uDF1" label="备用字段1"  show-overflow-tooltip="" />
        <el-table-column prop="uDF2" label="备用字段2"  show-overflow-tooltip="" />
        <el-table-column prop="uDF3" label="备用字段3"  show-overflow-tooltip="" />
        <el-table-column prop="uDF4" label="备用字段4"  show-overflow-tooltip="" />
        <el-table-column prop="uDF5" label="备用字段5"  show-overflow-tooltip="" />
        <el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('wcsMateialPzInfo:update') || auth('wcsMateialPzInfo:delete')">
          <template #default="scope">
            <el-button icon="ele-Edit" size="small" text="" type="primary" @click="openEditWcsMateialPzInfo(scope.row)" v-auth="'wcsMateialPzInfo:update'"> 编辑 </el-button>
            <el-button icon="ele-Delete" size="small" text="" type="primary" @click="delWcsMateialPzInfo(scope.row)" v-auth="'wcsMateialPzInfo:delete'"> 删除 </el-button>
          </template>
        </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="total, sizes, prev, pager, next, jumper"
    />
      <printDialog
        ref="printDialogRef"
        :title="printWcsMateialPzInfoTitle"
        @reloadTable="handleQuery" />
      <editDialog
        ref="editDialogRef"
        :title="editWcsMateialPzInfoTitle"
        @reloadTable="handleQuery"
      />
    </el-card>
  </div>
</template>
<script lang="ts" setup="" name="wcsMateialPzInfo">
  import { ref } from "vue";
  import { ElMessageBox, ElMessage } from "element-plus";
  import { auth } from '/@/utils/authFunction';
  import { formatDate } from '/@/utils/formatTime';
  import printDialog from '/@/views/system/print/component/hiprint/preview.vue'
  import editDialog from '/@/views/wcs/wcsMateialPzInfo/component/editDialog.vue'
  import { pageWcsMateialPzInfo, deleteWcsMateialPzInfo } from '/@/api/wcs/wcsMateialPzInfo';
  const showAdvanceQueryUI = ref(false);
  const printDialogRef = ref();
  const editDialogRef = ref();
  const loading = ref(false);
  const tableData = ref<any>([]);
  const queryParams = ref<any>({});
  const tableParams = ref({
    page: 1,
    pageSize: 10,
    total: 0,
  });
  const printWcsMateialPzInfoTitle = ref("");
  const editWcsMateialPzInfoTitle = ref("");
  // 改变高级查询的控件显示状态
  const changeAdvanceQueryUI = () => {
    showAdvanceQueryUI.value = !showAdvanceQueryUI.value;
  }
  // 查询操作
  const handleQuery = async () => {
    loading.value = true;
    var res = await pageWcsMateialPzInfo(Object.assign(queryParams.value, tableParams.value));
    tableData.value = res.data.result?.items ?? [];
    tableParams.value.total = res.data.result?.total;
    loading.value = false;
  };
  // 列排序
  const sortChange = async (column: any) => {
    queryParams.value.field = column.prop;
    queryParams.value.order = column.order;
    await handleQuery();
  };
  // 打开新增页面
  const openAddWcsMateialPzInfo = () => {
    editWcsMateialPzInfoTitle.value = '添加物料品种信息';
    editDialogRef.value.openDialog({});
  };
  // 打开打印页面
  const openPrintWcsMateialPzInfo = async (row: any) => {
    printWcsMateialPzInfoTitle.value = '打印物料品种信息';
  }
  // 打开编辑页面
  const openEditWcsMateialPzInfo = (row: any) => {
    editWcsMateialPzInfoTitle.value = '编辑物料品种信息';
    editDialogRef.value.openDialog(row);
  };
  // 删除
  const delWcsMateialPzInfo = (row: any) => {
    ElMessageBox.confirm(`确定要删除吗?`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
  .then(async () => {
    await deleteWcsMateialPzInfo(row);
    handleQuery();
    ElMessage.success("删除成功");
  })
  .catch(() => {});
  };
  // 改变页面容量
  const handleSizeChange = (val: number) => {
    tableParams.value.pageSize = val;
    handleQuery();
  };
  // 改变页码序号
  const handleCurrentChange = (val: number) => {
    tableParams.value.page = val;
    handleQuery();
  };
  handleQuery();
</script>
<style scoped>
:deep(.el-input),
:deep(.el-select),
:deep(.el-input-number) {
    width: 100%;
}
</style>