hwh
2024-08-16 7865b72aa43b2f24150f7c815f6dbcf2e8f2f283
设备PLC
1个文件已修改
26个文件已添加
2763 ■■■■■ 已修改文件
Admin.NET/WCS.Application/Configuration/Database.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Entity/WcsDevice.cs 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Entity/WcsPlc.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Entity/WcsplcStation.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Enum/PLCEnum.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceDto.cs 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceInput.cs 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceOutput.cs 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsDevice/WcsDeviceService.cs 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsPlc/Dto/WcsPlcDto.cs 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsPlc/Dto/WcsPlcInput.cs 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsPlc/Dto/WcsPlcOutput.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsPlc/WcsPlcService.cs 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsStation/Dto/WcsStationDto.cs 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsStation/Dto/WcsStationInput.cs 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsStation/Dto/WcsStationOutput.cs 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsStation/WcsStationService.cs 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/api/wcs/wcsDevice.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/api/wcs/wcsPlc.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/api/wcs/wcsStation.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/api/wcs/wcsplcStation.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsDevice/component/editDialog.vue 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsDevice/index.vue 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsPlc/component/editDialog.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsPlc/index.vue 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsStation/component/editDialog.vue 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/wcs/wcsStation/index.vue 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Configuration/Database.json
@@ -2,7 +2,7 @@
  // 详细数据库配置见SqlSugar官网(第一个为默认库),极力推荐 PostgreSQL 数据库
  // 数据库连接字符串参考地址:https://www.connectionstrings.com/
  "DbConnection": {
    "EnableConsoleSql": false, // 启用控制台打印SQL
    "EnableConsoleSql": true, // 启用控制台打印SQL
    "ConnectionConfigs": [
      {
        //"ConfigId": "1300000000001", // 默认库标识-禁止修改
Admin.NET/WCS.Application/Entity/WcsDevice.cs
New file
@@ -0,0 +1,65 @@

namespace WCS.Application;
/// <summary>
/// 设备信息表
/// </summary>
[SugarTable("WCSPLCDevice","设备信息表")]
public class WcsDevice  : EntityBaseData
{
    /// <summary>
    /// PlcId
    /// </summary>
    [Required]
    [SugarColumn(ColumnName = "PlcId", ColumnDescription = "PlcId")]
    public long PlcId { get; set; }
    /// <summary>
    /// 设备级别
    /// </summary>
    [SugarColumn(ColumnName = "Level", ColumnDescription = "设备级别")]
    public DeviceLevelEnum? Level { get; set; }
    /// <summary>
    /// DB区域
    /// </summary>
    [SugarColumn(ColumnName = "DbNumber", ColumnDescription = "DB区域", Length = 10)]
    public string? DbNumber { get; set; }
    /// <summary>
    /// 工位号
    /// </summary>
    [SugarColumn(ColumnName = "StationNum", ColumnDescription = "工位号", Length = 4)]
    public string? StationNum { get; set; }
    /// <summary>
    /// PLC偏移量
    /// </summary>
    [SugarColumn(ColumnName = "PlcPos", ColumnDescription = "PLC偏移量", Length = 10)]
    public string? PlcPos { get; set; }
    /// <summary>
    /// WCS偏移量
    /// </summary>
    [SugarColumn(ColumnName = "WcsPos", ColumnDescription = "WCS偏移量", Length = 10)]
    public string? WcsPos { get; set; }
    /// <summary>
    /// 流程字类型
    /// </summary>
    [SugarColumn(ColumnName = "PosType", ColumnDescription = "流程字类型", Length = 10)]
    public string? PosType { get; set; }
    /// <summary>
    /// 显示屏ip地址
    /// </summary>
    [SugarColumn(ColumnName = "LedIP", ColumnDescription = "显示屏ip地址", Length = 50)]
    public string? LedIP { get; set; }
    /// <summary>
    /// 描述
    /// </summary>
    [SugarColumn(ColumnName = "Text", ColumnDescription = "描述", Length = 20)]
    public string? Text { get; set; }
}
Admin.NET/WCS.Application/Entity/WcsPlc.cs
New file
@@ -0,0 +1,36 @@

namespace WCS.Application;
/// <summary>
/// PLC表
/// </summary>
[SugarTable("WCSPLC","PLC表")]
public class WcsPlc  : EntityBaseData
{
    /// <summary>
    /// PLCIP地址
    /// </summary>
    [Required]
    [SugarColumn(ColumnName = "IP", ColumnDescription = "PLCIP地址", Length = 20)]
    public string IP { get; set; }
    /// <summary>
    /// 设备类型
    /// </summary>
    [Required]
    [SugarColumn(ColumnName = "Type", ColumnDescription = "设备类型")]
    public PLCTypeEnum Type { get; set; }
    /// <summary>
    /// 仓库号
    /// </summary>
    [SugarColumn(ColumnName = "WareHouseNo", ColumnDescription = "仓库号", Length = 20)]
    public string? WareHouseNo { get; set; }
    /// <summary>
    /// 描述
    /// </summary>
    [SugarColumn(ColumnName = "Text", ColumnDescription = "描述", Length = 100)]
    public string? Text { get; set; }
}
Admin.NET/WCS.Application/Entity/WcsplcStation.cs
New file
@@ -0,0 +1,47 @@

namespace WCS.Application;
/// <summary>
/// 工位对应的流程字表
/// </summary>
[SugarTable("WCSPLCStation","工位对应的流程字表")]
public class WcsStation  : EntityBaseData
{
    /// <summary>
    /// 设备ID
    /// </summary>
    [Required]
    [SugarColumn(ColumnName = "DeviceId", ColumnDescription = "设备ID")]
    public long DeviceId { get; set; }
    /// <summary>
    /// 工位号
    /// </summary>
    [SugarColumn(ColumnName = "StationNum", ColumnDescription = "工位号", Length = 4)]
    public string? StationNum { get; set; }
    /// <summary>
    /// 偏移量
    /// </summary>
    [SugarColumn(ColumnName = "PlcPos", ColumnDescription = "偏移量", Length = 32)]
    public string? PlcPos { get; set; }
    /// <summary>
    /// 流程字类型
    /// </summary>
    [SugarColumn(ColumnName = "PosType", ColumnDescription = "流程字类型", Length = 10)]
    public string? PosType { get; set; }
    /// <summary>
    /// 显示屏ip地址
    /// </summary>
    [SugarColumn(ColumnName = "LedIP", ColumnDescription = "显示屏ip地址", Length = 50)]
    public string? LedIP { get; set; }
    /// <summary>
    /// 描述
    /// </summary>
    [SugarColumn(ColumnName = "Text", ColumnDescription = "描述", Length = 20)]
    public string? Text { get; set; }
}
Admin.NET/WCS.Application/Enum/PLCEnum.cs
New file
@@ -0,0 +1,47 @@

namespace WCS.Application;
/// <summary>
/// PLC类型枚举
/// </summary>
[Description("PLC类型枚举")]
public enum PLCTypeEnum
{
    /// <summary>
    /// 堆跺机
    /// </summary>
    [Description("堆跺机")]
    StackingMachine = 0,
    /// <summary>
    /// 输送线
    /// </summary>
    [Description("输送线")]
    ConveyorLine = 1,
    /// <summary>
    /// RGV小车
    /// </summary>
    [Description("RGV小车")]
    RGV = 2,
    /// <summary>
    /// 叠拆托机
    /// </summary>
    [Description("叠拆托机")]
    PalletMachine = 3,
}
/// <summary>
/// 设备级别枚举
/// </summary>
[Description("设备级别枚举")]
public enum DeviceLevelEnum
{
    /// <summary>
    /// DB区域级别
    /// </summary>
    [Description("DB区域级别")]
    DB = 1,
    /// <summary>
    /// 工位级别
    /// </summary>
    [Description("工位级别")]
    Station = 2,
}
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceDto.cs
New file
@@ -0,0 +1,114 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace WCS.Application;
    /// <summary>
    /// 设备信息输出参数
    /// </summary>
    public class WcsDeviceDto
    {
        /// <summary>
        /// PlcId
        /// </summary>
        public string PlcIdIP { get; set; }
        /// <summary>
        /// 主键Id
        /// </summary>
        public long Id { get; set; }
        /// <summary>
        /// PlcId
        /// </summary>
        public long PlcId { get; set; }
        /// <summary>
        /// 设备级别
        /// </summary>
        public DeviceLevelEnum Level { get; set; }
        /// <summary>
        /// DB区域
        /// </summary>
        public string? DbNumber { get; set; }
        /// <summary>
        /// 工位号
        /// </summary>
        public string? StationNum { get; set; }
        /// <summary>
        /// PLC偏移量
        /// </summary>
        public string? PlcPos { get; set; }
        /// <summary>
        /// WCS偏移量
        /// </summary>
        public string? WcsPos { get; set; }
        /// <summary>
        /// 流程字类型
        /// </summary>
        public string? PosType { get; set; }
        /// <summary>
        /// 显示屏ip地址
        /// </summary>
        public string? LedIP { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string? Text { 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/WcsDevice/Dto/WcsDeviceInput.cs
New file
@@ -0,0 +1,176 @@
// 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 WcsDeviceBaseInput
    {
        /// <summary>
        /// PlcId
        /// </summary>
        public virtual long PlcId { get; set; }
        /// <summary>
        /// 设备级别
        /// </summary>
        public virtual DeviceLevelEnum Level { get; set; }
        /// <summary>
        /// DB区域
        /// </summary>
        public virtual string? DbNumber { get; set; }
        /// <summary>
        /// 工位号
        /// </summary>
        public virtual string? StationNum { get; set; }
        /// <summary>
        /// PLC偏移量
        /// </summary>
        public virtual string? PlcPos { get; set; }
        /// <summary>
        /// WCS偏移量
        /// </summary>
        public virtual string? WcsPos { get; set; }
        /// <summary>
        /// 流程字类型
        /// </summary>
        public virtual string? PosType { get; set; }
        /// <summary>
        /// 显示屏ip地址
        /// </summary>
        public virtual string? LedIP { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public virtual string? Text { 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 PageWcsDeviceInput : BasePageInput
    {
        /// <summary>
        /// 关键字查询
        /// </summary>
        public string? SearchKey { get; set; }
        /// <summary>
        /// PlcId
        /// </summary>
        public long? PlcId { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string? Text { get; set; }
    }
    /// <summary>
    /// 设备信息增加输入参数
    /// </summary>
    public class AddWcsDeviceInput : WcsDeviceBaseInput
    {
        /// <summary>
        /// PlcId
        /// </summary>
        [Required(ErrorMessage = "PlcId不能为空")]
        public override long PlcId { get; set; }
        /// <summary>
        /// 软删除
        /// </summary>
        [Required(ErrorMessage = "软删除不能为空")]
        public override bool IsDelete { get; set; }
    }
    /// <summary>
    /// 设备信息删除输入参数
    /// </summary>
    public class DeleteWcsDeviceInput : BaseIdInput
    {
    }
    /// <summary>
    /// 设备信息更新输入参数
    /// </summary>
    public class UpdateWcsDeviceInput : WcsDeviceBaseInput
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        [Required(ErrorMessage = "主键Id不能为空")]
        public long Id { get; set; }
    }
    /// <summary>
    /// 设备信息主键查询输入参数
    /// </summary>
    public class QueryByIdWcsDeviceInput : DeleteWcsDeviceInput
    {
    }
Admin.NET/WCS.Application/Service/WcsDevice/Dto/WcsDeviceOutput.cs
New file
@@ -0,0 +1,116 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace WCS.Application;
/// <summary>
/// 设备信息输出参数
/// </summary>
public class WcsDeviceOutput
{
    /// <summary>
    /// 主键Id
    /// </summary>
    public long Id { get; set; }
    /// <summary>
    /// PlcId
    /// </summary>
    public long PlcId { get; set; }
    /// <summary>
    /// PlcId 描述
    /// </summary>
    public string PlcIdIP { get; set; }
    /// <summary>
    /// 设备级别
    /// </summary>
    public DeviceLevelEnum Level { get; set; }
    /// <summary>
    /// DB区域
    /// </summary>
    public string? DbNumber { get; set; }
    /// <summary>
    /// 工位号
    /// </summary>
    public string? StationNum { get; set; }
    /// <summary>
    /// PLC偏移量
    /// </summary>
    public string? PlcPos { get; set; }
    /// <summary>
    /// WCS偏移量
    /// </summary>
    public string? WcsPos { get; set; }
    /// <summary>
    /// 流程字类型
    /// </summary>
    public string? PosType { get; set; }
    /// <summary>
    /// 显示屏ip地址
    /// </summary>
    public string? LedIP { get; set; }
    /// <summary>
    /// 描述
    /// </summary>
    public string? Text { 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/WcsDevice/WcsDeviceService.cs
New file
@@ -0,0 +1,156 @@

namespace WCS.Application;
/// <summary>
/// 设备信息服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class WcsDeviceService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<WcsDevice> _wcsDeviceRep;
    public WcsDeviceService(SqlSugarRepository<WcsDevice> wcsDeviceRep)
    {
        _wcsDeviceRep = wcsDeviceRep;
    }
    /// <summary>
    /// 分页查询设备信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询设备信息")]
    public async Task<SqlSugarPagedList<WcsDeviceOutput>> Page(PageWcsDeviceInput input)
    {
        if (input.Field.IsNullOrEmpty())
        {
            input.Field = "u.Id";
            input.Order = "desc";
        }
        input.SearchKey = input.SearchKey?.Trim();
        var query = _wcsDeviceRep.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
                u.Text.Contains(input.SearchKey)
            )
            .WhereIF(input.PlcId>0, u => u.PlcId == input.PlcId)
            .WhereIF(!string.IsNullOrWhiteSpace(input.Text), u => u.Text.Contains(input.Text.Trim()))
            //处理外键和TreeSelector相关字段的连接
            .LeftJoin<WcsPlc>((u, plcid) => u.PlcId == plcid.Id )
            .Select((u, plcid) => new WcsDeviceOutput
            {
                Id = u.Id,
                PlcId = u.PlcId,
                PlcIdIP = plcid.IP,
                Level = (DeviceLevelEnum)u.Level,
                DbNumber = u.DbNumber,
                StationNum = u.StationNum,
                PlcPos = u.PlcPos,
                WcsPos = u.WcsPos,
                PosType = u.PosType,
                LedIP = u.LedIP,
                Text = u.Text,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserName = u.CreateUserName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserName = u.UpdateUserName,
                CreateOrgId = u.CreateOrgId,
                CreateOrgName = u.CreateOrgName,
                IsDelete = u.IsDelete,
            });
        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(AddWcsDeviceInput input)
    {
        var entity = input.Adapt<WcsDevice>();
        await _wcsDeviceRep.InsertAsync(entity);
        return entity.Id;
    }
    /// <summary>
    /// 删除设备信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除设备信息")]
    public async Task Delete(DeleteWcsDeviceInput input)
    {
        var entity = await _wcsDeviceRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _wcsDeviceRep.FakeDeleteAsync(entity);   //假删除
        //await _wcsDeviceRep.DeleteAsync(entity);   //真删除
    }
    /// <summary>
    /// 更新设备信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新设备信息")]
    public async Task Update(UpdateWcsDeviceInput input)
    {
        var entity = input.Adapt<WcsDevice>();
        await _wcsDeviceRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }
    /// <summary>
    /// 获取设备信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取设备信息")]
    public async Task<WcsDevice> Detail([FromQuery] QueryByIdWcsDeviceInput input)
    {
        return await _wcsDeviceRep.GetFirstAsync(u => u.Id == input.Id);
    }
    /// <summary>
    /// 获取设备信息列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取设备信息列表")]
    public async Task<List<WcsDeviceOutput>> List([FromQuery] PageWcsDeviceInput input)
    {
        return await _wcsDeviceRep.AsQueryable().Select<WcsDeviceOutput>().ToListAsync();
    }
    /// <summary>
    /// 获取PlcId列表
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "WcsPlcPlcIdDropdown"), HttpGet]
    [DisplayName("获取PlcId列表")]
    public async Task<dynamic> WcsPlcPlcIdDropdown()
    {
        return await _wcsDeviceRep.Context.Queryable<WcsPlc>()
                .Select(u => new
                {
                    Label = u.IP,
                    Value = u.Id
                }
                ).ToListAsync();
    }
}
Admin.NET/WCS.Application/Service/WcsPlc/Dto/WcsPlcDto.cs
New file
@@ -0,0 +1,39 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace WCS.Application;
    /// <summary>
    /// PLC输出参数
    /// </summary>
    public class WcsPlcDto
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        public long Id { get; set; }
        /// <summary>
        /// PLCIP地址
        /// </summary>
        public string IP { get; set; }
        /// <summary>
        /// 设备类型
        /// </summary>
        public PLCTypeEnum Type { get; set; }
        /// <summary>
        /// 仓库号
        /// </summary>
        public string? WareHouseNo { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string? Text { get; set; }
    }
Admin.NET/WCS.Application/Service/WcsPlc/Dto/WcsPlcInput.cs
New file
@@ -0,0 +1,106 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core;
using System.ComponentModel.DataAnnotations;
namespace WCS.Application;
    /// <summary>
    /// PLC基础输入参数
    /// </summary>
    public class WcsPlcBaseInput
    {
        /// <summary>
        /// PLCIP地址
        /// </summary>
        public virtual string IP { get; set; }
        /// <summary>
        /// 设备类型
        /// </summary>
        public virtual PLCTypeEnum Type { get; set; }
        /// <summary>
        /// 仓库号
        /// </summary>
        public virtual string? WareHouseNo { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public virtual string? Text { get; set; }
    }
    /// <summary>
    /// PLC分页查询输入参数
    /// </summary>
    public class PageWcsPlcInput : BasePageInput
    {
        /// <summary>
        /// 关键字查询
        /// </summary>
        public string? SearchKey { get; set; }
        /// <summary>
        /// PLCIP地址
        /// </summary>
        public string? IP { get; set; }
        /// <summary>
        /// 设备类型
        /// </summary>
        public PLCTypeEnum? Type { get; set; }
    }
    /// <summary>
    /// PLC增加输入参数
    /// </summary>
    public class AddWcsPlcInput : WcsPlcBaseInput
    {
        /// <summary>
        /// PLCIP地址
        /// </summary>
        [Required(ErrorMessage = "PLCIP地址不能为空")]
        public override string IP { get; set; }
        /// <summary>
        /// 设备类型
        /// </summary>
        [Required(ErrorMessage = "设备类型不能为空")]
        public override PLCTypeEnum Type { get; set; }
    }
    /// <summary>
    /// PLC删除输入参数
    /// </summary>
    public class DeleteWcsPlcInput : BaseIdInput
    {
    }
    /// <summary>
    /// PLC更新输入参数
    /// </summary>
    public class UpdateWcsPlcInput : WcsPlcBaseInput
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        [Required(ErrorMessage = "主键Id不能为空")]
        public long Id { get; set; }
    }
    /// <summary>
    /// PLC主键查询输入参数
    /// </summary>
    public class QueryByIdWcsPlcInput : DeleteWcsPlcInput
    {
    }
Admin.NET/WCS.Application/Service/WcsPlc/Dto/WcsPlcOutput.cs
New file
@@ -0,0 +1,41 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace WCS.Application;
/// <summary>
/// PLC输出参数
/// </summary>
public class WcsPlcOutput
{
    /// <summary>
    /// 主键Id
    /// </summary>
    public long Id { get; set; }
    /// <summary>
    /// PLCIP地址
    /// </summary>
    public string IP { get; set; }
    /// <summary>
    /// 设备类型
    /// </summary>
    public PLCTypeEnum Type { get; set; }
    /// <summary>
    /// 仓库号
    /// </summary>
    public string? WareHouseNo { get; set; }
    /// <summary>
    /// 描述
    /// </summary>
    public string? Text { get; set; }
    }
Admin.NET/WCS.Application/Service/WcsPlc/WcsPlcService.cs
New file
@@ -0,0 +1,118 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.Service;
using Microsoft.AspNetCore.Http;
namespace WCS.Application;
/// <summary>
/// PLC服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class WcsPlcService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<WcsPlc> _wcsPlcRep;
    public WcsPlcService(SqlSugarRepository<WcsPlc> wcsPlcRep)
    {
        _wcsPlcRep = wcsPlcRep;
    }
    /// <summary>
    /// 分页查询PLC
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询PLC")]
    public async Task<SqlSugarPagedList<WcsPlcOutput>> Page(PageWcsPlcInput input)
    {
        input.SearchKey = input.SearchKey?.Trim();
        var query = _wcsPlcRep.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
                u.IP.Contains(input.SearchKey)
            )
            .WhereIF(!string.IsNullOrWhiteSpace(input.IP), u => u.IP.Contains(input.IP.Trim()))
            .WhereIF(input.Type.HasValue, u => u.Type == input.Type)
            .Select<WcsPlcOutput>();
        return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
    }
    /// <summary>
    /// 增加PLC
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    [DisplayName("增加PLC")]
    public async Task<long> Add(AddWcsPlcInput input)
    {
        var entity = input.Adapt<WcsPlc>();
        await _wcsPlcRep.InsertAsync(entity);
        return entity.Id;
    }
    /// <summary>
    /// 删除PLC
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除PLC")]
    public async Task Delete(DeleteWcsPlcInput input)
    {
        var entity = await _wcsPlcRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _wcsPlcRep.FakeDeleteAsync(entity);   //假删除
        //await _wcsPlcRep.DeleteAsync(entity);   //真删除
    }
    /// <summary>
    /// 更新PLC
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新PLC")]
    public async Task Update(UpdateWcsPlcInput input)
    {
        var entity = input.Adapt<WcsPlc>();
        await _wcsPlcRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }
    /// <summary>
    /// 获取PLC
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取PLC")]
    public async Task<WcsPlc> Detail([FromQuery] QueryByIdWcsPlcInput input)
    {
        return await _wcsPlcRep.GetFirstAsync(u => u.Id == input.Id);
    }
    /// <summary>
    /// 获取PLC列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取PLC列表")]
    public async Task<List<WcsPlcOutput>> List([FromQuery] PageWcsPlcInput input)
    {
        return await _wcsPlcRep.AsQueryable().Select<WcsPlcOutput>().ToListAsync();
    }
}
Admin.NET/WCS.Application/Service/WcsStation/Dto/WcsStationDto.cs
New file
@@ -0,0 +1,49 @@

namespace WCS.Application;
    /// <summary>
    /// 设备工位输出参数
    /// </summary>
    public class WcsStationDto
    {
        /// <summary>
        /// 设备ID
        /// </summary>
        public string? DeviceIdText { get; set; }
        /// <summary>
        /// 主键Id
        /// </summary>
        public long Id { get; set; }
        /// <summary>
        /// 设备ID
        /// </summary>
        public long DeviceId { get; set; }
        /// <summary>
        /// 工位号
        /// </summary>
        public string? StationNum { get; set; }
        /// <summary>
        /// 偏移量
        /// </summary>
        public string? PlcPos { get; set; }
        /// <summary>
        /// 流程字类型
        /// </summary>
        public string? PosType { get; set; }
        /// <summary>
        /// 显示屏ip地址
        /// </summary>
        public string? LedIP { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string? Text { get; set; }
    }
Admin.NET/WCS.Application/Service/WcsStation/Dto/WcsStationInput.cs
New file
@@ -0,0 +1,104 @@
// 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 WcsStationBaseInput
    {
        /// <summary>
        /// 设备ID
        /// </summary>
        public virtual long DeviceId { get; set; }
        /// <summary>
        /// 工位号
        /// </summary>
        public virtual string? StationNum { get; set; }
        /// <summary>
        /// 偏移量
        /// </summary>
        public virtual string? PlcPos { get; set; }
        /// <summary>
        /// 流程字类型
        /// </summary>
        public virtual string? PosType { get; set; }
        /// <summary>
        /// 显示屏ip地址
        /// </summary>
        public virtual string? LedIP { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public virtual string? Text { get; set; }
    }
    /// <summary>
    /// 设备工位分页查询输入参数
    /// </summary>
    public class PageWcsStationInput : BasePageInput
    {
        /// <summary>
        /// 关键字查询
        /// </summary>
        public string? SearchKey { get; set; }
        /// <summary>
        /// 设备ID
        /// </summary>
        public long DeviceId { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string? Text { get; set; }
    }
    /// <summary>
    /// 设备工位增加输入参数
    /// </summary>
    public class AddWcsStationInput : WcsStationBaseInput
    {
    }
    /// <summary>
    /// 设备工位删除输入参数
    /// </summary>
    public class DeleteWcsStationInput : BaseIdInput
    {
    }
    /// <summary>
    /// 设备工位更新输入参数
    /// </summary>
    public class UpdateWcsStationInput : WcsStationBaseInput
    {
        /// <summary>
        /// 主键Id
        /// </summary>
        [Required(ErrorMessage = "主键Id不能为空")]
        public long Id { get; set; }
    }
    /// <summary>
    /// 设备工位主键查询输入参数
    /// </summary>
    public class QueryByIdWcsStationInput : DeleteWcsStationInput
    {
    }
Admin.NET/WCS.Application/Service/WcsStation/Dto/WcsStationOutput.cs
New file
@@ -0,0 +1,56 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace WCS.Application;
/// <summary>
/// 设备工位输出参数
/// </summary>
public class WcsStationOutput
{
    /// <summary>
    /// 主键Id
    /// </summary>
    public long Id { get; set; }
    /// <summary>
    /// 设备ID
    /// </summary>
    public long DeviceId { get; set; }
    /// <summary>
    /// 设备ID 描述
    /// </summary>
    public string? DeviceIdText { get; set; }
    /// <summary>
    /// 工位号
    /// </summary>
    public string? StationNum { get; set; }
    /// <summary>
    /// 偏移量
    /// </summary>
    public string? PlcPos { get; set; }
    /// <summary>
    /// 流程字类型
    /// </summary>
    public string? PosType { get; set; }
    /// <summary>
    /// 显示屏ip地址
    /// </summary>
    public string? LedIP { get; set; }
    /// <summary>
    /// 描述
    /// </summary>
    public string? Text { get; set; }
    }
Admin.NET/WCS.Application/Service/WcsStation/WcsStationService.cs
New file
@@ -0,0 +1,144 @@

namespace WCS.Application;
/// <summary>
/// 设备工位服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class WcsStationService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<WcsStation> _wcsStationRep;
    public WcsStationService(SqlSugarRepository<WcsStation> wcsStationRep)
    {
        _wcsStationRep = wcsStationRep;
    }
    /// <summary>
    /// 分页查询设备工位
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询设备工位")]
    public async Task<SqlSugarPagedList<WcsStationOutput>> Page(PageWcsStationInput input)
    {
        if (input.Field.IsNullOrEmpty())
        {
            input.Field = "u.Id";
            input.Order = "desc";
        }
        input.SearchKey = input.SearchKey?.Trim();
        var query = _wcsStationRep.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
                u.Text.Contains(input.SearchKey)
            )
            .WhereIF(input.DeviceId>0, u => u.DeviceId == input.DeviceId)
            .WhereIF(!string.IsNullOrWhiteSpace(input.Text), u => u.Text.Contains(input.Text.Trim()))
            //处理外键和TreeSelector相关字段的连接
            .LeftJoin<WcsDevice>((u, deviceid) => u.DeviceId == deviceid.Id )
            .Select((u, deviceid) => new WcsStationOutput
            {
                Id = u.Id,
                DeviceId = u.DeviceId,
                DeviceIdText = deviceid.Text,
                StationNum = u.StationNum,
                PlcPos = u.PlcPos,
                PosType = u.PosType,
                LedIP = u.LedIP,
                Text = u.Text,
            });
        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(AddWcsStationInput input)
    {
        var entity = input.Adapt<WcsStation>();
        await _wcsStationRep.InsertAsync(entity);
        return entity.Id;
    }
    /// <summary>
    /// 删除设备工位
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除设备工位")]
    public async Task Delete(DeleteWcsStationInput input)
    {
        var entity = await _wcsStationRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _wcsStationRep.FakeDeleteAsync(entity);   //假删除
        //await _wcsStationRep.DeleteAsync(entity);   //真删除
    }
    /// <summary>
    /// 更新设备工位
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新设备工位")]
    public async Task Update(UpdateWcsStationInput input)
    {
        var entity = input.Adapt<WcsStation>();
        await _wcsStationRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }
    /// <summary>
    /// 获取设备工位
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取设备工位")]
    public async Task<WcsStation> Detail([FromQuery] QueryByIdWcsStationInput input)
    {
        return await _wcsStationRep.GetFirstAsync(u => u.Id == input.Id);
    }
    /// <summary>
    /// 获取设备工位列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取设备工位列表")]
    public async Task<List<WcsStationOutput>> List([FromQuery] PageWcsStationInput input)
    {
        return await _wcsStationRep.AsQueryable().Select<WcsStationOutput>().ToListAsync();
    }
    /// <summary>
    /// 获取设备ID列表
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "WcsDeviceDeviceIdDropdown"), HttpGet]
    [DisplayName("获取设备ID列表")]
    public async Task<dynamic> WcsDeviceDeviceIdDropdown()
    {
        return await _wcsStationRep.Context.Queryable<WcsDevice>()
                .Select(u => new
                {
                    Label = u.Text,
                    Value = u.Id
                }
                ).ToListAsync();
    }
}
Web/src/api/wcs/wcsDevice.ts
New file
@@ -0,0 +1,56 @@
import request from '/@/utils/request';
enum Api {
  AddWcsDevice = '/api/wcsDevice/add',
  DeleteWcsDevice = '/api/wcsDevice/delete',
  UpdateWcsDevice = '/api/wcsDevice/update',
  PageWcsDevice = '/api/wcsDevice/page',
  DetailWcsDevice = '/api/wcsDevice/detail',
  GetWcsPlcPlcIdDropdown = '/api/wcsDevice/WcsPlcPlcIdDropdown',
}
// 增加设备信息
export const addWcsDevice = (params?: any) =>
    request({
        url: Api.AddWcsDevice,
        method: 'post',
        data: params,
    });
// 删除设备信息
export const deleteWcsDevice = (params?: any) =>
    request({
            url: Api.DeleteWcsDevice,
            method: 'post',
            data: params,
        });
// 编辑设备信息
export const updateWcsDevice = (params?: any) =>
    request({
            url: Api.UpdateWcsDevice,
            method: 'post',
            data: params,
        });
// 分页查询设备信息
export const pageWcsDevice = (params?: any) =>
    request({
            url: Api.PageWcsDevice,
            method: 'post',
            data: params,
        });
// 详情设备信息
export const detailWcsDevice = (id: any) =>
    request({
            url: Api.DetailWcsDevice,
            method: 'get',
            data: { id },
        });
export const getWcsPlcPlcIdDropdown = () =>
        request({
        url: Api.GetWcsPlcPlcIdDropdown,
        method: 'get'
        });
Web/src/api/wcs/wcsPlc.ts
New file
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
enum Api {
  AddWcsPlc = '/api/wcsPlc/add',
  DeleteWcsPlc = '/api/wcsPlc/delete',
  UpdateWcsPlc = '/api/wcsPlc/update',
  PageWcsPlc = '/api/wcsPlc/page',
  DetailWcsPlc = '/api/wcsPlc/detail',
}
// 增加PLC
export const addWcsPlc = (params?: any) =>
    request({
        url: Api.AddWcsPlc,
        method: 'post',
        data: params,
    });
// 删除PLC
export const deleteWcsPlc = (params?: any) =>
    request({
            url: Api.DeleteWcsPlc,
            method: 'post',
            data: params,
        });
// 编辑PLC
export const updateWcsPlc = (params?: any) =>
    request({
            url: Api.UpdateWcsPlc,
            method: 'post',
            data: params,
        });
// 分页查询PLC
export const pageWcsPlc = (params?: any) =>
    request({
            url: Api.PageWcsPlc,
            method: 'post',
            data: params,
        });
// 详情PLC
export const detailWcsPlc = (id: any) =>
    request({
            url: Api.DetailWcsPlc,
            method: 'get',
            data: { id },
        });
Web/src/api/wcs/wcsStation.ts
New file
@@ -0,0 +1,56 @@
import request from '/@/utils/request';
enum Api {
  AddWcsStation = '/api/wcsStation/add',
  DeleteWcsStation = '/api/wcsStation/delete',
  UpdateWcsStation = '/api/wcsStation/update',
  PageWcsStation = '/api/wcsStation/page',
  DetailWcsStation = '/api/wcsStation/detail',
  GetWcsDeviceDeviceIdDropdown = '/api/wcsStation/WcsDeviceDeviceIdDropdown',
}
// 增加设备工位
export const addWcsStation = (params?: any) =>
    request({
        url: Api.AddWcsStation,
        method: 'post',
        data: params,
    });
// 删除设备工位
export const deleteWcsStation = (params?: any) =>
    request({
            url: Api.DeleteWcsStation,
            method: 'post',
            data: params,
        });
// 编辑设备工位
export const updateWcsStation = (params?: any) =>
    request({
            url: Api.UpdateWcsStation,
            method: 'post',
            data: params,
        });
// 分页查询设备工位
export const pageWcsStation = (params?: any) =>
    request({
            url: Api.PageWcsStation,
            method: 'post',
            data: params,
        });
// 详情设备工位
export const detailWcsStation = (id: any) =>
    request({
            url: Api.DetailWcsStation,
            method: 'get',
            data: { id },
        });
export const getWcsDeviceDeviceIdDropdown = () =>
        request({
        url: Api.GetWcsDeviceDeviceIdDropdown,
        method: 'get'
        });
Web/src/api/wcs/wcsplcStation.ts
New file
@@ -0,0 +1,56 @@
import request from '/@/utils/request';
enum Api {
  AddWcsplcStation = '/api/wcsplcStation/add',
  DeleteWcsplcStation = '/api/wcsplcStation/delete',
  UpdateWcsplcStation = '/api/wcsplcStation/update',
  PageWcsplcStation = '/api/wcsplcStation/page',
  DetailWcsplcStation = '/api/wcsplcStation/detail',
  GetWcsDeviceDeviceIdDropdown = '/api/wcsplcStation/WcsDeviceDeviceIdDropdown',
}
// 增加设备工位
export const addWcsplcStation = (params?: any) =>
    request({
        url: Api.AddWcsplcStation,
        method: 'post',
        data: params,
    });
// 删除设备工位
export const deleteWcsplcStation = (params?: any) =>
    request({
            url: Api.DeleteWcsplcStation,
            method: 'post',
            data: params,
        });
// 编辑设备工位
export const updateWcsplcStation = (params?: any) =>
    request({
            url: Api.UpdateWcsplcStation,
            method: 'post',
            data: params,
        });
// 分页查询设备工位
export const pageWcsplcStation = (params?: any) =>
    request({
            url: Api.PageWcsplcStation,
            method: 'post',
            data: params,
        });
// 详情设备工位
export const detailWcsplcStation = (id: any) =>
    request({
            url: Api.DetailWcsplcStation,
            method: 'get',
            data: { id },
        });
export const getWcsDeviceDeviceIdDropdown = () =>
        request({
        url: Api.GetWcsDeviceDeviceIdDropdown,
        method: 'get'
        });
Web/src/views/wcs/wcsDevice/component/editDialog.vue
New file
@@ -0,0 +1,195 @@
<template>
    <div class="wcsDevice-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="PlcId" prop="plcId">
                            <el-select clearable filterable v-model="ruleForm.plcId" placeholder="请选择PlcId">
                                <el-option v-for="(item,index) in wcsPlcPlcIdDropdownList" :key="index" :value="item.value" :label="item.label" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="设备级别" prop="level">
                            <el-select clearable v-model="ruleForm.level" placeholder="请选择设备级别">
                                <el-option v-for="(item,index) in dl('DeviceLevelEnum')" :key="index" :value="Number(item.value)" :label="`${item.name} (${item.code}) [${item.value}]`"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="DB区域" prop="dbNumber">
                            <el-input v-model="ruleForm.dbNumber" placeholder="请输入DB区域" 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="工位号" prop="stationNum">
                            <el-input v-model="ruleForm.stationNum" placeholder="请输入工位号" maxlength="4" 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="PLC偏移量" prop="plcPos">
                            <el-input v-model="ruleForm.plcPos" placeholder="请输入PLC偏移量" 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="WCS偏移量" prop="wcsPos">
                            <el-input v-model="ruleForm.wcsPos" placeholder="请输入WCS偏移量" 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="流程字类型" prop="posType">
                            <el-input v-model="ruleForm.posType" 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="显示屏ip地址" prop="ledIP">
                            <el-input v-model="ruleForm.ledIP" placeholder="请输入显示屏ip地址" maxlength="50" 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="text">
                            <el-input v-model="ruleForm.text" placeholder="请输入描述" 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 { getDictDataItem as di, getDictDataList as dl } from '/@/utils/dict-utils';
    import { getDictLabelByVal as dv } from '/@/utils/dict-utils';
      import { formatDate } from '/@/utils/formatTime';
    import { addWcsDevice, updateWcsDevice, detailWcsDevice } from "/@/api/wcs/wcsDevice";
    import { getWcsPlcPlcIdDropdown } from '/@/api/wcs/wcsDevice';
    import { getAPI } from '/@/utils/axios-utils';
    import { SysEnumApi } from '/@/api-services/api';
    //父级传递来的参数
    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 detailWcsDevice(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 addWcsDevice(values);
                } else {
                    await updateWcsDevice(values);
                }
                closeDialog();
            } else {
                ElMessage({
                    message: `表单有${Object.keys(fields).length}处验证失败,请修改后再提交`,
                    type: "error",
                });
            }
        });
    };
    const wcsPlcPlcIdDropdownList = ref<any>([]);
    const getWcsPlcPlcIdDropdownList = async () => {
        let list = await getWcsPlcPlcIdDropdown();
        wcsPlcPlcIdDropdownList.value = list.data.result ?? [];
    };
    getWcsPlcPlcIdDropdownList();
    //将属性或者函数暴露给父组件
    defineExpose({ openDialog });
</script>
Web/src/views/wcs/wcsDevice/index.vue
New file
@@ -0,0 +1,220 @@
<template>
  <div class="wcsDevice-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="PlcId">
              <el-select clearable="" filterable="" v-model="queryParams.plcId" placeholder="请选择PlcId">
                <el-option v-for="(item,index) in wcsPlcPlcIdDropdownList" :key="index" :value="item.value" :label="item.label" />
              </el-select>
            </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.text" 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="'wcsDevice: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="openAddWcsDevice" v-auth="'wcsDevice: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="plcId" label="PlcId"  show-overflow-tooltip="">
          <template #default="scope">
            <span>{{scope.row.plcIdIP}}</span>
          </template>
        </el-table-column>
          <el-table-column prop="level" label="设备级别"  show-overflow-tooltip="" >
            <template #default="scope">
              <el-tag :type="dv('DeviceLevelEnum', scope.row.level)?.tagType"> {{dv('DeviceLevelEnum', scope.row.level)?.name}}</el-tag>
            </template>
          </el-table-column>
        <el-table-column prop="dbNumber" label="DB区域"  show-overflow-tooltip="" />
        <el-table-column prop="stationNum" label="工位号"  show-overflow-tooltip="" />
        <el-table-column prop="plcPos" label="PLC偏移量"  show-overflow-tooltip="" />
        <el-table-column prop="wcsPos" label="WCS偏移量"  show-overflow-tooltip="" />
        <el-table-column prop="posType" label="流程字类型"  show-overflow-tooltip="" />
        <el-table-column prop="ledIP" label="显示屏ip地址"  show-overflow-tooltip="" />
        <el-table-column prop="text" label="描述"  show-overflow-tooltip="" />
        <el-table-column label="修改记录" width="80" align="center" show-overflow-tooltip>
          <template #default="scope">
            <ModifyRecord :data="scope.row" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('wcsDevice:update') || auth('wcsDevice:delete')">
          <template #default="scope">
            <el-button icon="ele-Edit" size="small" text="" type="primary" @click="openEditWcsDevice(scope.row)" v-auth="'wcsDevice:update'"> 编辑 </el-button>
            <el-button icon="ele-Delete" size="small" text="" type="primary" @click="delWcsDevice(scope.row)" v-auth="'wcsDevice: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="printWcsDeviceTitle"
        @reloadTable="handleQuery" />
      <editDialog
        ref="editDialogRef"
        :title="editWcsDeviceTitle"
        @reloadTable="handleQuery"
      />
    </el-card>
  </div>
</template>
<script lang="ts" setup="" name="wcsDevice">
  import { 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 ModifyRecord from '/@/components/table/modifyRecord.vue';
  import printDialog from '/@/views/system/print/component/hiprint/preview.vue'
  import editDialog from '/@/views/wcs/wcsDevice/component/editDialog.vue'
  import { pageWcsDevice, deleteWcsDevice } from '/@/api/wcs/wcsDevice';
  import { getWcsPlcPlcIdDropdown } from '/@/api/wcs/wcsDevice';
  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 printWcsDeviceTitle = ref("");
  const editWcsDeviceTitle = ref("");
  // 改变高级查询的控件显示状态
  const changeAdvanceQueryUI = () => {
    showAdvanceQueryUI.value = !showAdvanceQueryUI.value;
  }
  // 查询操作
  const handleQuery = async () => {
    loading.value = true;
    var res = await pageWcsDevice(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 openAddWcsDevice = () => {
    editWcsDeviceTitle.value = '添加设备信息';
    editDialogRef.value.openDialog({});
  };
  // 打开打印页面
  const openPrintWcsDevice = async (row: any) => {
    printWcsDeviceTitle.value = '打印设备信息';
  }
  // 打开编辑页面
  const openEditWcsDevice = (row: any) => {
    editWcsDeviceTitle.value = '编辑设备信息';
    editDialogRef.value.openDialog(row);
  };
  // 删除
  const delWcsDevice = (row: any) => {
    ElMessageBox.confirm(`确定要删除吗?`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
  .then(async () => {
    await deleteWcsDevice(row);
    handleQuery();
    ElMessage.success("删除成功");
  })
  .catch(() => {});
  };
  // 改变页面容量
  const handleSizeChange = (val: number) => {
    tableParams.value.pageSize = val;
    handleQuery();
  };
  // 改变页码序号
  const handleCurrentChange = (val: number) => {
    tableParams.value.page = val;
    handleQuery();
  };
  const wcsPlcPlcIdDropdownList = ref<any>([]);
  const getWcsPlcPlcIdDropdownList = async () => {
    let list = await getWcsPlcPlcIdDropdown();
    wcsPlcPlcIdDropdownList.value = list.data.result ?? [];
  };
  getWcsPlcPlcIdDropdownList();
  handleQuery();
</script>
<style scoped>
:deep(.el-input),
:deep(.el-select),
:deep(.el-input-number) {
    width: 100%;
}
</style>
Web/src/views/wcs/wcsPlc/component/editDialog.vue
New file
@@ -0,0 +1,149 @@
<template>
    <div class="wcsPlc-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="PLCIP地址" prop="ip">
                            <el-input v-model="ruleForm.ip" placeholder="请输入PLCIP地址" 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="type">
                            <el-select clearable v-model="ruleForm.type" placeholder="请选择设备类型">
                                <el-option v-for="(item,index) in dl('PLCTypeEnum')" :key="index" :value="Number(item.value)" :label="`${item.name} (${item.code}) [${item.value}]`"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="仓库号" prop="wareHouseNo">
                            <el-input v-model="ruleForm.wareHouseNo" 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="text">
                            <el-input v-model="ruleForm.text" placeholder="请输入描述" maxlength="100" 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 { getDictDataItem as di, getDictDataList as dl } from '/@/utils/dict-utils';
    import { getDictLabelByVal as dv } from '/@/utils/dict-utils';
    import { addWcsPlc, updateWcsPlc, detailWcsPlc } from "/@/api/wcs/wcsPlc";
    import { getAPI } from '/@/utils/axios-utils';
    import { SysEnumApi } from '/@/api-services/api';
    //父级传递来的参数
    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>({
        iP: [{required: true, message: '请输入PLCIP地址!', trigger: 'blur',},],
    });
    // 页面加载时
    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 detailWcsPlc(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 addWcsPlc(values);
                } else {
                    await updateWcsPlc(values);
                }
                closeDialog();
            } else {
                ElMessage({
                    message: `表单有${Object.keys(fields).length}处验证失败,请修改后再提交`,
                    type: "error",
                });
            }
        });
    };
    //将属性或者函数暴露给父组件
    defineExpose({ openDialog });
</script>
Web/src/views/wcs/wcsPlc/index.vue
New file
@@ -0,0 +1,203 @@
<template>
  <div class="wcsPlc-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="PLCIP地址">
              <el-input v-model="queryParams.ip" clearable="" placeholder="请输入PLCIP地址"/>
            </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-select clearable="" v-model="queryParams.type" placeholder="请选择设备类型">
                <el-option v-for="(item,index) in dl('PLCTypeEnum')" :key="index" :value="item.value" :label="`${item.name} (${item.code}) [${item.value}] `" />
              </el-select>
            </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="'wcsPlc: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="openAddWcsPlc" v-auth="'wcsPlc: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="ip" label="PLCIP地址"  show-overflow-tooltip="" />
          <el-table-column prop="type" label="设备类型"  show-overflow-tooltip="" >
            <template #default="scope">
              <el-tag :type="dv('PLCTypeEnum', scope.row.type)?.tagType"> {{dv('PLCTypeEnum', scope.row.type)?.name}}</el-tag>
            </template>
          </el-table-column>
        <el-table-column prop="wareHouseNo" label="仓库号"  show-overflow-tooltip="" />
        <el-table-column prop="text" label="描述"  show-overflow-tooltip="" />
        <el-table-column label="修改记录" width="80" align="center" show-overflow-tooltip>
          <template #default="scope">
            <ModifyRecord :data="scope.row" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('wcsPlc:update') || auth('wcsPlc:delete')">
          <template #default="scope">
            <el-button icon="ele-Edit" size="small" text="" type="primary" @click="openEditWcsPlc(scope.row)" v-auth="'wcsPlc:update'"> 编辑 </el-button>
            <el-button icon="ele-Delete" size="small" text="" type="primary" @click="delWcsPlc(scope.row)" v-auth="'wcsPlc: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="printWcsPlcTitle"
        @reloadTable="handleQuery" />
      <editDialog
        ref="editDialogRef"
        :title="editWcsPlcTitle"
        @reloadTable="handleQuery"
      />
    </el-card>
  </div>
</template>
<script lang="ts" setup="" name="wcsPlc">
  import { 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 ModifyRecord from '/@/components/table/modifyRecord.vue';
  import printDialog from '/@/views/system/print/component/hiprint/preview.vue'
  import editDialog from '/@/views/wcs/wcsPlc/component/editDialog.vue'
  import { pageWcsPlc, deleteWcsPlc } from '/@/api/wcs/wcsPlc';
    import { getAPI } from '/@/utils/axios-utils';
    import { SysEnumApi } from '/@/api-services/api';
  import commonFunction from '/@/utils/commonFunction';
  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 printWcsPlcTitle = ref("");
  const editWcsPlcTitle = ref("");
  // 改变高级查询的控件显示状态
  const changeAdvanceQueryUI = () => {
    showAdvanceQueryUI.value = !showAdvanceQueryUI.value;
  }
  // 查询操作
  const handleQuery = async () => {
    loading.value = true;
    var res = await pageWcsPlc(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 openAddWcsPlc = () => {
    editWcsPlcTitle.value = '添加PLC';
    editDialogRef.value.openDialog({});
  };
  // 打开打印页面
  const openPrintWcsPlc = async (row: any) => {
    printWcsPlcTitle.value = '打印PLC';
  }
  // 打开编辑页面
  const openEditWcsPlc = (row: any) => {
    editWcsPlcTitle.value = '编辑PLC';
    editDialogRef.value.openDialog(row);
  };
  // 删除
  const delWcsPlc = (row: any) => {
    ElMessageBox.confirm(`确定要删除吗?`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
  .then(async () => {
    await deleteWcsPlc(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>
Web/src/views/wcs/wcsStation/component/editDialog.vue
New file
@@ -0,0 +1,166 @@
<template>
    <div class="wcsStation-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="设备ID" prop="deviceId">
                            <el-select clearable filterable v-model="ruleForm.deviceId" placeholder="请选择设备ID">
                                <el-option v-for="(item,index) in wcsDeviceDeviceIdDropdownList" :key="index" :value="item.value" :label="item.label" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
                        <el-form-item label="工位号" prop="stationNum">
                            <el-input v-model="ruleForm.stationNum" placeholder="请输入工位号" maxlength="4" 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="plcPos">
                            <el-input v-model="ruleForm.plcPos" placeholder="请输入偏移量" maxlength="32" 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="posType">
                            <el-input v-model="ruleForm.posType" 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="显示屏ip地址" prop="ledIP">
                            <el-input v-model="ruleForm.ledIP" placeholder="请输入显示屏ip地址" maxlength="50" 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="text">
                            <el-input v-model="ruleForm.text" placeholder="请输入描述" 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 { addWcsStation, updateWcsStation, detailWcsStation } from "/@/api/wcs/wcsStation";
    import { getWcsDeviceDeviceIdDropdown } from '/@/api/wcs/wcsStation';
    //父级传递来的参数
    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 detailWcsStation(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 addWcsStation(values);
                } else {
                    await updateWcsStation(values);
                }
                closeDialog();
            } else {
                ElMessage({
                    message: `表单有${Object.keys(fields).length}处验证失败,请修改后再提交`,
                    type: "error",
                });
            }
        });
    };
    const wcsDeviceDeviceIdDropdownList = ref<any>([]);
    const getWcsDeviceDeviceIdDropdownList = async () => {
        let list = await getWcsDeviceDeviceIdDropdown();
        wcsDeviceDeviceIdDropdownList.value = list.data.result ?? [];
    };
    getWcsDeviceDeviceIdDropdownList();
    //将属性或者函数暴露给父组件
    defineExpose({ openDialog });
</script>
Web/src/views/wcs/wcsStation/index.vue
New file
@@ -0,0 +1,196 @@
<template>
  <div class="wcsStation-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="设备ID">
              <el-select clearable="" filterable="" v-model="queryParams.deviceId" placeholder="请选择设备ID">
                <el-option v-for="(item, index) in wcsDeviceDeviceIdDropdownList" :key="index" :value="item.value"
                  :label="item.label" />
              </el-select>
            </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.text" 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="'wcsStation: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="openAddWcsStation"
                  v-auth="'wcsStation: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="deviceId" label="设备ID" show-overflow-tooltip="">
          <template #default="scope">
            <span>{{ scope.row.deviceIdText }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="stationNum" label="工位号" show-overflow-tooltip="" />
        <el-table-column prop="plcPos" label="偏移量" show-overflow-tooltip="" />
        <el-table-column prop="posType" label="流程字类型" show-overflow-tooltip="" />
        <el-table-column prop="ledIP" label="显示屏ip地址" show-overflow-tooltip="" />
        <el-table-column prop="text" label="描述" show-overflow-tooltip="" />
        <el-table-column label="修改记录" width="80" align="center" show-overflow-tooltip>
          <template #default="scope">
            <ModifyRecord :data="scope.row" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip=""
          v-if="auth('wcsStation:update') || auth('wcsStation:delete')">
          <template #default="scope">
            <el-button icon="ele-Edit" size="small" text="" type="primary" @click="openEditWcsStation(scope.row)"
              v-auth="'wcsStation:update'"> 编辑 </el-button>
            <el-button icon="ele-Delete" size="small" text="" type="primary" @click="delWcsStation(scope.row)"
              v-auth="'wcsStation: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="printWcsStationTitle" @reloadTable="handleQuery" />
      <editDialog ref="editDialogRef" :title="editWcsStationTitle" @reloadTable="handleQuery" />
    </el-card>
  </div>
</template>
<script lang="ts" setup="" name="wcsStation">
import { ref } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { auth } from '/@/utils/authFunction';
import ModifyRecord from '/@/components/table/modifyRecord.vue';
import printDialog from '/@/views/system/print/component/hiprint/preview.vue'
import editDialog from '/@/views/wcs/wcsStation/component/editDialog.vue'
import { pageWcsStation, deleteWcsStation } from '/@/api/wcs/wcsStation';
import { getWcsDeviceDeviceIdDropdown } from '/@/api/wcs/wcsStation';
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 printWcsStationTitle = ref("");
const editWcsStationTitle = ref("");
// 改变高级查询的控件显示状态
const changeAdvanceQueryUI = () => {
  showAdvanceQueryUI.value = !showAdvanceQueryUI.value;
}
// 查询操作
const handleQuery = async () => {
  loading.value = true;
  var res = await pageWcsStation(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 openAddWcsStation = () => {
  editWcsStationTitle.value = '添加设备工位';
  editDialogRef.value.openDialog({});
};
// 打开打印页面
const openPrintWcsStation = async (row: any) => {
  printWcsStationTitle.value = '打印设备工位';
}
// 打开编辑页面
const openEditWcsStation = (row: any) => {
  editWcsStationTitle.value = '编辑设备工位';
  editDialogRef.value.openDialog(row);
};
// 删除
const delWcsStation = (row: any) => {
  ElMessageBox.confirm(`确定要删除吗?`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      await deleteWcsStation(row);
      handleQuery();
      ElMessage.success("删除成功");
    })
    .catch(() => { });
};
// 改变页面容量
const handleSizeChange = (val: number) => {
  tableParams.value.pageSize = val;
  handleQuery();
};
// 改变页码序号
const handleCurrentChange = (val: number) => {
  tableParams.value.page = val;
  handleQuery();
};
const wcsDeviceDeviceIdDropdownList = ref<any>([]);
const getWcsDeviceDeviceIdDropdownList = async () => {
  let list = await getWcsDeviceDeviceIdDropdown();
  wcsDeviceDeviceIdDropdownList.value = list.data.result ?? [];
};
getWcsDeviceDeviceIdDropdownList();
handleQuery();
</script>
<style scoped>
:deep(.el-input),
:deep(.el-select),
:deep(.el-input-number) {
  width: 100%;
}
</style>