diff --git a/.gitignore b/.gitignore index 8d6942c..e342c36 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,10 @@ /vol-net6/VOL.System/obj /vol-net6/VOL.System/bin /vol-net6/VOL.WebApi/obj +/vol-net6/VOL.WebApi/obj/* /vol-net6/VOL.WebApi/bin /vol-net6/VOL.WebApi/Properties/PublishProfiles /vol-net6/VOL.WebApi/Properties +/vol-net6/VOL.WebApi/quartz/* +/vol-net6/VOL.Data/obj +/vol-net6/VOL.Data/bin diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..03a966c Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/vol-net6/VOL.Core/BaseProvider/ServiceBase.cs b/vol-net6/VOL.Core/BaseProvider/ServiceBase.cs index d9978e7..1f79f5f 100644 --- a/vol-net6/VOL.Core/BaseProvider/ServiceBase.cs +++ b/vol-net6/VOL.Core/BaseProvider/ServiceBase.cs @@ -73,7 +73,7 @@ namespace VOL.Core.BaseProvider protected virtual void Init(IRepository repository) { - + IsMultiTenancy = true; // 开启租户隔离 } protected virtual Type GetRealDetailType() diff --git a/vol-net6/VOL.Core/Controllers/Basic/ApiBaseController.cs b/vol-net6/VOL.Core/Controllers/Basic/ApiBaseController.cs index adec094..90efdad 100644 --- a/vol-net6/VOL.Core/Controllers/Basic/ApiBaseController.cs +++ b/vol-net6/VOL.Core/Controllers/Basic/ApiBaseController.cs @@ -62,7 +62,7 @@ namespace VOL.Core.Controllers.Basic /// [ApiActionPermission(Enums.ActionPermissionOptions.Search)] [HttpPost, Route("GetDetailPage")] - [ApiExplorerSettings(IgnoreApi = true)] + [ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口 public virtual ActionResult GetDetailPage([FromBody] PageDataOptions loadData) { return Content(InvokeService("GetDetailPage", new object[] { loadData }).Serialize()); @@ -167,7 +167,7 @@ namespace VOL.Core.Controllers.Basic /// [ApiActionPermission(Enums.ActionPermissionOptions.Delete)] [HttpPost, Route("Del")] - [ApiExplorerSettings(IgnoreApi = true)] + [ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口 public virtual ActionResult Del([FromBody] object[] keys) { _baseWebResponseContent = InvokeService("Del", new object[] { keys, true }) as WebResponseContent; @@ -181,7 +181,7 @@ namespace VOL.Core.Controllers.Basic /// [ApiActionPermission(Enums.ActionPermissionOptions.Audit)] [HttpPost, Route("Audit")] - [ApiExplorerSettings(IgnoreApi = true)] + [ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口 public virtual ActionResult Audit([FromBody] object[] id, int? auditStatus, string auditReason) { _baseWebResponseContent = InvokeService("Audit", new object[] { id, auditStatus, auditReason }) as WebResponseContent; @@ -195,7 +195,7 @@ namespace VOL.Core.Controllers.Basic /// [ApiActionPermission(Enums.ActionPermissionOptions.Add)] [HttpPost, Route("Add")] - [ApiExplorerSettings(IgnoreApi = true)] + [ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口 public virtual ActionResult Add([FromBody] SaveModel saveModel) { _baseWebResponseContent = InvokeService("Add", @@ -212,8 +212,8 @@ namespace VOL.Core.Controllers.Basic /// /// [ApiActionPermission(Enums.ActionPermissionOptions.Update)] - [HttpPost, Route("Update")] - [ApiExplorerSettings(IgnoreApi = true)] + [HttpPost, Route("Update")] + [ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口 public virtual ActionResult Update([FromBody] SaveModel saveModel) { _baseWebResponseContent = InvokeService("Update", new object[] { saveModel }) as WebResponseContent; diff --git a/vol-net6/VOL.Core/EFDbContext/EFLoggerProvider.cs b/vol-net6/VOL.Core/EFDbContext/EFLoggerProvider.cs index 123093d..fde2f37 100644 --- a/vol-net6/VOL.Core/EFDbContext/EFLoggerProvider.cs +++ b/vol-net6/VOL.Core/EFDbContext/EFLoggerProvider.cs @@ -26,7 +26,11 @@ namespace VOL.Core.EFDbContext && logLevel == LogLevel.Information) { var logContent = formatter(state, exception); + // TODO: 拿到日志内容想怎么玩就怎么玩吧 + Console.WriteLine(); + Console.ForegroundColor = ConsoleColor.Green; // 字体绿色 Console.WriteLine(logContent); + Console.ResetColor(); } } public IDisposable BeginScope(TState state) => null; diff --git a/vol-net6/VOL.Core/EFDbContext/VOLContext.cs b/vol-net6/VOL.Core/EFDbContext/VOLContext.cs index c863152..8c9175c 100644 --- a/vol-net6/VOL.Core/EFDbContext/VOLContext.cs +++ b/vol-net6/VOL.Core/EFDbContext/VOLContext.cs @@ -84,11 +84,14 @@ namespace VOL.Core.EFDbContext { optionsBuilder.UseSqlServer(connectionString); } - //默认禁用实体跟踪 + // 默认禁用实体跟踪(注释记录EFCore时) optionsBuilder = optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); - //var loggerFactory = new LoggerFactory(); - //loggerFactory.AddProvider(new EFLoggerProvider()); - // optionsBuilder.UseLoggerFactory(loggerFactory); + + // 记录EFCore产生的SQL语句 + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + base.OnConfiguring(optionsBuilder); } protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/vol-net6/VOL.Core/Tenancy/TenancyManager.cs b/vol-net6/VOL.Core/Tenancy/TenancyManager.cs index 6d714cc..40fd8c7 100644 --- a/vol-net6/VOL.Core/Tenancy/TenancyManager.cs +++ b/vol-net6/VOL.Core/Tenancy/TenancyManager.cs @@ -16,16 +16,16 @@ namespace VOL.Core.Tenancy { string multiTenancyString = $"select * from {tableName}"; //超级管理员不限制 - //if (UserContext.Current.IsSuperAdmin) - //{ - // return multiTenancyString; - //} + if (UserContext.Current.IsSuperAdmin) + { + return multiTenancyString; + } switch (tableName) { //例如:指定用户表指定查询条件 - //case "Sys_User": - // multiTenancyString += $" where UserId='{UserContext.Current.UserId}'"; - // break; + case "Sys_User": + multiTenancyString += $" where UserId='{UserContext.Current.UserId}'"; + break; default: //开启数租户数据隔离,用户只能看到自己的表数据(自己根据需要写条件做租户数据隔离) multiTenancyString += $" where CreateID='{UserContext.Current.UserId}'"; diff --git a/vol-net6/VOL.Core/Utils/CommonUtil.cs b/vol-net6/VOL.Core/Utils/CommonUtil.cs new file mode 100644 index 0000000..202771c --- /dev/null +++ b/vol-net6/VOL.Core/Utils/CommonUtil.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; + +namespace VOL.Core.Utils +{ + public class CommonUtil + { + // 实体对象转Dictionary + + public static Dictionary ConvertToDictionary(T entity) + { + var dictionary = new Dictionary(); + var properties = typeof(T).GetProperties(); + + foreach (var property in properties) + { + var key = property.Name; + var value = property.GetValue(entity); + dictionary.Add(key, value); + } + + return dictionary; + } + + // Dictionary转实体对象 + public static T ConvertToObject(Dictionary dictionary) where T : new() + { + var obj = new T(); + var properties = typeof(T).GetProperties(); + + foreach (var property in properties) + { + if (dictionary.TryGetValue(property.Name, out var value)) + { + property.SetValue(obj, value); + } + } + + return obj; + } + } +} diff --git a/vol-net6/VOL.Core/Utils/DataConvertUtil.cs b/vol-net6/VOL.Core/Utils/DataConvertUtil.cs new file mode 100644 index 0000000..8669653 --- /dev/null +++ b/vol-net6/VOL.Core/Utils/DataConvertUtil.cs @@ -0,0 +1,306 @@ +using System.Text; +using System; + +namespace VOL.Core.Utils +{ + public class DataConvertUtil + { + /// + /// 赋值string string => ushort[] + /// + /// + /// + /// + /// + public static void SetString(ushort[] src, int start, string value) + { + byte[] bytesTemp = Encoding.UTF8.GetBytes(value); + ushort[] dest = Bytes2Ushorts(bytesTemp); + dest.CopyTo(src, start); + } + + /// + /// 获取string ushort[] => string + /// + /// + /// + /// + /// string + public static string GetString(ushort[] src, int start, int len) + { + ushort[] temp = new ushort[len]; + for (int i = 0; i < len; i++) + { + temp[i] = src[i + start]; + } + byte[] bytesTemp = Ushorts2Bytes(temp); + //string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' }); // 去除字符串左右端的指定内容 + string res = Encoding.UTF8.GetString(bytesTemp).Trim(); + return res; + } + + /// + /// 赋值Real float => ushort[] + /// + /// + /// + /// + public static void SetReal(ushort[] src, int start, float value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + /// + /// 获取float ushort[] => float + /// + /// + /// + /// float + public static float GetReal(ushort[] src, int start) + { + try + { + ushort[] temp = new ushort[2]; + for (int i = 0; i < 2; i++) + { + temp[i] = src[i + start]; + } + byte[] bytesTemp = Ushorts2Bytes(temp,false); + // !!!BitConverter默认是小端转换,如果是大端顺序数组接收,需要先反序字节顺序 + Array.Reverse(bytesTemp); + float res = BitConverter.ToSingle(bytesTemp, 0); + return res; + } catch (Exception e) + { + return 0; + } + + } + + /// + /// 赋值Short short => ushort[] + /// + /// + /// + /// + public static void SetShort(ushort[] src, int start, short value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + /// + /// 获取short ushort[] => short + /// + /// + /// + /// short + public static short GetShort(ushort[] src, int start) + { + try + { + ushort[] temp = new ushort[1]; + temp[0] = src[start]; + byte[] bytesTemp = Ushorts2Bytes(temp); + short res = BitConverter.ToInt16(bytesTemp, 0); + return res; + } + catch (Exception e) + { + return 0; + } + + } + + /// + /// 赋值Short short => ushort[] + /// + /// + /// + /// + public static void SetInt(ushort[] src, int start, int value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + + /// + /// 获取short ushort[] => int + /// + /// + /// + /// short + public static int GetInt(ushort[] src, int start) + { + try { + ushort[] temp = new ushort[2]; + temp[0] = src[start]; + temp[1] = src[start + 1]; // 0 100 + Array.Reverse(temp); + byte[] bytesTemp = Ushorts2Bytes(temp); + int res = BitConverter.ToInt32(bytesTemp, 0); + return res; + } catch (Exception e) + { + return 0; + } + + } + + + /// + /// 获取short ushort[] => long + /// + /// + /// + /// short + public static long GetLong(ushort[] src, int start) + { + try { + ushort[] temp = new ushort[4]; + temp[0] = src[start]; + temp[1] = src[start + 1]; + temp[2] = src[start + 2]; + temp[3] = src[start + 3]; + Array.Reverse(temp); + byte[] bytesTemp = Ushorts2Bytes(temp); + long res = BitConverter.ToInt64(bytesTemp, 0); + return res; + } catch (Exception e) + { + return 0; + } + + } + + + + /// + /// 获取bool数组 ushort[] => bool[] + /// + /// + /// + /// short + + public static bool[] GetBools(ushort[] src, int start, int num) + { + ushort[] temp = new ushort[num]; + for (int i = start; i < start + num; i++) + { + temp[i] = src[i + start]; + } + Array.Reverse(temp); // 反序,小端读取 + byte[] bytes = Ushorts2Bytes(temp); + bool[] res = Bytes2Bools(bytes); + return res; + } + + + // byte[] => bool[] + private static bool[] Bytes2Bools(byte[] b) + { + bool[] array = new bool[8 * b.Length]; + + for (int i = 0; i < b.Length; i++) + { + for (int j = 0; j < 8; j++) + { + array[i * 8 + j] = (b[i] & 1) == 1;//判定byte的最后一位是否为1,若为1,则是true;否则是false + b[i] = (byte)(b[i] >> 1);//将byte右移一位 + } + } + return array; + } + + // bool[] => byte + private static byte Bools2Byte(bool[] array) + { + if (array != null && array.Length > 0) + { + byte b = 0; + for (int i = 0; i < 8; i++) + { + if (array[i]) + { + byte nn = (byte)(1 << i);//左移一位,相当于×2 + b += nn; + } + } + return b; + } + return 0; + } + + + // byte[] => ushort[] + private static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false) + { + int len = src.Length; + + byte[] srcPlus = new byte[len + 1]; + src.CopyTo(srcPlus, 0); + int count = len >> 1; + + if (len % 2 != 0) + { + count += 1; + } + + ushort[] dest = new ushort[count]; + if (reverse) + { + for (int i = 0; i < count; i++) + { + dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff); + } + } + else + { + for (int i = 0; i < count; i++) + { + dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8); + } + } + + return dest; + } + + + // ushort[] => byte[] + private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false) + { + + int count = src.Length; + byte[] dest = new byte[count << 1]; + if (reverse) // 大端 + { + for (int i = 0; i < count; i++) + { + dest[i * 2] = (byte)(src[i] >> 8); + dest[i * 2 + 1] = (byte)(src[i] >> 0); + } + } + else // 小端 + { + for (int i = 0; i < count; i++) + { + dest[i * 2] = (byte)(src[i] >> 0); + dest[i * 2 + 1] = (byte)(src[i] >> 8); + } + } + return dest; + } + } + +} diff --git a/vol-net6/VOL.Data/Class1.cs b/vol-net6/VOL.Data/Class1.cs new file mode 100644 index 0000000..330ac58 --- /dev/null +++ b/vol-net6/VOL.Data/Class1.cs @@ -0,0 +1,7 @@ +namespace VOL.Data +{ + public class Class1 + { + + } +} \ No newline at end of file diff --git a/vol-net6/VOL.Data/IRepositories/config/IData_ConfigRepository.cs b/vol-net6/VOL.Data/IRepositories/config/IData_ConfigRepository.cs new file mode 100644 index 0000000..2b0faf5 --- /dev/null +++ b/vol-net6/VOL.Data/IRepositories/config/IData_ConfigRepository.cs @@ -0,0 +1,18 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *Repository提供数据库操作,如果要增加数据库操作请在当前目录下Partial文件夹IData_ConfigRepository编写接口 + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Core.BaseProvider; +using VOL.Entity.DomainModels; +using VOL.Core.Extensions.AutofacManager; +namespace VOL.Data.IRepositories +{ + public partial interface IData_ConfigRepository : IDependency,IRepository + { + } +} diff --git a/vol-net6/VOL.Data/IRepositories/machine/IData_MachineRepository.cs b/vol-net6/VOL.Data/IRepositories/machine/IData_MachineRepository.cs new file mode 100644 index 0000000..1319286 --- /dev/null +++ b/vol-net6/VOL.Data/IRepositories/machine/IData_MachineRepository.cs @@ -0,0 +1,18 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *Repository提供数据库操作,如果要增加数据库操作请在当前目录下Partial文件夹IData_MachineRepository编写接口 + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Core.BaseProvider; +using VOL.Entity.DomainModels; +using VOL.Core.Extensions.AutofacManager; +namespace VOL.Data.IRepositories +{ + public partial interface IData_MachineRepository : IDependency,IRepository + { + } +} diff --git a/vol-net6/VOL.Data/IRepositories/produce/IData_ProduceRepository.cs b/vol-net6/VOL.Data/IRepositories/produce/IData_ProduceRepository.cs new file mode 100644 index 0000000..3882874 --- /dev/null +++ b/vol-net6/VOL.Data/IRepositories/produce/IData_ProduceRepository.cs @@ -0,0 +1,18 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *Repository提供数据库操作,如果要增加数据库操作请在当前目录下Partial文件夹IData_ProduceRepository编写接口 + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Core.BaseProvider; +using VOL.Entity.DomainModels; +using VOL.Core.Extensions.AutofacManager; +namespace VOL.Data.IRepositories +{ + public partial interface IData_ProduceRepository : IDependency,IRepository + { + } +} diff --git a/vol-net6/VOL.Data/IServices/config/IData_ConfigService.cs b/vol-net6/VOL.Data/IServices/config/IData_ConfigService.cs new file mode 100644 index 0000000..502df3e --- /dev/null +++ b/vol-net6/VOL.Data/IServices/config/IData_ConfigService.cs @@ -0,0 +1,12 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + */ +using VOL.Core.BaseProvider; +using VOL.Entity.DomainModels; + +namespace VOL.Data.IServices +{ + public partial interface IData_ConfigService : IService + { + } +} diff --git a/vol-net6/VOL.Data/IServices/config/Partial/IData_ConfigService.cs b/vol-net6/VOL.Data/IServices/config/Partial/IData_ConfigService.cs new file mode 100644 index 0000000..655874a --- /dev/null +++ b/vol-net6/VOL.Data/IServices/config/Partial/IData_ConfigService.cs @@ -0,0 +1,19 @@ +/* +*所有关于Data_Config类的业务代码接口应在此处编写 +*/ +using VOL.Core.BaseProvider; +using VOL.Entity.DomainModels; +using VOL.Core.Utilities; +using System.Linq.Expressions; +namespace VOL.Data.IServices +{ + public partial interface IData_ConfigService + { + // 获取设备配置列表 + List getConfigList(); + + // 根据主键查询设备 + + Data_Config GetConfigById(int id); + } + } diff --git a/vol-net6/VOL.Data/IServices/machine/IData_MachineService.cs b/vol-net6/VOL.Data/IServices/machine/IData_MachineService.cs new file mode 100644 index 0000000..2001ef7 --- /dev/null +++ b/vol-net6/VOL.Data/IServices/machine/IData_MachineService.cs @@ -0,0 +1,12 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + */ +using VOL.Core.BaseProvider; +using VOL.Entity.DomainModels; + +namespace VOL.Data.IServices +{ + public partial interface IData_MachineService : IService + { + } +} diff --git a/vol-net6/VOL.Data/IServices/machine/Partial/IData_MachineService.cs b/vol-net6/VOL.Data/IServices/machine/Partial/IData_MachineService.cs new file mode 100644 index 0000000..371b948 --- /dev/null +++ b/vol-net6/VOL.Data/IServices/machine/Partial/IData_MachineService.cs @@ -0,0 +1,15 @@ +/* +*所有关于Data_Machine类的业务代码接口应在此处编写 +*/ +using VOL.Core.BaseProvider; +using VOL.Entity.DomainModels; +using VOL.Core.Utilities; +using System.Linq.Expressions; +namespace VOL.Data.IServices +{ + public partial interface IData_MachineService + { + // 查询设备列表数据 + Dictionary GetMachineData(); + } + } diff --git a/vol-net6/VOL.Data/IServices/modbus/IDataProcessing.cs b/vol-net6/VOL.Data/IServices/modbus/IDataProcessing.cs new file mode 100644 index 0000000..0381af9 --- /dev/null +++ b/vol-net6/VOL.Data/IServices/modbus/IDataProcessing.cs @@ -0,0 +1,35 @@ +using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using VOL.Entity.DomainModels; + +namespace VOL.Data.IServices.modbus +{ + public interface IDataProcessing + { + // 读西门子数据 + Dictionary> readSiemensData(IModbusService modbus); + + // 读广数数据 + Dictionary> readGSKData(IModbusService modbus); + + + // 获取设备配置信息 + Data_Config GetDataConfig(int deviceId); + + // 保存设备数据 + bool saveMachineData(Data_Machine machine, out string message); + + + // 保存生产数据 + bool saveProduceData(Data_Produce produce, out string message); + + + } +} diff --git a/vol-net6/VOL.Data/IServices/modbus/IModbusService.cs b/vol-net6/VOL.Data/IServices/modbus/IModbusService.cs new file mode 100644 index 0000000..ce3f407 --- /dev/null +++ b/vol-net6/VOL.Data/IServices/modbus/IModbusService.cs @@ -0,0 +1,46 @@ +using NModbus; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VOL.Data.IServices.modbus +{ + public interface IModbusService + { + /// + /// 创建主站客户端 + /// + /// + void createModbusClient(); + + + /// + /// 关闭链接 + /// + /// + void disConnent(); + + /// + /// 从站地址 + /// 起始地址 + /// 数据 + /// 写数据 + /// + /// + + void writeData(byte slaveAddress, ushort startAddress, object data); + + + /// + /// 从站地址 + /// 起始地址 + /// 寄存器单元地址数 + /// 读数据 + /// + /// dynamic + + dynamic readData(byte slaveAddress, ushort startAddress, string type, int units = 1); + } +} diff --git a/vol-net6/VOL.Data/IServices/produce/IData_ProduceService.cs b/vol-net6/VOL.Data/IServices/produce/IData_ProduceService.cs new file mode 100644 index 0000000..d82fae9 --- /dev/null +++ b/vol-net6/VOL.Data/IServices/produce/IData_ProduceService.cs @@ -0,0 +1,12 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + */ +using VOL.Core.BaseProvider; +using VOL.Entity.DomainModels; + +namespace VOL.Data.IServices +{ + public partial interface IData_ProduceService : IService + { + } +} diff --git a/vol-net6/VOL.Data/IServices/produce/Partial/IData_ProduceService.cs b/vol-net6/VOL.Data/IServices/produce/Partial/IData_ProduceService.cs new file mode 100644 index 0000000..2a5d6e0 --- /dev/null +++ b/vol-net6/VOL.Data/IServices/produce/Partial/IData_ProduceService.cs @@ -0,0 +1,23 @@ +/* +*所有关于Data_Produce类的业务代码接口应在此处编写 +*/ +using VOL.Entity.DomainModels; + + +namespace VOL.Data.IServices +{ + public partial interface IData_ProduceService + { + // 根据查询对象获取最新的一条记录 + Data_Produce getLastProduceData(Func query); + + + // 最近一周生产加工数 + Dictionary produceDataGroupByWeekDays(); + + + // 近一周工单走势数据 + Dictionary workDataGroupByWeekDays(int configId, string target); + + } + } diff --git a/vol-net6/VOL.Data/Repositories/config/Data_ConfigRepository.cs b/vol-net6/VOL.Data/Repositories/config/Data_ConfigRepository.cs new file mode 100644 index 0000000..5b56ac4 --- /dev/null +++ b/vol-net6/VOL.Data/Repositories/config/Data_ConfigRepository.cs @@ -0,0 +1,24 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *Repository提供数据库操作,如果要增加数据库操作请在当前目录下Partial文件夹Data_ConfigRepository编写代码 + */ +using VOL.Data.IRepositories; +using VOL.Core.BaseProvider; +using VOL.Core.EFDbContext; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; + +namespace VOL.Data.Repositories +{ + public partial class Data_ConfigRepository : RepositoryBase , IData_ConfigRepository + { + public Data_ConfigRepository(VOLContext dbContext) + : base(dbContext) + { + + } + public static IData_ConfigRepository Instance + { + get { return AutofacContainerModule.GetService(); } } + } +} diff --git a/vol-net6/VOL.Data/Repositories/machine/Data_MachineRepository.cs b/vol-net6/VOL.Data/Repositories/machine/Data_MachineRepository.cs new file mode 100644 index 0000000..66b3cb1 --- /dev/null +++ b/vol-net6/VOL.Data/Repositories/machine/Data_MachineRepository.cs @@ -0,0 +1,24 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *Repository提供数据库操作,如果要增加数据库操作请在当前目录下Partial文件夹Data_MachineRepository编写代码 + */ +using VOL.Data.IRepositories; +using VOL.Core.BaseProvider; +using VOL.Core.EFDbContext; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; + +namespace VOL.Data.Repositories +{ + public partial class Data_MachineRepository : RepositoryBase , IData_MachineRepository + { + public Data_MachineRepository(VOLContext dbContext) + : base(dbContext) + { + + } + public static IData_MachineRepository Instance + { + get { return AutofacContainerModule.GetService(); } } + } +} diff --git a/vol-net6/VOL.Data/Repositories/produce/Data_ProduceRepository.cs b/vol-net6/VOL.Data/Repositories/produce/Data_ProduceRepository.cs new file mode 100644 index 0000000..d06fa89 --- /dev/null +++ b/vol-net6/VOL.Data/Repositories/produce/Data_ProduceRepository.cs @@ -0,0 +1,24 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *Repository提供数据库操作,如果要增加数据库操作请在当前目录下Partial文件夹Data_ProduceRepository编写代码 + */ +using VOL.Data.IRepositories; +using VOL.Core.BaseProvider; +using VOL.Core.EFDbContext; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; + +namespace VOL.Data.Repositories +{ + public partial class Data_ProduceRepository : RepositoryBase , IData_ProduceRepository + { + public Data_ProduceRepository(VOLContext dbContext) + : base(dbContext) + { + + } + public static IData_ProduceRepository Instance + { + get { return AutofacContainerModule.GetService(); } } + } +} diff --git a/vol-net6/VOL.Data/Services/config/Data_ConfigService.cs b/vol-net6/VOL.Data/Services/config/Data_ConfigService.cs new file mode 100644 index 0000000..ea08790 --- /dev/null +++ b/vol-net6/VOL.Data/Services/config/Data_ConfigService.cs @@ -0,0 +1,27 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下Data_ConfigService与IData_ConfigService中编写 + */ +using VOL.Data.IRepositories; +using VOL.Data.IServices; +using VOL.Core.BaseProvider; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; + +namespace VOL.Data.Services +{ + public partial class Data_ConfigService : ServiceBase + , IData_ConfigService, IDependency + { + public Data_ConfigService(IData_ConfigRepository repository) + : base(repository) + { + Init(repository); + } + public static IData_ConfigService Instance + { + get { return AutofacContainerModule.GetService(); } } + } + } diff --git a/vol-net6/VOL.Data/Services/config/Partial/Data_ConfigService.cs b/vol-net6/VOL.Data/Services/config/Partial/Data_ConfigService.cs new file mode 100644 index 0000000..4428e07 --- /dev/null +++ b/vol-net6/VOL.Data/Services/config/Partial/Data_ConfigService.cs @@ -0,0 +1,52 @@ +/* + *所有关于Data_Config类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*Data_ConfigService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VOL.Core.BaseProvider; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; +using System.Linq; +using VOL.Core.Utilities; +using System.Linq.Expressions; +using VOL.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VOL.Data.IRepositories; + +namespace VOL.Data.Services +{ + public partial class Data_ConfigService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IData_ConfigRepository _repository;//访问数据库 + + [ActivatorUtilitiesConstructor] + public Data_ConfigService( + IData_ConfigRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + base.Init(dbRepository); + } + + public List getConfigList() { + var list = _repository.DbContext.Set().Select(x => new Data_Config() { + id = x.id, name = x.name, type = x.type, device_ip = x.device_ip, com_ip = x.com_ip + }).OrderBy(x => x.id).ToList(); + return list; + } + + public Data_Config GetConfigById(int id) { + return _repository.DbContext.Set().FirstOrDefault(e => e.id == id); + } + } +} diff --git a/vol-net6/VOL.Data/Services/machine/Data_MachineService.cs b/vol-net6/VOL.Data/Services/machine/Data_MachineService.cs new file mode 100644 index 0000000..edece9f --- /dev/null +++ b/vol-net6/VOL.Data/Services/machine/Data_MachineService.cs @@ -0,0 +1,29 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下Data_MachineService与IData_MachineService中编写 + */ +using VOL.Data.IRepositories; +using VOL.Data.IServices; +using VOL.Core.BaseProvider; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; + +namespace VOL.Data.Services +{ + public partial class Data_MachineService : ServiceBase + , IData_MachineService, IDependency + { + public Data_MachineService(IData_MachineRepository repository) + : base(repository) + { + Init(repository); + } + public static IData_MachineService Instance + { + get { return AutofacContainerModule.GetService(); } + } + } + +} diff --git a/vol-net6/VOL.Data/Services/machine/Partial/Data_MachineService.cs b/vol-net6/VOL.Data/Services/machine/Partial/Data_MachineService.cs new file mode 100644 index 0000000..3e33b73 --- /dev/null +++ b/vol-net6/VOL.Data/Services/machine/Partial/Data_MachineService.cs @@ -0,0 +1,131 @@ +/* + *所有关于Data_Machine类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*Data_MachineService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VOL.Core.BaseProvider; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; +using System.Linq; +using VOL.Core.Utilities; +using System.Linq.Expressions; +using VOL.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VOL.Data.IRepositories; +using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; +using SkiaSharp; +using StackExchange.Redis; +using System.Text.RegularExpressions; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using VOL.Core.Utilities; + +namespace VOL.Data.Services +{ + public partial class Data_MachineService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IData_MachineRepository _repository;//访问数据库 + + private WebResponseContent webResponse = new WebResponseContent(); + + [ActivatorUtilitiesConstructor] + public Data_MachineService( + IData_MachineRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + base.Init(dbRepository); + } + + public Dictionary GetMachineData() + { + var db = _repository.DbContext.Set(); + var machineList = new Dictionary(); + List configList = Data_ConfigService.Instance.getConfigList(); + IQueryable query = db.Where(x => x.com_status == 5); + foreach ( Data_Config config in configList ) + { + // 机床数据,各自取最新一条 + Data_Machine? data_Machine = query.Where(x => x.config_id == config.id). + OrderByDescending(d => d.CreateDate).FirstOrDefault(); + if ( data_Machine != null ) + { + data_Machine.com_ip = config.com_ip; + data_Machine.name = config.name; + data_Machine.totalQuantity = data_Machine.quantity_total; + data_Machine.totalRuntime = data_Machine.run_time_total; + // 判断通讯是否断开 + #pragma warning disable CS8600 + Data_Machine lastdata_Machine = db.Where(x => x.config_id == config.id). + OrderByDescending(d => d.CreateDate).FirstOrDefault(); + #pragma warning restore CS8600 + data_Machine.com_status = lastdata_Machine.com_status; + // 生产数据, 各自取最新一条 + Func where = p => p.config_id == config.id && p.com_status == 5; + Data_Produce data_Produce = Data_ProduceService.Instance.getLastProduceData(where); + if (data_Produce != null) + { + data_Machine.currentTurnout = data_Produce.turnout_all; + data_Machine.OEE = data_Produce.oee; + } + machineList.Add(config.id, data_Machine); + } + } + return machineList; + } + + + // 重写Add方法 + public override WebResponseContent Add(SaveModel saveDataModel) { + Dictionary mapData = saveDataModel.MainData; + mapData.TryGetValue("CreateID", out var userId); + mapData.TryGetValue("CreateDate", out var CreateDate); + AddOnExecuting = (Data_Machine data_Machine, object list) => + { + if (userId != null) + { + data_Machine.CreateID = (int?)userId; + } + if (CreateDate != null) + { + data_Machine.CreateDate = (DateTime?)CreateDate; + } + return webResponse.OK(); + }; + return base.Add(saveDataModel); + } + + // 测试使用 + public void testQuery() { + //List data_Machines = _repository.DbContext.Set().ToList(); + //var list = db.Where(x => x.com_status == 5).GroupBy(e => e.config_id).Select(g => new { + // ConfigId = g.Key, + // Data_Machine = g.OrderByDescending(d => d.CreateDate).ToList() + //}).OrderBy(g => g.ConfigId).ToList(); + // 1. 查设备ID分组 + //var result1 = db.GroupBy(e => e.config_id).Select(g => new + //{ + // ConfigId = g.Key + //}).OrderBy(g => g.ConfigId).ToList(); + //List configIds = result1.Select(c => c.ConfigId).ToList(); + // 2. 查找设备名称并赋值 + //var result2 = db.Where(p => configIds.Contains(p.config_id) && p.com_status == 5).OrderByDescending(o => o.CreateDate).ToList(); + //Console.Write(JsonConvert.SerializeObject(result2)); + + //Console.Write(string.Join(",", data_Machines)); + //var list = db.GroupBy(e => e.config_id).Count(); + } + } +} diff --git a/vol-net6/VOL.Data/Services/modbus/DataProcessing.cs b/vol-net6/VOL.Data/Services/modbus/DataProcessing.cs new file mode 100644 index 0000000..1ac0e97 --- /dev/null +++ b/vol-net6/VOL.Data/Services/modbus/DataProcessing.cs @@ -0,0 +1,211 @@ +using Microsoft.AspNetCore.Http; +using VOL.Data.IServices.modbus; +using VOL.Entity.DomainModels; +using VOL.Core.Services; +using Microsoft.AspNetCore.Mvc; +using Autofac.Core; +using VOL.Core.Extensions.AutofacManager; +using System.Reflection.PortableExecutable; + +namespace VOL.Data.Services.modbus +{ + public class DataProcessing : IDataProcessing, IDependency // 继承IDependency,交给Ioc容器接管 + { + private readonly IHttpContextAccessor _httpContextAccessor; + + public DataProcessing(IHttpContextAccessor httpContextAccessor) { + _httpContextAccessor = httpContextAccessor; + } + + + // 读西门子数据 + public Dictionary> readSiemensData(IModbusService modbus) + { + // 生产数据 + Dictionary map1 = new Dictionary + { + { "com_status",modbus.readData(1, 6430, "int16") }, // 通讯状态 5:通讯正常 15:通讯断线 + { "run_time", (int)modbus.readData(1, 6435, "int16") }, // 运行时长 分钟 + { "turnout_1",(int)modbus.readData(1, 6436, "int16") }, // 工单1产量 件 + { "turnout_2", (int)modbus.readData(1, 6437, "int16") }, // 工单2产量 件 + { "turnout_3", (int)modbus.readData(1, 6438, "int16") }, // 工单3产量 件 + { "turnout_all", (int)modbus.readData(1, 6439, "int16") }, // 当班产量 件 + { "status", modbus.readData(1, 6440, "int16") }, // 运行状态 0:待机 1:运行 2:故障 + { "schedule_1", (decimal)modbus.readData(1, 1315, "single") }, // 工单1任务进度 % + { "schedule_2",(decimal) modbus.readData(1, 1317, "single") }, // 工单2任务进度 % + { "schedule_3", (decimal)modbus.readData(1, 1319, "single") }, // 工单3任务进度 % + { "yield_1", (decimal)modbus.readData(1, 1321, "single") }, // 工单1良品率 % 真实值 *= 100 + { "yield_2", (decimal)modbus.readData(1, 1323, "single") }, // 工单2良品率 % 真实值 *= 100 + { "yield_3", (decimal)modbus.readData(1, 1325, "single") }, // 工单3良品率 % 真实值 *= 100 + { "oee", (decimal)modbus.readData(1, 1339, "single") }, // 设备综合效率 % 真实值 *= 100 + }; + + // 机床数据 + Dictionary map2 = new Dictionary + { + // 操作模式 0:JOG 1:AUTO 2:AUTO + TEACHIN 3:JOG + REPOIN 4:JOG + REPOS + // 5:MDA 6:MDA + REPOS 7:MDA + REPOS + TEAHIN8:MDA + TEACHIN + { "com_status", modbus.readData(1, 6430, "int16") }, // 通讯状态 5:通讯正常 15:通讯断线 + { "smode", modbus.readData(1, 6099, "int16") }, + { "state", modbus.readData(1, 6429, "int16") }, // 运行状态 0:待机 1:故障 2:运行 3:暂停 + { "temperature", (decimal)modbus.readData(1, 1201, "single")}, // 电机温度 ℃ + { "potential", (decimal)modbus.readData(1, 1203, "single")}, // 母线电压 V + { "current", (decimal)modbus.readData(1, 1205, "single")}, // 实际电流 A + { "cut_rate", (decimal)modbus.readData(1, 1225, "single")}, // 切削倍率 + { "main_rate", (decimal)modbus.readData(1, 1231, "single")}, // 主轴倍率 + { "run_program_no", modbus.readData(1, 6689, "string", 26)}, // 加工程序号 length = 52 + { "run_time_total", (long)modbus.readData(1, 6435, "int16")}, // 累计运行时长 分钟 + { "quantity_total", (long)modbus.readData(1, 1215, "single")}, // 累计加工数 次 + }; + + // 组装Map返回 + Dictionary> map = new(); + map.Add("produce", map1); + map.Add("machine", map2); + return map; + } + + // 读广数数据 + public Dictionary> readGSKData(IModbusService modbus) + { + // 生产数据 + Dictionary map1 = new Dictionary + { + { "program_no", (int)modbus.readData(1, 6429, "int16") }, // 程序编号 + { "com_status", modbus.readData(1, 6430, "int16") }, // 通讯状态 5:通讯正常 15:通讯断线 + { "run_time", (int)modbus.readData(1, 6435, "int16") }, // 运行时长 分钟 + { "turnout_1", (int)modbus.readData(1, 6436, "int16") }, // 工单1产量 件 + { "turnout_2", (int)modbus.readData(1, 6437, "int16") }, // 工单2产量 件 + { "turnout_3", (int)modbus.readData(1, 6438, "int16") }, // 工单3产量 件 + { "turnout_all",(int)modbus.readData(1, 6439, "int16") }, // 当班产量 件 + { "status", modbus.readData(1, 6440, "int16") }, // 运行状态 0:待机 1:运行 2:故障 + { "schedule_1", (decimal)modbus.readData(1, 1315, "single") }, // 工单1任务进度 % + { "schedule_2", (decimal)modbus.readData(1, 1317, "single") }, // 工单2任务进度 % + { "schedule_3", (decimal)modbus.readData(1, 1319, "single") }, // 工单3任务进度 % + { "yield_1", (decimal)modbus.readData(1, 1321, "single") }, // 工单1良品率 % 真实值 *= 100 + { "yield_2", (decimal)modbus.readData(1, 1323, "single") }, // 工单2良品率 % 真实值 *= 100 + { "yield_3", (decimal)modbus.readData(1, 1325, "single") }, // 工单3良品率 % 真实值 *= 100 + { "oee", (decimal)modbus.readData(1, 1331, "single") }, // 设备综合效率 % 真实值 *= 100 + }; + + // 机床数据 + Dictionary map2 = new Dictionary + { + { "com_status", modbus.readData(1, 6430, "int16") }, // 通讯状态 5:通讯正常 15:通讯断线 + { "gmode", modbus.readData(1, 6099, "int16") }, // 工作方式 0:编辑 1:自动 2:MDI 3:DNC 4:手动 5:手轮 6:回参考点 + { "state", modbus.readData(1, 6100, "int16") }, // 运行状态 0:复位 1:停止 2:运行 3:暂停 + { "quantity", (long)modbus.readData(1, 4117, "int32")}, // 当天加工数量 次 + { "on_time", (long)modbus.readData(1, 1201, "int32")}, // 开机时间 秒 + { "run_time", (long)modbus.readData(1, 1203, "int32")}, // 运行时间 秒 + { "feed_rate", (decimal)modbus.readData(1, 1241, "single")}, // 进给倍率 + { "main_rate", (decimal)modbus.readData(1, 1247, "single")}, // 主轴倍率 + { "run_program_no", modbus.readData(1, 6299, "string", 4)}, // 运行程序编号 length = 8 + { "run_time_total", (long)modbus.readData(1, 4115, "int32")}, // 累计运行时长 分钟 + { "quantity_total", (long)modbus.readData(1, 1199, "int32")} // 累计加工数 次 + }; + + // 组装Map返回 + Dictionary> map = new(); + map.Add("produce", map1); + map.Add("machine", map2); + return map; + } + + // 查询设备信息 + + public Data_Config GetDataConfig(int deviceId) { + return Data_ConfigService.Instance.GetConfigById(deviceId); + } + + + // 保存机床数据 + public bool saveMachineData(Data_Machine machine, out string message) { + SaveModel model = new SaveModel(); + Dictionary mapData = new() + { + { "config_id", machine.config_id}, + { "com_status", machine.com_status ?? 15 }, + { "gmode", machine.gmode ?? 1 }, + { "smode", machine.smode ?? 1 }, + { "run_program_no", machine.run_program_no ?? "12345"}, + { "state", machine.state ?? 0 }, + { "temperature", machine.temperature ?? 0M }, + { "potential", machine.potential ?? 0M}, + { "current", machine.current ?? 0M}, + { "quantity", machine.quantity ?? 0}, + { "on_time", machine.on_time ?? 0}, + { "run_time", machine.run_time ?? 0}, + { "feed_rate",machine.feed_rate ?? 0M}, + { "cut_rate", machine.cut_rate ?? 0M}, + { "main_rate", machine.main_rate ?? 0M}, + { "run_time_total", machine.run_time_total ?? 0}, + { "quantity_total", machine.quantity_total ?? 0}, + { "CreateID", machine.CreateID}, + { "CreateDate", machine.CreateDate}, + }; + model.MainData = mapData; + try { + Core.Utilities.WebResponseContent result = Data_MachineService.Instance.Add(model); + if (!result.Status) + { + message = result.Message; + //Logger.Info(result.Message); + return false; + } + } catch (Exception ex) + { + //Logger.Error(ex.Message); + message = ex.Message; + return false; + } + message = "ok"; + return true; + } + + + + // 保存生产数据 + public bool saveProduceData(Data_Produce produce, out string message) + { + SaveModel model = new SaveModel(); + Dictionary mapData = new() + { + { "config_id", produce.config_id}, + { "program_no", produce.program_no ?? 12345 }, + { "com_status", produce.com_status ?? 15 }, + { "run_time", produce.run_time ?? 0 }, + { "status", produce.status ?? 0 }, + { "turnout_all", produce.turnout_all ?? 0 }, + { "turnout_1", produce.turnout_1 ?? 0 }, + { "turnout_2", produce.turnout_2 ?? 0 }, + { "turnout_3", produce.turnout_3 ?? 0 }, + { "schedule_1", produce.schedule_1 ?? 0M }, + { "schedule_2", produce.schedule_2 ?? 0M }, + { "schedule_3", produce.schedule_3 ?? 0M }, + { "yield_1", produce.yield_1 ?? 1M }, + { "yield_2", produce.yield_2 ?? 0M }, + { "yield_3", produce.yield_3 ?? 0M }, + { "oee", produce.oee ?? 0.95M }, // 默认95% + { "CreateID", produce.CreateID}, + { "CreateDate", produce.CreateDate}, + }; + model.MainData = mapData; + try + { + Core.Utilities.WebResponseContent result = Data_ProduceService.Instance.Add(model); + if (!result.Status) + { + message = result.Message; + return false; + } + } + catch (Exception ex) + { + message = ex.Message; + return false; + } + message = "ok"; + return true; + } + } +} diff --git a/vol-net6/VOL.Data/Services/modbus/ModbusTcpService.cs b/vol-net6/VOL.Data/Services/modbus/ModbusTcpService.cs new file mode 100644 index 0000000..5d1d7ef --- /dev/null +++ b/vol-net6/VOL.Data/Services/modbus/ModbusTcpService.cs @@ -0,0 +1,178 @@ +using NModbus; +using System.Net.Sockets; +using VOL.Data.IServices.modbus; +using VOL.Core.Utils; +using VOL.Core.Extensions; +using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; +using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; + +namespace VOL.Data.Services.modbus +{ + public class ModbusTcpService : IModbusService + { + // IP + private string ip { set; get; } = "127.0.0.1"; + + // 端口 + private int port { set; get; } = 502; + + // 从站地址 + private int slaveNo { set; get; } = 1; + + private TcpClient client; + + private IModbusMaster modbusMaster; + + public ModbusTcpService(string ip, int port) { + this.ip = ip; + this.port = port; + this.client = new TcpClient(ip, port); + this.createModbusClient(); + } + + public void createModbusClient() + { + ModbusFactory modbusFactory = new(); + modbusMaster = modbusFactory.CreateMaster(client); + modbusMaster.Transport.ReadTimeout = 3000; //读超时 + modbusMaster.Transport.WriteTimeout = 3000;//写超时 + modbusMaster.Transport.Retries = 3; + modbusMaster.Transport.WaitToRetryMilliseconds = 500;//尝试重复连接间隔 + } + + + // 是否已连接 + public bool isConnected + { + get => client.Connected; + } + + + // 写寄存器数据 + public void writeData(byte slaveAddress, ushort startAddress, object data) + { + var type = data.GetType().Name.ToLower(); + dynamic val ; + ushort[]? units; // 单元数 + switch (type) { + case "int16": + val = data.ToShort(); + units = new ushort[1]; + DataConvertUtil.SetShort(units, 0, val); + break; + case "int32": + val = data.ToInt(); + units = new ushort[2]; + DataConvertUtil.SetInt(units, 0, val); + break; + case "single": + val = data.ToFloat(); + units = new ushort[2]; + DataConvertUtil.SetReal(units, 0, val); + break; + case "string": + val = data.ToString(); + int length = (int) Math.Ceiling((double) val.Length / 2); + units = new ushort[length]; // 先不考虑中文字符,一个寄存器地址存放两个字符 + DataConvertUtil.SetString(units, 0, val); // units 25690 25690 + break; + default: + throw new ArgumentException("暂未实现写入此类型:"+ type); + } + if (units != null) { + this.WriteMultipleRegisters(slaveAddress, startAddress, units); + } + } + + + + // 读寄存器数据 + public dynamic readData(byte slaveAddress, ushort startAddress, string type, int units = 1) + { + type = type.ToLower(); + ushort[]? source; + dynamic? data = null; + switch (type) + { + case "int16": + source = this.ReadHoldingRegisters(slaveAddress, startAddress, 1); + data = DataConvertUtil.GetShort(source, 0); + break; + case "int32": + source = this.ReadHoldingRegisters(slaveAddress, startAddress, 2); + data = DataConvertUtil.GetInt(source, 0); + break; + case "single": + source = this.ReadHoldingRegisters(slaveAddress, startAddress, 2); + data = DataConvertUtil.GetReal(source, 0); + break; + case "string": + //units = val.Length * 2; // 先不考虑中文字符 + source = this.ReadHoldingRegisters(slaveAddress, startAddress, (ushort) units); // 25690 25690 0 0 + data = DataConvertUtil.GetString(source, 0, units); + break; + default: + throw new ArgumentException("暂未实现读取此类型:" + type); + } + return data; + } + + + + // 读线圈 0x01 0x + public bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort num) + { + return modbusMaster.ReadCoils(slaveAddress, startAddress, num); + } + + // 读离散输入 0x02 1x + public bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort num) + { + return modbusMaster.ReadInputs(slaveAddress, startAddress, num); + } + + // 读保持寄存器 0x03 4x + public ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort num) + { + return modbusMaster.ReadHoldingRegisters(slaveAddress, startAddress, num); + } + + // 读输入寄存器 0x04 3x + public ushort[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort num) + { + return modbusMaster.ReadInputRegisters(slaveAddress, startAddress, num); + } + + // 写单个线圈 0x05 + public void WriteSingleCoil(byte slaveAddress, ushort startAddress, bool value) + { + modbusMaster.WriteSingleCoil(slaveAddress, startAddress, value); + } + + + // 写单个保持寄存器 0x06 + public void WriteSingleRegister(byte slaveAddress, ushort startAddress, ushort value) + { + modbusMaster.WriteSingleRegister(slaveAddress, startAddress, value); + } + + // 写多个线圈 0x0F + public void WriteMultipleCoils(byte slaveAddress, ushort startAddress, bool[] value) + { + modbusMaster.WriteMultipleCoils(slaveAddress, startAddress, value); + } + + // 写多个保持寄存器 0x10 + public void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] value) + { + modbusMaster.WriteMultipleRegisters(slaveAddress, startAddress, value); + } + + + // 关闭Socket + public void disConnent() { + client.Close(); + modbusMaster.Dispose(); + } + } +} diff --git a/vol-net6/VOL.Data/Services/produce/Data_ProduceService.cs b/vol-net6/VOL.Data/Services/produce/Data_ProduceService.cs new file mode 100644 index 0000000..8a32282 --- /dev/null +++ b/vol-net6/VOL.Data/Services/produce/Data_ProduceService.cs @@ -0,0 +1,29 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下Data_ProduceService与IData_ProduceService中编写 + */ +using VOL.Data.IRepositories; +using VOL.Data.IServices; +using VOL.Core.BaseProvider; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; + +namespace VOL.Data.Services +{ + public partial class Data_ProduceService : ServiceBase + , IData_ProduceService, IDependency + { + public Data_ProduceService(IData_ProduceRepository repository) + : base(repository) + { + Init(repository); + } + public static IData_ProduceService Instance + { + get { return AutofacContainerModule.GetService(); } } + } + + + } diff --git a/vol-net6/VOL.Data/Services/produce/Partial/Data_ProduceService.cs b/vol-net6/VOL.Data/Services/produce/Partial/Data_ProduceService.cs new file mode 100644 index 0000000..fd3a642 --- /dev/null +++ b/vol-net6/VOL.Data/Services/produce/Partial/Data_ProduceService.cs @@ -0,0 +1,195 @@ +/* + *所有关于Data_Produce类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*Data_ProduceService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VOL.Core.BaseProvider; +using VOL.Core.Extensions.AutofacManager; +using VOL.Entity.DomainModels; +using System.Linq; +using VOL.Core.Utilities; +using System.Linq.Expressions; +using VOL.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VOL.Data.IRepositories; +using VOL.Core.DBManager; +using SkiaSharp; + +namespace VOL.Data.Services +{ + public partial class Data_ProduceService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IData_ProduceRepository _repository;//访问数据库 + + private WebResponseContent webResponse = new WebResponseContent(); + + [ActivatorUtilitiesConstructor] + public Data_ProduceService( + IData_ProduceRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + base.Init(dbRepository); + } + + + public Data_Produce getLastProduceData(Func query) { + //_repository.DbContext.Set().FirstOrDefault(query); + Data_Produce? data_Produce = _repository.DbContext.Set().Where(query) + .OrderByDescending(x => x.CreateDate).FirstOrDefault(); + return data_Produce; + } + + + public Dictionary produceDataGroupByWeekDays() { + List configList = Data_ConfigService.Instance.getConfigList(); + if (configList == null) { + return new(); + } + var dapper = DBServerProvider.SqlDapper; + string sql = @"SELECT + c.datelist AS date, + d.config_id AS configId, + COALESCE ( MAX( turnout_all ), 0 ) AS currentTurnout + FROM + data_calendar c + LEFT JOIN data_produce d ON c.datelist = DATE( d.CreateDate ) + AND d.com_status = @comStatus + WHERE + c.datelist BETWEEN CURDATE() - INTERVAL @Redays DAY + AND CURDATE() + GROUP BY + c.datelist, + d.config_id"; + int comStatus = 5; + int Redays = 6; + // 原生sql动态查询 + var result = dapper.QueryDynamicList(sql, new { comStatus, Redays }); + var resultMap = new Dictionary(); + var datelist = result.Select(p => p.date.ToString("yyyy-MM-dd")).Distinct().ToList(); + var configMap = new Dictionary>(); + foreach (var config in configList) + { + var data = new List(); + foreach (var item in result) + { + //Console.WriteLine(item.currentTurnout.GetType()); Int64 + if (item.configId == null || item.configId == config.id) { + data.Add(Convert.ToInt32(item.currentTurnout)); + } + } + configMap.Add(config.id.ToString(), data); + } + resultMap.Add("datelist", datelist); + resultMap.Add("dataMap", configMap); + return resultMap; + } + + + public Dictionary workDataGroupByWeekDays(int configId, string target) + { + var dapper = DBServerProvider.SqlDapper; + string sql = @"SELECT + c.datelist AS date, + d.config_id AS configId, + COALESCE ( MAX( id ), 0 ) AS lastId + FROM + data_calendar c + LEFT JOIN data_produce d ON c.datelist = DATE( d.CreateDate ) + AND d.com_status = @comStatus + AND d.config_id = @configId + WHERE + c.datelist BETWEEN CURDATE() - INTERVAL @Redays DAY + AND CURDATE() + GROUP BY + c.datelist, + d.config_id"; + int comStatus = 5; + int Redays = 6; + var result = dapper.QueryDynamicList(sql, new { comStatus, configId, Redays }); + var datelist = result.Select(p => p.date.ToString("yyyy-MM-dd")).Distinct().ToList(); + var resultMap = new Dictionary(); + var dataMap = new Dictionary>>(); + var dataSize = datelist.Count; + // 初始化所有指标数据 + var work1_Turnouts = new List(dataSize); + var work2_Turnouts = new List(dataSize); + var work3_Turnouts = new List(dataSize); + var work1_Schedules = new List(dataSize); + var work2_Schedules = new List(dataSize); + var work3_Schedules = new List(dataSize); + var work1_Yields = new List(dataSize); + var work2_Yields = new List(dataSize); + var work3_Yields = new List(dataSize); + foreach (var item in result) + { + int a = 0, b = 0, c = 0, aa = 0, bb = 0, cc = 0, aaa = 0, bbb = 0, ccc = 0; + var data = new List(); + if (item.configId != null && item.lastId != 0) + { + sql = @"SELECT * from data_produce where id = @lastId"; + var row = dapper.QueryDynamicFirst(sql, new { item.lastId }); + if (row != null) + { + a = row.turnout_1 ?? 0; + b = row.turnout_2 ?? 0; + c = row.turnout_3 ?? 0; + aa = row.schedule_1 != null ? Convert.ToInt32(row.schedule_1 * 100) : 0; + bb = row.schedule_2 != null ? Convert.ToInt32(row.schedule_2 * 100) : 0; + cc = row.schedule_3 != null ? Convert.ToInt32(row.schedule_3 * 100) : 0; + aaa = row.yield_1 != null ? Convert.ToInt32(row.yield_1 * 100) : 0; + bbb = row.yield_2 != null ? Convert.ToInt32(row.yield_2 * 100) : 0; + ccc = row.yield_3 != null ? Convert.ToInt32(row.yield_3 * 100) : 0; + } + } + work1_Turnouts.Add(a); + work2_Turnouts.Add(b); + work3_Turnouts.Add(c); + work1_Schedules.Add(aa); + work2_Schedules.Add(bb); + work3_Schedules.Add(cc); + work1_Yields.Add(aaa); + work2_Yields.Add(bbb); + work3_Yields.Add(ccc); + } + dataMap.Add("turnout", new List> { work1_Turnouts , work2_Turnouts, work3_Turnouts }); + dataMap.Add("schedule", new List> { work1_Schedules, work2_Schedules, work3_Schedules }); + dataMap.Add("yield", new List> { work1_Yields, work2_Yields, work3_Yields }); + resultMap.Add("datelist", datelist); + resultMap.Add("dataMap", dataMap); + return resultMap; + } + + + // 重写Add方法 + public override WebResponseContent Add(SaveModel saveDataModel) + { + Dictionary mapData = saveDataModel.MainData; + mapData.TryGetValue("CreateID", out var userId); + mapData.TryGetValue("CreateDate", out var CreateDate); + AddOnExecuting = (Data_Produce data_Produce, object list) => + { + if (userId != null) + { + data_Produce.CreateID = (int?)userId; + } + if (CreateDate != null) + { + data_Produce.CreateDate = (DateTime?)CreateDate; + } + return webResponse.OK(); + }; + return base.Add(saveDataModel); + } + } +} diff --git a/vol-net6/VOL.Data/VOL.Data.csproj b/vol-net6/VOL.Data/VOL.Data.csproj new file mode 100644 index 0000000..9dad5eb --- /dev/null +++ b/vol-net6/VOL.Data/VOL.Data.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + + + diff --git a/vol-net6/VOL.Entity/DomainModels/Core/PageGridData.cs b/vol-net6/VOL.Entity/DomainModels/Core/PageGridData.cs index 4765eb8..8b616b6 100644 --- a/vol-net6/VOL.Entity/DomainModels/Core/PageGridData.cs +++ b/vol-net6/VOL.Entity/DomainModels/Core/PageGridData.cs @@ -13,6 +13,9 @@ namespace VOL.Entity.DomainModels public string msg { get; set; } public int total { get; set; } public List rows { get; set; } + /// + /// 统计求和数据 + /// public object summary { get; set; } /// /// 可以在返回前,再返回一些额外的数据,比如返回其他表的信息,前台找到查询后的方法取出来 diff --git a/vol-net6/VOL.Entity/DomainModels/config/Data_Config.cs b/vol-net6/VOL.Entity/DomainModels/config/Data_Config.cs new file mode 100644 index 0000000..efcb8e3 --- /dev/null +++ b/vol-net6/VOL.Entity/DomainModels/config/Data_Config.cs @@ -0,0 +1,116 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果数据库字段发生变化,请在代码生器重新生成此Model + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Entity.SystemModels; + +namespace VOL.Entity.DomainModels +{ + [Entity(TableCnName = "设备配置",TableName = "Data_Config")] + public partial class Data_Config:BaseEntity + { + /// + /// + /// + [Key] + [Display(Name ="id")] + [Column(TypeName="int")] + [Editable(true)] + [Required(AllowEmptyStrings=false)] + public int id { get; set; } + + /// + ///设备名称 + /// + [Display(Name ="设备名称")] + [MaxLength(255)] + [Column(TypeName="nvarchar(255)")] + [Editable(true)] + public string name { get; set; } + + /// + ///机床类型 + /// + [Display(Name ="机床类型")] + [Column(TypeName="short")] + [Editable(true)] + public short? type { get; set; } + + /// + ///设备IP + /// + [Display(Name ="设备IP")] + [MaxLength(255)] + [Column(TypeName="nvarchar(255)")] + [Editable(true)] + public string device_ip { get; set; } + + /// + ///通讯IP + /// + [Display(Name ="通讯IP")] + [MaxLength(60)] + [Column(TypeName="nvarchar(60)")] + [Editable(true)] + public string com_ip { get; set; } + + /// + /// + /// + [Display(Name ="CreateID")] + [Column(TypeName="int")] + [Editable(true)] + public int? CreateID { get; set; } + + /// + /// + /// + [Display(Name ="Creator")] + [MaxLength(255)] + [Column(TypeName="nvarchar(255)")] + [Editable(true)] + public string Creator { get; set; } + + /// + ///创建时间 + /// + [Display(Name ="创建时间")] + [Column(TypeName="datetime")] + [Editable(true)] + public DateTime? CreateDate { get; set; } + + /// + /// + /// + [Display(Name ="ModifyID")] + [Column(TypeName="int")] + [Editable(true)] + public int? ModifyID { get; set; } + + /// + /// + /// + [Display(Name ="Modifier")] + [MaxLength(255)] + [Column(TypeName="nvarchar(255)")] + [Editable(true)] + public string Modifier { get; set; } + + /// + /// + /// + [Display(Name ="ModifyDate")] + [Column(TypeName="datetime")] + [Editable(true)] + public DateTime? ModifyDate { get; set; } + + + } +} \ No newline at end of file diff --git a/vol-net6/VOL.Entity/DomainModels/config/partial/Data_Config.cs b/vol-net6/VOL.Entity/DomainModels/config/partial/Data_Config.cs new file mode 100644 index 0000000..49154bd --- /dev/null +++ b/vol-net6/VOL.Entity/DomainModels/config/partial/Data_Config.cs @@ -0,0 +1,37 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果数据库字段发生变化,请在代码生器重新生成此Model + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Entity.SystemModels; + +namespace VOL.Entity.DomainModels +{ + + public partial class Data_Config + { + //此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常 + /// + ///通讯状态 + /// + [Display(Name = "通讯状态")] + [Column(TypeName = "short")] + [Editable(true), NotMapped] + public short? com_status { get; set; } + + /// + ///运行状态 + /// + [Display(Name = "运行状态")] + [Column(TypeName = "short")] + [Editable(true), NotMapped] + public short? state { get; set; } + + } +} \ No newline at end of file diff --git a/vol-net6/VOL.Entity/DomainModels/machine/Data_Machine.cs b/vol-net6/VOL.Entity/DomainModels/machine/Data_Machine.cs new file mode 100644 index 0000000..e0290f5 --- /dev/null +++ b/vol-net6/VOL.Entity/DomainModels/machine/Data_Machine.cs @@ -0,0 +1,225 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果数据库字段发生变化,请在代码生器重新生成此Model + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Entity.SystemModels; + +namespace VOL.Entity.DomainModels +{ + [Entity(TableCnName = "机床数据",TableName = "Data_Machine")] + public partial class Data_Machine:BaseEntity + { + /// + /// + /// + [Key] + [Display(Name ="id")] + [Column(TypeName="int")] + [Editable(true)] + [Required(AllowEmptyStrings=false)] + public int id { get; set; } + + /// + ///设备信息 + /// + [Display(Name ="设备信息")] + [Column(TypeName="int")] + [Editable(true)] + [Required(AllowEmptyStrings=false)] + public int config_id { get; set; } + + /// + ///通讯状态 + /// + [Display(Name ="通讯状态")] + [Column(TypeName="short")] + [Editable(true)] + public short? com_status { get; set; } + + /// + ///运行模式(西门子) + /// + [Display(Name ="运行模式(西门子)")] + [Column(TypeName="short")] + [Editable(true)] + public short? smode { get; set; } + + /// + ///运行模式(广数) + /// + [Display(Name ="运行模式(广数)")] + [Column(TypeName="short")] + [Editable(true)] + public short? gmode { get; set; } + + /// + ///加工程序号 + /// + [Display(Name ="加工程序号")] + [MaxLength(60)] + [Column(TypeName="nvarchar(60)")] + [Editable(true)] + public string run_program_no { get; set; } + + /// + ///运行状态 + /// + [Display(Name ="运行状态")] + [Column(TypeName="short")] + [Editable(true)] + public short? state { get; set; } + + /// + ///电机温度 + /// + [Display(Name ="电机温度")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? temperature { get; set; } + + /// + ///母线电压 + /// + [Display(Name ="母线电压")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? potential { get; set; } + + /// + ///实际电流 + /// + [Display(Name ="实际电流")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? current { get; set; } + + /// + ///加工数 + /// + [Display(Name ="加工数")] + [Column(TypeName="bigint")] + [Editable(true)] + public long? quantity { get; set; } + + /// + ///主轴倍率 + /// + [Display(Name ="主轴倍率")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? main_rate { get; set; } + + /// + ///进给倍率 + /// + [Display(Name ="进给倍率")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? feed_rate { get; set; } + + /// + ///切削倍率 + /// + [Display(Name ="切削倍率")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? cut_rate { get; set; } + + /// + ///开机时间 + /// + [Display(Name ="开机时间")] + [Column(TypeName="bigint")] + [Editable(true)] + public long? on_time { get; set; } + + /// + ///运行时间 + /// + [Display(Name ="运行时间")] + [Column(TypeName="bigint")] + [Editable(true)] + public long? run_time { get; set; } + + /// + ///累计运行时长 + /// + [Display(Name ="累计运行时长")] + [Column(TypeName="bigint")] + [Editable(true)] + public long? run_time_total { get; set; } + + /// + ///累计加工数 + /// + [Display(Name ="累计加工数")] + [Column(TypeName="bigint")] + [Editable(true)] + public long? quantity_total { get; set; } + + /// + /// + /// + [Display(Name ="CreateID")] + [Column(TypeName="int")] + [Editable(true)] + public int? CreateID { get; set; } + + /// + /// + /// + [Display(Name ="Creator")] + [MaxLength(255)] + [Column(TypeName="nvarchar(255)")] + [Editable(true)] + public string Creator { get; set; } + + /// + ///记录时间 + /// + [Display(Name ="记录时间")] + [Column(TypeName="datetime")] + [Editable(true)] + public DateTime? CreateDate { get; set; } + + /// + /// + /// + [Display(Name ="ModifyID")] + [Column(TypeName="int")] + [Editable(true)] + public int? ModifyID { get; set; } + + /// + /// + /// + [Display(Name ="Modifier")] + [MaxLength(255)] + [Column(TypeName="nvarchar(255)")] + [Editable(true)] + public string Modifier { get; set; } + + /// + ///更新时间 + /// + [Display(Name ="更新时间")] + [Column(TypeName="datetime")] + [Editable(true)] + public DateTime? ModifyDate { get; set; } + + + } +} \ No newline at end of file diff --git a/vol-net6/VOL.Entity/DomainModels/machine/partial/Data_Machine.cs b/vol-net6/VOL.Entity/DomainModels/machine/partial/Data_Machine.cs new file mode 100644 index 0000000..05c11b9 --- /dev/null +++ b/vol-net6/VOL.Entity/DomainModels/machine/partial/Data_Machine.cs @@ -0,0 +1,72 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果数据库字段发生变化,请在代码生器重新生成此Model + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Entity.SystemModels; + +namespace VOL.Entity.DomainModels +{ + + public partial class Data_Machine + { + //此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常 + [Display(Name = "设备名称")] + [MaxLength(255)] + [Column(TypeName = "nvarchar(255)")] + [Editable(true), NotMapped] + public string name { get; set; } + + /// + ///通讯IP + /// + [Display(Name = "通讯IP")] + [MaxLength(60)] + [Column(TypeName = "nvarchar(60)")] + [Editable(true), NotMapped] + public string com_ip { get; set; } + + + /// + ///累计运行时长 + /// + [Display(Name = "当班产量")] + [Column(TypeName = "int")] + [Editable(true), NotMapped] + public int? currentTurnout { get; set; } + + + /// + ///累计加工数 + /// + [Display(Name = "累计加工数")] + [Column(TypeName = "bigint")] + [Editable(true), NotMapped] + public long? totalQuantity { get; set; } + + + /// + ///累计运行时长 + /// + [Display(Name = "累计运行时长")] + [Column(TypeName = "bigint")] + [Editable(true), NotMapped] + public long? totalRuntime { get; set; } + + + /// + ///设备综合效率 + /// + [Display(Name = "设备综合效率")] + [DisplayFormat(DataFormatString = "10,2")] + [Column(TypeName = "decimal")] + [Editable(true), NotMapped] + public decimal? OEE { get; set; } + } +} \ No newline at end of file diff --git a/vol-net6/VOL.Entity/DomainModels/produce/Data_Produce.cs b/vol-net6/VOL.Entity/DomainModels/produce/Data_Produce.cs new file mode 100644 index 0000000..b243b8e --- /dev/null +++ b/vol-net6/VOL.Entity/DomainModels/produce/Data_Produce.cs @@ -0,0 +1,217 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果数据库字段发生变化,请在代码生器重新生成此Model + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Entity.SystemModels; + +namespace VOL.Entity.DomainModels +{ + [Entity(TableCnName = "生产数据",TableName = "Data_Produce")] + public partial class Data_Produce:BaseEntity + { + /// + ///ID + /// + [Key] + [Display(Name ="ID")] + [Column(TypeName="int")] + [Editable(true)] + [Required(AllowEmptyStrings=false)] + public int id { get; set; } + + /// + ///设备信息 + /// + [Display(Name ="设备信息")] + [Column(TypeName="int")] + [Editable(true)] + [Required(AllowEmptyStrings=false)] + public int config_id { get; set; } + + /// + ///程序编号 + /// + [Display(Name ="程序编号")] + [Column(TypeName="int")] + [Editable(true)] + public int? program_no { get; set; } + + /// + ///通讯状态 + /// + [Display(Name ="通讯状态")] + [Column(TypeName="short")] + [Editable(true)] + public short? com_status { get; set; } + + /// + ///运行时长 + /// + [Display(Name ="运行时长")] + [Column(TypeName="int")] + [Editable(true)] + public int? run_time { get; set; } + + /// + ///运行状态 + /// + [Display(Name ="运行状态")] + [Column(TypeName="short")] + [Editable(true)] + public short? status { get; set; } + + /// + ///当班产量 + /// + [Display(Name ="当班产量")] + [Column(TypeName="int")] + [Editable(true)] + public int? turnout_all { get; set; } + + /// + ///工单 1 产量 + /// + [Display(Name ="工单 1 产量")] + [Column(TypeName="int")] + [Editable(true)] + public int? turnout_1 { get; set; } + + /// + ///工单 2 产量 + /// + [Display(Name ="工单 2 产量")] + [Column(TypeName="int")] + [Editable(true)] + public int? turnout_2 { get; set; } + + /// + ///工单 3 产量 + /// + [Display(Name ="工单 3 产量")] + [Column(TypeName="int")] + [Editable(true)] + public int? turnout_3 { get; set; } + + /// + ///工单1任务进度 + /// + [Display(Name ="工单1任务进度")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? schedule_1 { get; set; } + + /// + ///工单2任务进度 + /// + [Display(Name ="工单2任务进度")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? schedule_2 { get; set; } + + /// + ///工单3任务进度 + /// + [Display(Name ="工单3任务进度")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? schedule_3 { get; set; } + + /// + ///工单1良品率 + /// + [Display(Name ="工单1良品率")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? yield_1 { get; set; } + + /// + ///工单2良品率 + /// + [Display(Name ="工单2良品率")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? yield_2 { get; set; } + + /// + ///工单3良品率 + /// + [Display(Name ="工单3良品率")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? yield_3 { get; set; } + + /// + ///设备综合效率 + /// + [Display(Name ="设备综合效率")] + [DisplayFormat(DataFormatString="10,2")] + [Column(TypeName="decimal")] + [Editable(true)] + public decimal? oee { get; set; } + + /// + /// + /// + [Display(Name ="CreateID")] + [Column(TypeName="int")] + [Editable(true)] + public int? CreateID { get; set; } + + /// + /// + /// + [Display(Name ="Creator")] + [MaxLength(255)] + [Column(TypeName="nvarchar(255)")] + [Editable(true)] + public string Creator { get; set; } + + /// + ///记录时间 + /// + [Display(Name ="记录时间")] + [Column(TypeName="datetime")] + [Editable(true)] + public DateTime? CreateDate { get; set; } + + /// + /// + /// + [Display(Name ="ModifyID")] + [Column(TypeName="int")] + [Editable(true)] + public int? ModifyID { get; set; } + + /// + /// + /// + [Display(Name ="Modifier")] + [MaxLength(255)] + [Column(TypeName="nvarchar(255)")] + [Editable(true)] + public string Modifier { get; set; } + + /// + ///更新时间 + /// + [Display(Name ="更新时间")] + [Column(TypeName="datetime")] + [Editable(true)] + public DateTime? ModifyDate { get; set; } + + + } +} \ No newline at end of file diff --git a/vol-net6/VOL.Entity/DomainModels/produce/partial/Data_Produce.cs b/vol-net6/VOL.Entity/DomainModels/produce/partial/Data_Produce.cs new file mode 100644 index 0000000..0e05f34 --- /dev/null +++ b/vol-net6/VOL.Entity/DomainModels/produce/partial/Data_Produce.cs @@ -0,0 +1,28 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果数据库字段发生变化,请在代码生器重新生成此Model + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Entity.SystemModels; + +namespace VOL.Entity.DomainModels +{ + + public partial class Data_Produce + { + //此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常 + /// + /// 日期 + /// + [Display(Name = "日期")] + [Column(TypeName = "date")] + [Editable(true), NotMapped] + public DateOnly? datelist { get; set; } + } +} \ No newline at end of file diff --git a/vol-net6/VOL.Entity/MappingConfiguration/config/Data_ConfigMapConfig.cs b/vol-net6/VOL.Entity/MappingConfiguration/config/Data_ConfigMapConfig.cs new file mode 100644 index 0000000..c109456 --- /dev/null +++ b/vol-net6/VOL.Entity/MappingConfiguration/config/Data_ConfigMapConfig.cs @@ -0,0 +1,16 @@ +using VOL.Entity.MappingConfiguration; +using VOL.Entity.DomainModels; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VOL.Entity.MappingConfiguration +{ + public class Data_ConfigMapConfig : EntityMappingConfiguration + { + public override void Map(EntityTypeBuilder + builderTable) + { + //b.Property(x => x.StorageName).HasMaxLength(45); + } + } +} + diff --git a/vol-net6/VOL.Entity/MappingConfiguration/machine/Data_MachineMapConfig.cs b/vol-net6/VOL.Entity/MappingConfiguration/machine/Data_MachineMapConfig.cs new file mode 100644 index 0000000..05893a1 --- /dev/null +++ b/vol-net6/VOL.Entity/MappingConfiguration/machine/Data_MachineMapConfig.cs @@ -0,0 +1,16 @@ +using VOL.Entity.MappingConfiguration; +using VOL.Entity.DomainModels; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VOL.Entity.MappingConfiguration +{ + public class Data_MachineMapConfig : EntityMappingConfiguration + { + public override void Map(EntityTypeBuilder + builderTable) + { + //b.Property(x => x.StorageName).HasMaxLength(45); + } + } +} + diff --git a/vol-net6/VOL.Entity/MappingConfiguration/produce/Data_ProduceMapConfig.cs b/vol-net6/VOL.Entity/MappingConfiguration/produce/Data_ProduceMapConfig.cs new file mode 100644 index 0000000..93629b0 --- /dev/null +++ b/vol-net6/VOL.Entity/MappingConfiguration/produce/Data_ProduceMapConfig.cs @@ -0,0 +1,16 @@ +using VOL.Entity.MappingConfiguration; +using VOL.Entity.DomainModels; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace VOL.Entity.MappingConfiguration +{ + public class Data_ProduceMapConfig : EntityMappingConfiguration + { + public override void Map(EntityTypeBuilder + builderTable) + { + //b.Property(x => x.StorageName).HasMaxLength(45); + } + } +} + diff --git a/vol-net6/VOL.System/IServices/System/Partial/ISys_DepartmentService.cs b/vol-net6/VOL.System/IServices/System/Partial/ISys_DepartmentService.cs index cdf6107..6831766 100644 --- a/vol-net6/VOL.System/IServices/System/Partial/ISys_DepartmentService.cs +++ b/vol-net6/VOL.System/IServices/System/Partial/ISys_DepartmentService.cs @@ -5,9 +5,12 @@ using VOL.Core.BaseProvider; using VOL.Entity.DomainModels; using VOL.Core.Utilities; using System.Linq.Expressions; +using System.Threading.Tasks; namespace VOL.System.IServices { public partial interface ISys_DepartmentService { + // 获取用户关联根部门 + Task GetUserDepartment(int userId); } } diff --git a/vol-net6/VOL.System/Services/System/Partial/Sys_DepartmentService.cs b/vol-net6/VOL.System/Services/System/Partial/Sys_DepartmentService.cs index 8083de3..a350de3 100644 --- a/vol-net6/VOL.System/Services/System/Partial/Sys_DepartmentService.cs +++ b/vol-net6/VOL.System/Services/System/Partial/Sys_DepartmentService.cs @@ -20,6 +20,8 @@ using VOL.System.IRepositories; using System.Collections.Generic; using VOL.Core.ManageUser; using VOL.Core.UserManager; +using VOL.Core.DBManager; +using System.Threading.Tasks; namespace VOL.System.Services { @@ -96,6 +98,22 @@ namespace VOL.System.Services { return base.Del(keys, delList).Reload(); } + + + public async Task GetUserDepartment(int userId) { + var dapper = DBServerProvider.SqlDapper; + string sql = @"SELECT + d.DepartmentId, + d.DepartmentCode, + d.DepartmentName + FROM + sys_department AS d + LEFT JOIN sys_userdepartment AS ud ON ud.DepartmentId = d.DepartmentId + WHERE + ud.UserId = @userId + AND d.ParentId IS NULL;"; + return await dapper.QueryFirstAsync(sql, new { userId }); ; + } } } diff --git a/vol-net6/VOL.WebApi/Controllers/Data/DataApiController.cs b/vol-net6/VOL.WebApi/Controllers/Data/DataApiController.cs new file mode 100644 index 0000000..679d804 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/DataApiController.cs @@ -0,0 +1,81 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using System; +using VOL.Core.Filters; +using VOL.Data.IServices.modbus; +using VOL.Data.Services.modbus; +using Microsoft.Extensions.DependencyInjection; +using VOL.WebApi.Utils; +using VOL.Entity.DomainModels; +using System.Collections.Generic; +using Confluent.Kafka; +using VOL.Data.IServices; +using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; +using Newtonsoft.Json; + +namespace VOL.WebApi.Controllers.Data +{ + /// + /// 数据采集API类 + /// + [Route("api/Data_Screen")] + [JWTAuthorize, ApiController, AllowAnonymous] + public class DataApiController : Controller + { + private IData_ConfigService _configService; + private IData_MachineService _machineService; + private IData_ProduceService _produceService; + + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public DataApiController( + IData_ConfigService configService, + IData_MachineService machineService, + IData_ProduceService produceService, + IHttpContextAccessor httpContextAccessor + ) + { + _configService = configService; + _machineService = machineService; + _produceService = produceService; + _httpContextAccessor = httpContextAccessor; + } + + + // 获取设备配置数据 + [HttpPost, Route("GetDeviceConfig")] + public IActionResult getDeviceConfig([FromBody] PageDataOptions loadData) + { + return Json(_configService.GetPageData(loadData)); + } + + // 获取机床数据 + [HttpPost, Route("GetMachineData")] + public IActionResult getMachineData([FromBody] Data_Config config) // application/json模式 + { + //Console.WriteLine(JsonConvert.SerializeObject(config)); + return Json(_machineService.GetMachineData()); + } + + + // 获取近一周每日加工量数据 + [HttpPost, Route("GetTurnOutByWeekDays")] + public IActionResult getTurnOutByWeekDays() + { + return Json(_produceService.produceDataGroupByWeekDays()); + } + + // 获取近一周工单指标数据 + [HttpPost, Route("GetWorkDataByWeekDays")] + public IActionResult GetWorkDataByWeekDays(string target, int configId) // x-www-form表单模式 + { + //return Json(new { target, configId }); + return Json(_produceService.workDataGroupByWeekDays(configId, target)); + } + + + + } +} diff --git a/vol-net6/VOL.WebApi/Controllers/Data/DataTestController.cs b/vol-net6/VOL.WebApi/Controllers/Data/DataTestController.cs new file mode 100644 index 0000000..74b42a6 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/DataTestController.cs @@ -0,0 +1,350 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using System; +using VOL.Core.Filters; +using VOL.Data.IServices.modbus; +using VOL.Data.Services.modbus; +using Microsoft.Extensions.DependencyInjection; +using VOL.WebApi.Utils; +using VOL.Entity.DomainModels; +using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; + +namespace VOL.WebApi.Controllers.Data +{ + /// + /// 数据采集API类 + /// + [Route("api/Data_Test")] + [AllowAnonymous] + public class DataTestController : Controller + { + private static ModbusTcpService _service; // 静态字段 + + private readonly IHttpContextAccessor _httpContextAccessor; + + private readonly IDataProcessing _dataService; // 业务处理 + + + [ActivatorUtilitiesConstructor] + public DataTestController( + //ModbusTcpService service, // ModbusTcpService为有参构造,暂时无法注入 + IDataProcessing dataService, + IHttpContextAccessor httpContextAccessor + ) + { + //_service = service; + _dataService = dataService; + _httpContextAccessor = httpContextAccessor; + } + + // 静态构造器 类实例化前调用,且只调用一次 + static DataTestController() + { + try + { + //_service = new ModbusTcpService("127.0.0.1", 502); + _service = new ModbusTcpService("192.168.0.99", 502); + Console.WriteLine("master modbus tcp created..."); + } + catch (Exception) + { + Console.WriteLine("master modbus tcp connect failed!"); + } + } + + + /// + /// 测试定时接口 + /// + /// IActionResult + [ApiTask] + [HttpGet, HttpPost, Route("test")] + public IActionResult Test() + { + //Logger.Info("log info test..."); + //Logger.Error("log info error..."); + //Data_Device data_Device = new Data_Device(); + //bool result = _dataService.saveDeviceData(data_Device, out string message); + //Console.WriteLine(message); + //Data_Produce data_Produce = new Data_Produce(); + //bool result2 = _dataService.saveProduceData(data_Produce, out string message1); + //Console.WriteLine(message1); + _service = new ModbusTcpService("192.168.0.99", 502); + _service.writeData(1,0,(short)1); + _service.writeData(1,0,1); + _service.writeData(1,0,1F); + _service.writeData(1,0,"1234"); + + return Content(DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss")); + } + + + + /// + /// 测试采集接口 + /// + /// IActionResult + //[ApiTask] + [HttpGet, HttpPost, Route("getData")] + public IActionResult Collection() + { + Console.WriteLine(_service); + bool isConnected = _service == null ? false : _service.isConnected; + if (!isConnected) + { + try + { + _service.disConnent(); + _service = new ModbusTcpService("127.0.0.1", 502); + Console.WriteLine("master modbus tcp reconnect..."); + } + catch (Exception) + { + Console.WriteLine("master modbus tcp reconnect failed!"); + } + isConnected = _service == null ? false : _service.isConnected; + if (!isConnected) + { + return Content("master modbus connect failed!"); + } + } + try { + // 读Int16 + ushort[] us1 = _service.ReadHoldingRegisters(1, 9, 1); + short v = DataConvertUtil.GetShort(us1, 0); + Console.WriteLine("Short Data:" + v); + // 读Float + ushort[] us2 = _service.ReadHoldingRegisters(1, 1, 2); + float f = DataConvertUtil.GetReal(us2, 0); + Console.WriteLine("Real Data:" + f); + // 读Bool + ushort[] us3 = _service.ReadHoldingRegisters(1, 11, 1); + bool[] bs = DataConvertUtil.GetBools(us3,0,1); + Console.WriteLine("Bools Data:" + String.Join(",",bs)); + + // 写String + ushort[] src = new ushort[6]; + DataConvertUtil.SetString(src, 0, "你好世界"); // UTF8 1个中文字符 = 3Byte + _service.WriteMultipleRegisters(1, 30, src); + + // 读String + ushort[] target = _service.ReadHoldingRegisters(1, 30, 6); + string str = DataConvertUtil.GetString(target,0,6); + Console.WriteLine("String Data:" + str.ToString()); + } catch (Exception ex) { + Console.WriteLine(ex.Message); + _service.disConnent(); + return Content("read data error!"); + } + return Content("ok!"); + } + + + + + + [HttpGet, HttpPost, Route("readTest")] + public IActionResult Test01() + { + _service = new ModbusTcpService("192.168.0.99", 502); + if (_service.isConnected) + { + //Console.WriteLine("=========read0x========="); + //bool[] data0x = _service.ReadCoils(1, 0, 5); // 0x + ////bool[] bools = { true, false }; + //Array.ForEach(data0x, Console.WriteLine); + //Console.WriteLine("=========read0x========="); + + //Console.WriteLine("=========read1x========="); + //bool[] data1x = _service.ReadInputs(1, 0, 5); + //Array.ForEach(data1x, Console.WriteLine); + //Console.WriteLine("=========read1x========="); + // 读取从0开始,文档上地址从1开始的,地址需要减1 + Console.WriteLine("=========read4x========="); + // int16 + ushort[] src0 = new ushort[1]; + DataConvertUtil.SetShort(src0, 0, 2); + _service.WriteMultipleRegisters(1, 6429, src0); + + ushort[] data4xs_int16 = _service.ReadHoldingRegisters(1, 6429, 1); // 运行状态 + short val = DataConvertUtil.GetShort(data4xs_int16, 0); + Console.WriteLine(val); + + // 写 float + ushort[] src1 = new ushort[2]; + DataConvertUtil.SetReal(src1, 0, 3.14F); + _service.WriteMultipleRegisters(1, 1215, src1); + + // 读 float + ushort[] data4xs_float = _service.ReadHoldingRegisters(1, 1215, 2); // 加工数 + float fval = DataConvertUtil.GetReal(data4xs_float, 0); + Console.WriteLine(fval); + + //// string + //ushort[] data_strlen = _service.ReadHoldingRegisters(1, 6689, 1); + //short strlen = DataConvertUtil.GetShort(data_strlen, 0); + //Console.WriteLine(strlen); + + //// 6690程序号不可写, 为双引号 asill码为34 + //ushort[] src2 = new ushort[6]; + //DataConvertUtil.SetString(src1, 0, "123456"); + //_service.WriteMultipleRegisters(1, 6691, src2); + + //ushort[] data4xs_str = _service.ReadHoldingRegisters(1, 6690, 52); // 程序号 + //string str = DataConvertUtil.GetString(data4xs_str, 0, 52); + //Console.WriteLine(str); + + Console.WriteLine("=========read4x========="); + //ushort[] data4xs_float = _service.ReadHoldingRegisters(1, 1200, 2); // 刀具长度补偿编号 + //float fval = DataConvertUtil.GetReal(data4xs_float, 0); + //Console.WriteLine(fval); + + //ushort[] data4xs_int32 = _service.ReadHoldingRegisters(1, 1, 2); // 电机温度 + //int vval = DataConvertUtil.GetInt(data4xs_int32, 0); + //Console.WriteLine(vval); + + //ushort[] data4xs_int64 = _service.ReadHoldingRegisters(1, 4, 4); // 运行模式 + //long vvval = DataConvertUtil.GetLong(data4xs_int64, 0); + //Console.WriteLine(vvval); + //Console.WriteLine("=========read4x========="); + + //Console.WriteLine("=========read3x========="); + //ushort[] data3xs = _service.ReadInputRegisters(1, 4, 2); + //uint[] data3x = data3xs.Select(x => (uint)x).ToArray(); + //Array.ForEach(data3x, Console.WriteLine); + //Console.WriteLine("=========read3x========="); + + _service.disConnent(); + //List data = new(); + //data.Add(data0x); + //data.Add(data1x); + //data.Add(data3x); + //data.Add(data4x); + return Content("read ok"); + } + else + { + return Content("Modbus 从站连接失败!"); + } + } + + + + [HttpGet, HttpPost, Route("unitTestSem")] + public IActionResult Test02() + { + _service = new ModbusTcpService("192.168.1.99", 502); + if (_service.isConnected) + { + // 读取从0开始,文档上地址从1开始的,地址需要减1 + Console.WriteLine("=========read4x========="); + + // 写数据 + //_service.writeData(1, 6429, 1); + + //_service.writeData(1, 1173, 256); + + //_service.writeData(1, 1215, 6.28F); + + //_service.writeData(1, 6691, "Hello World!!"); + + + // 读数据 + //short s = _service.readData(1, 6429, "int16"); // 运行模式 + //float f = _service.readData(1, 1215, "single"); // 加工数 + //int i = _service.readData(1, 1173, "int32"); + //string str = _service.readData(1, 6690, "string", 52); + + //Console.WriteLine(s); + //Console.WriteLine(f); + //Console.WriteLine(i); + //Console.WriteLine(str); + + //short s = _service.readData(1, 6429, "int16"); // 运行模式 + //float f1 = _service.readData(1, 1231, "single"); // 主轴倍率 + //float f2 = _service.readData(1, 1215, "single"); // 加工数 + + //Console.WriteLine(s); + //Console.WriteLine(f1); + //Console.WriteLine(f2); + //Console.WriteLine(str); + short s = _service.readData(1, 6430, "int16"); // 通讯状态 + Console.WriteLine(s); + + Console.WriteLine("=========read4x========="); + + _service.disConnent(); + + return Content("read ok"); + } + else + { + return Content("Modbus 从站连接失败!"); + } + } + + + [HttpGet, HttpPost, Route("unitTestCnc")] + public IActionResult Test03() + { + _service = new ModbusTcpService("192.168.1.100", 502); + //_service = new ModbusTcpService("192.168.1.99", 502); + if (_service.isConnected) + { + // 读取从0开始,文档上地址从1开始的,地址需要减1 + Console.WriteLine("=========read4x========="); + + // 写数据 + //_service.writeData(1, 6424, 2); + + //_service.writeData(1, 1309, 65537); + + //_service.writeData(1, 1307, 5.68F); + + //_service.writeData(1, 6640, "hehe"); + + + // 读数据 + //short s = _service.readData(1, 6424, "int16"); + + //int i = _service.readData(1, 1309, "int32"); + + //float f = _service.readData(1, 1307, "single"); + + //string str = _service.readData(1, 6640, "string", 2); // 一个寄存器地址存放两个字符 + + //Console.WriteLine(s); + //Console.WriteLine(i); + //Console.WriteLine(f); + //Console.WriteLine(str); + //_service.writeData(1, 1307, 120F); + //_service.writeData(1, 1299, 19912F); + //_service.writeData(1, 6424, 2); + //_service.writeData(1, 6402, 25); + + //Console.WriteLine(_service.readData(1, 1307, "single")); // 加工数量 + //Console.WriteLine(_service.readData(1, 1299, "single")); // 切削时间 + //Console.WriteLine(_service.readData(1, 6424, "int16")); // 运行模式 + //Console.WriteLine(_service.readData(1, 6402, "int16")); // 快速倍率 + //Console.WriteLine(_service.readData(1, 6425, "int16")); // 轴状态 + + Console.WriteLine(_service.readData(1, 6429, "int16")); + Console.WriteLine(_service.readData(1, 6430, "int16")); + Console.WriteLine(_service.readData(1, 6431, "int16")); + + + Console.WriteLine("=========read4x========="); + + _service.disConnent(); + + return Content("read ok"); + } + else + { + return Content("Modbus 从站连接失败!"); + } + } + + } +} diff --git a/vol-net6/VOL.WebApi/Controllers/Data/Data_ConfigController.cs b/vol-net6/VOL.WebApi/Controllers/Data/Data_ConfigController.cs new file mode 100644 index 0000000..63c63f8 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/Data_ConfigController.cs @@ -0,0 +1,21 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果要增加方法请在当前目录下Partial文件夹Data_ConfigController编写 + */ +using Microsoft.AspNetCore.Mvc; +using VOL.Core.Controllers.Basic; +using VOL.Entity.AttributeManager; +using VOL.Data.IServices; +namespace VOL.Data.Controllers +{ + [Route("api/Data_Config")] + [PermissionTable(Name = "Data_Config")] + public partial class Data_ConfigController : ApiBaseController + { + public Data_ConfigController(IData_ConfigService service) + : base(service) + { + } + } +} + diff --git a/vol-net6/VOL.WebApi/Controllers/Data/Data_MachineController.cs b/vol-net6/VOL.WebApi/Controllers/Data/Data_MachineController.cs new file mode 100644 index 0000000..4057c71 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/Data_MachineController.cs @@ -0,0 +1,21 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果要增加方法请在当前目录下Partial文件夹Data_MachineController编写 + */ +using Microsoft.AspNetCore.Mvc; +using VOL.Core.Controllers.Basic; +using VOL.Entity.AttributeManager; +using VOL.Data.IServices; +namespace VOL.Data.Controllers +{ + [Route("api/Data_Machine")] + [PermissionTable(Name = "Data_Machine")] + public partial class Data_MachineController : ApiBaseController + { + public Data_MachineController(IData_MachineService service) + : base(service) + { + } + } +} + diff --git a/vol-net6/VOL.WebApi/Controllers/Data/Data_ProduceController.cs b/vol-net6/VOL.WebApi/Controllers/Data/Data_ProduceController.cs new file mode 100644 index 0000000..59af1b0 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/Data_ProduceController.cs @@ -0,0 +1,21 @@ +/* + *代码由框架生成,任何更改都可能导致被代码生成器覆盖 + *如果要增加方法请在当前目录下Partial文件夹Data_ProduceController编写 + */ +using Microsoft.AspNetCore.Mvc; +using VOL.Core.Controllers.Basic; +using VOL.Entity.AttributeManager; +using VOL.Data.IServices; +namespace VOL.Data.Controllers +{ + [Route("api/Data_Produce")] + [PermissionTable(Name = "Data_Produce")] + public partial class Data_ProduceController : ApiBaseController + { + public Data_ProduceController(IData_ProduceService service) + : base(service) + { + } + } +} + diff --git a/vol-net6/VOL.WebApi/Controllers/Data/NKNCaptureController.cs b/vol-net6/VOL.WebApi/Controllers/Data/NKNCaptureController.cs new file mode 100644 index 0000000..2978930 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/NKNCaptureController.cs @@ -0,0 +1,273 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using System; +using VOL.Core.Filters; +using VOL.Data.IServices.modbus; +using VOL.Data.Services.modbus; +using Microsoft.Extensions.DependencyInjection; +using VOL.WebApi.Utils; +using VOL.Entity.DomainModels; +using System.Collections.Generic; +using Microsoft.Extensions.Primitives; +using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; + +/// +// 尼可尼数据采集 +/// +namespace VOL.WebApi.Controllers.Data +{ + /// + /// 数据采集API类 + /// + [Route("api/NKNCapture")] + [AllowAnonymous] + public class NKNCaptureController : Controller + { + private ModbusTcpService _service; // 静态字段 + + private readonly IHttpContextAccessor _httpContextAccessor; + + private readonly IDataProcessing _dataService; // 业务处理 + + + [ActivatorUtilitiesConstructor] + public NKNCaptureController( + IDataProcessing dataService, + IHttpContextAccessor httpContextAccessor + ) + { + _dataService = dataService; + _httpContextAccessor = httpContextAccessor; + } + + + /// + /// 采集西门子设备 + /// + /// IActionResult + [ApiTask] + [HttpGet, HttpPost, Route("gatherSiemens")] + public IActionResult gatherSiemens() + { + var headers = _httpContextAccessor.HttpContext.Request.Headers; + headers.TryGetValue("USER-DEVICE-ID", out StringValues deviceIdStr); + if (1 == 1) { + try + { + _service = new ModbusTcpService("192.168.1.99", 502); + Console.WriteLine("siemens modbus tcp connected..."); + } + catch (Exception) + { + Console.WriteLine("siemens modbus tcp connect failed!"); + return Content("siemens modbus tcp connect failed!"); + } + if (!_service.isConnected) + { + Console.WriteLine("siemens modbus tcp disconnect!"); + return Content("siemens modbus tcp disconnect!"); + } + } + // 切削倍率 17136 1 + //_service.readData(1, 6435, "int16"); // 运行时长 分钟 + //_service.readData(1, 6436, "int16"); // 工单1产量 件 + //_service.readData(1, 6437, "int16"); // 工单2产量 件 + //_service.readData(1, 6438, "int16"); // 工单3产量 件 + //_service.readData(1, 6439, "int16"); // 当班产量 件 + //_service.readData(1, 6440, "int16"); // 运行状态 0:待机 1:运行 2:故障 + //_service.readData(1, 1315, "single"); // 工单1任务进度 % + //_service.readData(1, 1317, "single"); // 工单2任务进度 % + //_service.readData(1, 1319, "single"); // 工单3任务进度 % + //_service.readData(1, 1321, "single"); // 工单1良品率 % 真实值 *= 100 + //_service.readData(1, 1323, "single"); // 工单2良品率 % 真实值 *= 100 + //_service.readData(1, 1325, "single"); // 工单3良品率 % 真实值 *= 100 + //_service.readData(1, 1339, "single"); // 设备综合效率 % 真实值 *= 100 + + //dynamic d1 = _service.readData(1, 1201, "single"); // 电机温度 ℃ + //dynamic d2 = _service.readData(1, 1203, "single"); // 母线电压 V + //dynamic d3 = _service.readData(1, 1205, "single"); // 实际电流 A + //dynamic d4 = _service.readData(1, 1215, "single"); // 累计加工次数 + //dynamic d5 = _service.readData(1, 1225, "single"); // 切削倍率 + //dynamic d6 = _service.readData(1, 1231, "single"); // 主轴倍率 + //dynamic d7 = _service.readData(1, 6689, "string", 50); // 运行程序编号 length = 8 + //dynamic d8 = _service.readData(1, 6435, "int16"); // 累计运行时长 分钟 + string message = ""; + bool success = int.TryParse(deviceIdStr, out int deviceId); + try + { + if (success) + { + Dictionary> dataMap = new(); + if (1 == 1) + { + dataMap = _dataService.readSiemensData(_service); + } + else { + dataMap.Add("produce", new Dictionary()); + dataMap.Add("machine", new Dictionary()); + } + message = saveSourceData(dataMap, deviceId); + } + else + { + message = "设备非法或已下线"; + } + + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + message = "read data error: " + ex.Message; + } + finally + { + if (_service != null) + { + _service.disConnent(); + } + } + return Content(message); + } + + + /// + /// 采集广数设备 + /// + /// IActionResult + [ApiTask] + [HttpGet, HttpPost, Route("gatherGSK")] + public IActionResult gatherGSK() + { + var headers = _httpContextAccessor.HttpContext.Request.Headers; + headers.TryGetValue("USER-DEVICE-ID", out StringValues deviceIdStr); + if (1 == 1) + { + try + { + _service = new ModbusTcpService("192.168.1.100", 502); + Console.WriteLine("GSK modbus tcp connected..."); + } + catch (Exception) + { + Console.WriteLine("GSK modbus tcp connect failed!"); + return Content("GSK modbus tcp connect failed!"); + } + if (!_service.isConnected) + { + Console.WriteLine("GSK modbus tcp disconnect!"); + return Content("GSK modbus tcp disconnect!"); + } + } + + //_service.readData(1, 6429, "int16"); // 程序编号 + //_service.readData(1, 6435, "int16"); // 通讯状态 5:通讯正常 15:通讯断线 + //_service.readData(1, 6430, "int16"); + //_service.readData(1, 6435, "int16"); // 运行时长 分钟 + //_service.readData(1, 6436, "int16"); // 工单1产量 件 + //_service.readData(1, 6437, "int16"); // 工单2产量 件 + //_service.readData(1, 6438, "int16"); // 工单3产量 件 + //_service.readData(1, 6439, "int16"); // 当班产量 件 + //_service.readData(1, 6440, "int16"); // 运行状态 0:待机 1:运行 2:故障 + //_service.readData(1, 1315, "single"); // 工单1任务进度 % + //_service.readData(1, 1317, "single"); // 工单2任务进度 % + //_service.readData(1, 1319, "single"); // 工单3任务进度 % + //_service.readData(1, 1321, "single"); // 工单1良品率 % 真实值 *= 100 + //_service.readData(1, 1323, "single"); // 工单2良品率 % 真实值 *= 100 + //_service.readData(1, 1325, "single"); // 工单3良品率 % 真实值 *= 100 + //_service.readData(1, 1331, "single"); // 设备综合效率 % 真实值 *= 100 + + //_service.readData(1, 6430, "int16"); // 通讯状态 5:通讯正常 15:通讯断线 + //_service.readData(1, 6099, "int16"); // 工作方式 0:编辑 1:自动 2:MDI 3:DNC 4:手动 5:手轮 6:回参考点 + //_service.readData(1, 6100, "int16"); // 运行状态 0:复位 1:停止 2:运行 3:暂停 + //dynamic d1 = _service.readData(1, 4117, "int32"); // 当天加工数量 次 + //dynamic d2 = _service.readData(1, 1201, "int32"); // 开机时间 秒 + //dynamic d3 = _service.readData(1, 1203, "int32"); // 运行时间 秒 + //dynamic d4 = _service.readData(1, 1241, "single"); // 进给倍率 + //dynamic d5 = _service.readData(1, 1247, "single"); // 主轴倍率 + //dynamic d6 = _service.readData(1, 6299, "string", 8); // 运行程序编号 length = 8 + //dynamic d7 = _service.readData(1, 4115, "int32"); // 累计运行时长 分钟 + //dynamic d8 = _service.readData(1, 1199, "int32"); // 累计加工数 次 + + string message = ""; + bool success = int.TryParse(deviceIdStr, out int deviceId); + try + { + if (success) + { + Dictionary> dataMap = new(); + if (1 == 1) + { + dataMap = _dataService.readGSKData(_service); + } + else + { + dataMap.Add("produce", new Dictionary()); + dataMap.Add("machine", new Dictionary()); + } + message = saveSourceData(dataMap, deviceId); + } + else + { + message = "设备非法或已下线"; + } + } + catch (Exception ex) + { + Console.WriteLine(ex.StackTrace); + message = "read data error: " + ex.Message; + } + finally + { + if (_service != null) + { + _service.disConnent(); + } + } + return Content(message); + } + + + [HttpGet, HttpPost, Route("testSave")] + public IActionResult testSave() + { + Dictionary> dataMap = new(); + dataMap.Add("machine", new Dictionary() { { "config_id", 666 } }); + dataMap.Add("produce", new Dictionary() { { "config_id", 666 } }); + string message = saveSourceData(dataMap, 1); + return Content(message); + } + + + /// + /// 保存采集数据 + /// + /// IActionResult + private string saveSourceData(Dictionary> dataMap, int deviceId) + { + // 获取当前系统时间, 保证插入时间一致 + DateTime now = DateTime.Now; + // 设备关联的用户信息 + Data_Config dataConfig = _dataService.GetDataConfig(deviceId); + if (dataConfig == null) { + return "设备不存在!"; + } + int userId = dataConfig.CreateID ?? 1; // 默认超管 + Dictionary machineData = dataMap["machine"]; + Data_Machine data_Machine = CommonUtil.ConvertToObject(machineData); + data_Machine.config_id = deviceId; + data_Machine.CreateDate = now; + data_Machine.CreateID = userId; + bool result1 = _dataService.saveMachineData(data_Machine, out string message1); + + Dictionary produceData = dataMap["produce"]; + Data_Produce data_Produce = CommonUtil.ConvertToObject(produceData); + data_Produce.config_id = deviceId; + data_Produce.CreateDate = now; + data_Produce.CreateID = userId; + bool result2 = _dataService.saveProduceData(data_Produce, out string message2); + + return (result1 && result2) ? "OK" : "save machine: " + message1 + "; save produce: " + message2 + ";"; + } + } +} diff --git a/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_ConfigController.cs b/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_ConfigController.cs new file mode 100644 index 0000000..1a93351 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_ConfigController.cs @@ -0,0 +1,33 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("Data_Config",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VOL.Entity.DomainModels; +using VOL.Data.IServices; + +namespace VOL.Data.Controllers +{ + public partial class Data_ConfigController + { + private readonly IData_ConfigService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public Data_ConfigController( + IData_ConfigService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + } +} diff --git a/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_MachineController.cs b/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_MachineController.cs new file mode 100644 index 0000000..0969483 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_MachineController.cs @@ -0,0 +1,33 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("Data_Machine",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VOL.Entity.DomainModels; +using VOL.Data.IServices; + +namespace VOL.Data.Controllers +{ + public partial class Data_MachineController + { + private readonly IData_MachineService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public Data_MachineController( + IData_MachineService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + } +} diff --git a/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_ProduceController.cs b/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_ProduceController.cs new file mode 100644 index 0000000..62cc1c2 --- /dev/null +++ b/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_ProduceController.cs @@ -0,0 +1,33 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("Data_Produce",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VOL.Entity.DomainModels; +using VOL.Data.IServices; + +namespace VOL.Data.Controllers +{ + public partial class Data_ProduceController + { + private readonly IData_ProduceService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public Data_ProduceController( + IData_ProduceService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + } +} diff --git a/vol-net6/VOL.WebApi/Controllers/Order/Partial/SellOrderController.cs b/vol-net6/VOL.WebApi/Controllers/Order/Partial/SellOrderController.cs index b3cd145..28cfc73 100644 --- a/vol-net6/VOL.WebApi/Controllers/Order/Partial/SellOrderController.cs +++ b/vol-net6/VOL.WebApi/Controllers/Order/Partial/SellOrderController.cs @@ -44,7 +44,7 @@ namespace VOL.Order.Controllers [HttpPost] [ApiActionPermission("SellOrder", Core.Enums.ActionPermissionOptions.Search)] - [Route("getServiceDate"), FixedToken]//FixedToken请求此接口只要token合法就能能过//AllowAnonymous + [Route("getServiceDate"), FixedToken]//FixedToken 接口token永不过期 //AllowAnonymous 无需验证即可访问 public IActionResult GetServiceDate() { return Content(Service.GetServiceDate()); diff --git a/vol-net6/VOL.WebApi/Controllers/System/Partial/Sys_DepartmentController.cs b/vol-net6/VOL.WebApi/Controllers/System/Partial/Sys_DepartmentController.cs index a800825..7848355 100644 --- a/vol-net6/VOL.WebApi/Controllers/System/Partial/Sys_DepartmentController.cs +++ b/vol-net6/VOL.WebApi/Controllers/System/Partial/Sys_DepartmentController.cs @@ -125,6 +125,20 @@ namespace VOL.System.Controllers }).ToListAsync(); return JsonNormal(new { rows }); } + + /// + /// 获取用户根部门 + /// + /// + [HttpGet, Route("getUserDepartment")] + [ApiActionPermission()] + public async Task GetUserDepartment() + { + int useId = UserContext.Current.UserId; + var sysDepartment = await _service.GetUserDepartment(useId); + + return JsonNormal(new { sysDepartment.DepartmentName, sysDepartment.DepartmentId }); + } } } diff --git a/vol-net6/VOL.WebApi/Controllers/System/Partial/Sys_QuartzOptionsController.cs b/vol-net6/VOL.WebApi/Controllers/System/Partial/Sys_QuartzOptionsController.cs index 38f185e..b2aa628 100644 --- a/vol-net6/VOL.WebApi/Controllers/System/Partial/Sys_QuartzOptionsController.cs +++ b/vol-net6/VOL.WebApi/Controllers/System/Partial/Sys_QuartzOptionsController.cs @@ -13,6 +13,7 @@ using VOL.Entity.DomainModels; using VOL.System.IServices; using VOL.Core.Filters; using VOL.Core.Enums; +using Microsoft.Extensions.Primitives; namespace VOL.System.Controllers { @@ -40,6 +41,8 @@ namespace VOL.System.Controllers [HttpGet, HttpPost, Route("test")] public IActionResult Test() { + //var headers = _httpContextAccessor.HttpContext.Request.Headers; + //headers.TryGetValue("USER-DEVICE-ID", out StringValues val); //AuthKey return Content(DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss")); } diff --git a/vol-net6/VOL.WebApi/Controllers/System/Sys_LogController.cs b/vol-net6/VOL.WebApi/Controllers/System/Sys_LogController.cs index 9e0eed6..0e8e9f5 100644 --- a/vol-net6/VOL.WebApi/Controllers/System/Sys_LogController.cs +++ b/vol-net6/VOL.WebApi/Controllers/System/Sys_LogController.cs @@ -17,6 +17,7 @@ namespace VOL.System.Controllers public Sys_LogController(ISys_LogService service) : base("System", "System", "Sys_Log", service) { + // 没有多个构造函数时,执行默认构造 } } } diff --git a/vol-net6/VOL.WebApi/Program.cs b/vol-net6/VOL.WebApi/Program.cs index 35ffea1..dd64311 100644 --- a/vol-net6/VOL.WebApi/Program.cs +++ b/vol-net6/VOL.WebApi/Program.cs @@ -22,7 +22,7 @@ namespace VOL.WebApi AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true); //CreateHostBuilder(args).Build().Run(); var host = CreateHostBuilder(args).Build(); - #region kafkaϢ + #region kafka订阅消息111 //if (AppSetting.Kafka.UseConsumer) //{ // using var scope = host.Services.CreateScope(); @@ -30,16 +30,24 @@ namespace VOL.WebApi // testConsumer.Consume(res => // { // Console.WriteLine($"recieve:{DateTime.Now.ToLongTimeString()} value:{res.Message.Value}"); - // //̬ ݴ Ȳ + // //静态方法 数据处理 入库等操作 // bool bl = DataHandle.AlarmData(res.Message.Value); - // //ص践رִCommit + // //回调函数需返回便于执行Commit // return bl; // }, AppSetting.Kafka.Topics.TestTopic); //} #endregion + // 打印测试 + if (1 == 1) { + DateTime dateTime = DateTime.Now; + String dateOnly = dateTime.ToString("yyyy-MM-dd"); + Console.WriteLine(dateTime); // 输出完整的日期和时间 + Console.WriteLine(dateOnly); // 输出日期部分(不包含时间) + } host.Run(); } + public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => @@ -53,5 +61,26 @@ namespace VOL.WebApi webBuilder.UseIIS(); webBuilder.UseStartup(); }).UseServiceProviderFactory(new AutofacServiceProviderFactory()); + + + //public static async Task Main(string[] args) + //{ + // // 创建一个定时器,每隔1秒触发一次 + // var timer = new Timer(async state => + // { + // // 在这里编写您的异步任务逻辑 + // await Task.Delay(1000); + // Console.WriteLine("异步定时任务执行"); + // }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + // TimeSpan.Zero 表示定时器立即开始执行,TimeSpan.FromSeconds(1) 表示每隔1秒触发一次定时任务。 + + // // 等待一段时间,观察异步定时任务的执行 + // await Task.Delay(5000); + + // // 停止定时器 + // timer.Dispose(); + + // Console.WriteLine("定时器已停止"); + //} } } diff --git a/vol-net6/VOL.WebApi/Utils/CommonUtil.cs b/vol-net6/VOL.WebApi/Utils/CommonUtil.cs new file mode 100644 index 0000000..eb7685c --- /dev/null +++ b/vol-net6/VOL.WebApi/Utils/CommonUtil.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; + +namespace VOL.WebApi.Utils +{ + public class CommonUtil + { + // 实体对象转Dictionary + + public static Dictionary ConvertToDictionary(T entity) + { + var dictionary = new Dictionary(); + var properties = typeof(T).GetProperties(); + + foreach (var property in properties) + { + var key = property.Name; + var value = property.GetValue(entity); + dictionary.Add(key, value); + } + + return dictionary; + } + + // Dictionary转实体对象 + public static T ConvertToObject(Dictionary dictionary) where T : new() + { + var obj = new T(); + var properties = typeof(T).GetProperties(); + + foreach (var property in properties) + { + if (dictionary.TryGetValue(property.Name, out var value)) + { + property.SetValue(obj, value); + } + } + + return obj; + } + } +} diff --git a/vol-net6/VOL.WebApi/Utils/DataConvertUtil.cs b/vol-net6/VOL.WebApi/Utils/DataConvertUtil.cs new file mode 100644 index 0000000..eb0f2dd --- /dev/null +++ b/vol-net6/VOL.WebApi/Utils/DataConvertUtil.cs @@ -0,0 +1,307 @@ +using System.Text; +using System; + +namespace VOL.WebApi.Utils +{ + public class DataConvertUtil + { + /// + /// 赋值string string => ushort[] + /// + /// + /// + /// + /// + public static void SetString(ushort[] src, int start, string value) + { + byte[] bytesTemp = Encoding.UTF8.GetBytes(value); + ushort[] dest = Bytes2Ushorts(bytesTemp); + dest.CopyTo(src, start); + } + + /// + /// 获取string ushort[] => string + /// + /// + /// + /// + /// string + public static string GetString(ushort[] src, int start, int len) + { + ushort[] temp = new ushort[len]; + for (int i = 0; i < len; i++) + { + temp[i] = src[i + start]; + } + byte[] bytesTemp = Ushorts2Bytes(temp); + //string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' }); // 去除字符串左右端的指定内容 + string res = Encoding.UTF8.GetString(bytesTemp).Trim(); + return res; + } + + /// + /// 赋值Real float => ushort[] + /// + /// + /// + /// + public static void SetReal(ushort[] src, int start, float value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + /// + /// 获取float ushort[] => float + /// + /// + /// + /// float + public static float GetReal(ushort[] src, int start) + { + try + { + ushort[] temp = new ushort[2]; + + for (int i = 0; i < 2; i++) + { + temp[i] = src[i + start]; + } + Array.Reverse(temp); + // !!!BitConverter默认是小端转换,如果是大端字节顺序数组接收,需要先反序字节顺序 + byte[] bytesTemp = Ushorts2Bytes(temp,false); + float f = BitConverter.ToSingle(bytesTemp, 0); + return float.Parse(f.ToString("F2")); // 保留两位小数 + } catch (Exception e) + { + return 0; + } + + } + + /// + /// 赋值Short short => ushort[] + /// + /// + /// + /// + public static void SetShort(ushort[] src, int start, short value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + /// + /// 获取short ushort[] => short + /// + /// + /// + /// short + public static short GetShort(ushort[] src, int start) + { + try + { + ushort[] temp = new ushort[1]; + temp[0] = src[start]; + byte[] bytesTemp = Ushorts2Bytes(temp); + short res = BitConverter.ToInt16(bytesTemp, 0); + return res; + } + catch (Exception e) + { + return 0; + } + + } + + /// + /// 赋值Short short => ushort[] + /// + /// + /// + /// + public static void SetInt(ushort[] src, int start, int value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + + /// + /// 获取short ushort[] => int + /// + /// + /// + /// short + public static int GetInt(ushort[] src, int start) + { + try { + ushort[] temp = new ushort[2]; + temp[0] = src[start]; + temp[1] = src[start + 1]; // 0 100 + Array.Reverse(temp); // 100 0 地址低位存储低字节数据(小端) + byte[] bytesTemp = Ushorts2Bytes(temp,false); + int res = BitConverter.ToInt32(bytesTemp, 0); + return res; + } catch (Exception e) + { + return 0; + } + + } + + + /// + /// 获取short ushort[] => long + /// + /// + /// + /// short + public static long GetLong(ushort[] src, int start) + { + try { + ushort[] temp = new ushort[4]; + temp[0] = src[start]; + temp[1] = src[start + 1]; + temp[2] = src[start + 2]; + temp[3] = src[start + 3]; // 0 0 0 100 + Array.Reverse(temp); // 100 0 0 0 + byte[] bytesTemp = Ushorts2Bytes(temp); + long res = BitConverter.ToInt64(bytesTemp, 0); + return res; + } catch (Exception e) + { + return 0; + } + + } + + + + /// + /// 获取bool数组 ushort[] => bool[] + /// + /// + /// + /// short + + public static bool[] GetBools(ushort[] src, int start, int num) + { + ushort[] temp = new ushort[num]; + for (int i = start; i < start + num; i++) + { + temp[i] = src[i + start]; + } // 0 1 0 1 0 0 0 0 默认小端模式 + //Array.Reverse(temp); // 0 0 0 0 1 0 1 0 + byte[] bytes = Ushorts2Bytes(temp); + bool[] res = Bytes2Bools(bytes); + return res; + } + + + // byte[] => bool[] + private static bool[] Bytes2Bools(byte[] b) + { + bool[] array = new bool[8 * b.Length]; + + for (int i = 0; i < b.Length; i++) + { + for (int j = 0; j < 8; j++) + { + array[i * 8 + j] = (b[i] & 1) == 1;//判定byte的最后一位是否为1,若为1,则是true;否则是false + b[i] = (byte)(b[i] >> 1);//将byte右移一位 + } + } + return array; + } + + // bool[] => byte + private static byte Bools2Byte(bool[] array) + { + if (array != null && array.Length > 0) + { + byte b = 0; + for (int i = 0; i < 8; i++) + { + if (array[i]) + { + byte nn = (byte)(1 << i);//左移一位,相当于×2 + b += nn; + } + } + return b; + } + return 0; + } + + + // byte[] => ushort[] + private static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false) + { + int len = src.Length; + + byte[] srcPlus = new byte[len + 1]; + src.CopyTo(srcPlus, 0); + int count = len >> 1; + + if (len % 2 != 0) + { + count += 1; + } + + ushort[] dest = new ushort[count]; + if (reverse) + { + for (int i = 0; i < count; i++) + { + dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff); + } + } + else + { + for (int i = 0; i < count; i++) + { + dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8); + } + } + + return dest; + } + + + // ushort[] => byte[] + private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false) + { + + int count = src.Length; + byte[] dest = new byte[count << 1]; + if (reverse) + { + for (int i = 0; i < count; i++) + { + dest[i * 2] = (byte)(src[i] >> 8); + dest[i * 2 + 1] = (byte)(src[i] >> 0); + } + } + else + { + for (int i = 0; i < count; i++) + { + dest[i * 2] = (byte)(src[i] >> 0); + dest[i * 2 + 1] = (byte)(src[i] >> 8); + } + } + return dest; + } + } + +} diff --git a/vol-net6/VOL.WebApi/VOL.WebApi.csproj b/vol-net6/VOL.WebApi/VOL.WebApi.csproj index 243612c..d507653 100644 --- a/vol-net6/VOL.WebApi/VOL.WebApi.csproj +++ b/vol-net6/VOL.WebApi/VOL.WebApi.csproj @@ -31,6 +31,7 @@ + diff --git a/vol-net6/VOL.WebApi/VOL.WebApi.csproj.user b/vol-net6/VOL.WebApi/VOL.WebApi.csproj.user index 401c7a8..b466ae3 100644 --- a/vol-net6/VOL.WebApi/VOL.WebApi.csproj.user +++ b/vol-net6/VOL.WebApi/VOL.WebApi.csproj.user @@ -6,8 +6,8 @@ VOL.WebApi E:\jxx\Vue.NetCore\.Net6版本\VOL.WebApi\Properties\PublishProfiles\FolderProfile1.pubxml - MvcControllerEmptyScaffolder - root/Common/MVC/Controller + ApiControllerEmptyScaffolder + root/Common/Api ProjectDebugger diff --git a/vol-net6/VOL.WebApi/quartz/error/2023-08-31.txt b/vol-net6/VOL.WebApi/quartz/error/2023-08-31.txt new file mode 100644 index 0000000..505044e --- /dev/null +++ b/vol-net6/VOL.WebApi/quartz/error/2023-08-31.txt @@ -0,0 +1 @@ +作业启动:西门子设备采集(5s一次) \ No newline at end of file diff --git a/vol-net6/VOL.WebApi/wwwroot/Upload/Tables/Sys_User/202309261815594546/nkn.png b/vol-net6/VOL.WebApi/wwwroot/Upload/Tables/Sys_User/202309261815594546/nkn.png new file mode 100644 index 0000000..a512470 Binary files /dev/null and b/vol-net6/VOL.WebApi/wwwroot/Upload/Tables/Sys_User/202309261815594546/nkn.png differ diff --git a/vol-net6/VOL.WebApi/wwwroot/Upload/Tables/Sys_User/202309270810424470/yz.png b/vol-net6/VOL.WebApi/wwwroot/Upload/Tables/Sys_User/202309270810424470/yz.png new file mode 100644 index 0000000..aa891a0 Binary files /dev/null and b/vol-net6/VOL.WebApi/wwwroot/Upload/Tables/Sys_User/202309270810424470/yz.png differ diff --git a/vol-net6/VOL.sln b/vol-net6/VOL.sln index 6a43447..f14ffce 100644 --- a/vol-net6/VOL.sln +++ b/vol-net6/VOL.sln @@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VOL.Order", "VOL.Order\VOL. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VOL.WebApi", "VOL.WebApi\VOL.WebApi.csproj", "{4DB3C91B-93FE-4937-8B58-DDD3F57D4607}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VOL.Data", "VOL.Data\VOL.Data.csproj", "{FA76EAA8-C355-4E13-B15C-FF925919F861}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,6 +53,10 @@ Global {4DB3C91B-93FE-4937-8B58-DDD3F57D4607}.Debug|Any CPU.Build.0 = Debug|Any CPU {4DB3C91B-93FE-4937-8B58-DDD3F57D4607}.Release|Any CPU.ActiveCfg = Release|Any CPU {4DB3C91B-93FE-4937-8B58-DDD3F57D4607}.Release|Any CPU.Build.0 = Release|Any CPU + {FA76EAA8-C355-4E13-B15C-FF925919F861}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA76EAA8-C355-4E13-B15C-FF925919F861}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA76EAA8-C355-4E13-B15C-FF925919F861}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA76EAA8-C355-4E13-B15C-FF925919F861}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/vol-vue3/package-lock.json b/vol-vue3/package-lock.json index f2ad2c7..3cd97ce 100644 --- a/vol-vue3/package-lock.json +++ b/vol-vue3/package-lock.json @@ -8,6 +8,7 @@ "name": "vol.vue3", "version": "0.1.0", "dependencies": { + "@dataview/datav-vue3": "^0.0.0-test.1672506674342", "@element-plus/icons-vue": "^2.1.0", "@microsoft/signalr": "^6.0.4", "ali-oss": "^6.17.1", @@ -1680,6 +1681,27 @@ "node": ">=10" } }, + "node_modules/@dataview/datav-vue3": { + "version": "0.0.0-test.1672506674342", + "resolved": "https://registry.npmmirror.com/@dataview/datav-vue3/-/datav-vue3-0.0.0-test.1672506674342.tgz", + "integrity": "sha512-d0oT/msAi592CTvWmQl0umkLpHgMwtTN2+peyo0L2GHNG7b4cKeO9meEF5o28DgFzRwOLeNQW73vKCF4JC+ihw==", + "dependencies": { + "@jiaminghi/color": "^0.1.1", + "classnames": "^2.3.2", + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "vue": ">=3.2.0" + } + }, + "node_modules/@dataview/datav-vue3/node_modules/@jiaminghi/color": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@jiaminghi/color/-/color-0.1.1.tgz", + "integrity": "sha512-M09+Sb5HGqVim0zo+nG5gU1v+6gXT8ptr0BZR6dMGt83XmCJgnZtO8s7llTW4hLFFFM5co6geZvTekqLpSPAAQ==", + "dependencies": { + "@babel/runtime": "^7.5.5" + } + }, "node_modules/@element-plus/icons-vue": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz", @@ -4654,6 +4676,11 @@ "node": ">=0.10.0" } }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/clean-css": { "version": "4.2.3", "resolved": "https://registry.nlark.com/clean-css/download/clean-css-4.2.3.tgz?cache=0&sync_timestamp=1624616709466&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fclean-css%2Fdownload%2Fclean-css-4.2.3.tgz", @@ -18556,6 +18583,26 @@ "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==" }, + "@dataview/datav-vue3": { + "version": "0.0.0-test.1672506674342", + "resolved": "https://registry.npmmirror.com/@dataview/datav-vue3/-/datav-vue3-0.0.0-test.1672506674342.tgz", + "integrity": "sha512-d0oT/msAi592CTvWmQl0umkLpHgMwtTN2+peyo0L2GHNG7b4cKeO9meEF5o28DgFzRwOLeNQW73vKCF4JC+ihw==", + "requires": { + "@jiaminghi/color": "^0.1.1", + "classnames": "^2.3.2", + "lodash-es": "^4.17.21" + }, + "dependencies": { + "@jiaminghi/color": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@jiaminghi/color/-/color-0.1.1.tgz", + "integrity": "sha512-M09+Sb5HGqVim0zo+nG5gU1v+6gXT8ptr0BZR6dMGt83XmCJgnZtO8s7llTW4hLFFFM5co6geZvTekqLpSPAAQ==", + "requires": { + "@babel/runtime": "^7.5.5" + } + } + } + }, "@element-plus/icons-vue": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz", @@ -21099,6 +21146,11 @@ } } }, + "classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "clean-css": { "version": "4.2.3", "resolved": "https://registry.nlark.com/clean-css/download/clean-css-4.2.3.tgz?cache=0&sync_timestamp=1624616709466&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fclean-css%2Fdownload%2Fclean-css-4.2.3.tgz", diff --git a/vol-vue3/package.json b/vol-vue3/package.json index bee2417..b0b794b 100644 --- a/vol-vue3/package.json +++ b/vol-vue3/package.json @@ -1,5 +1,5 @@ { - "name": "vol.vue3", + "name": "yxsc", "version": "0.1.0", "private": true, "scripts": { @@ -10,11 +10,12 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.1.0", + "@jiaminghi/data-view": "^2.10.0", "@microsoft/signalr": "^6.0.4", "ali-oss": "^6.17.1", "axios": "^0.21.1", "core-js": "^3.6.5", - "echarts": "^5.0.2", + "echarts": "^5.3.0", "element-plus": "^2.2.14", "less": "^4.1.1", "vue": "^3.2.37", diff --git a/vol-vue3/public/index.html b/vol-vue3/public/index.html index a9c33a2..d86de0b 100644 --- a/vol-vue3/public/index.html +++ b/vol-vue3/public/index.html @@ -5,8 +5,8 @@ - - + + <%= htmlWebpackPlugin.options.title %> diff --git a/vol-vue3/src/api/http.js b/vol-vue3/src/api/http.js index aacf4e1..3ec6bbd 100644 --- a/vol-vue3/src/api/http.js +++ b/vol-vue3/src/api/http.js @@ -12,7 +12,7 @@ import { ElLoading as Loading, ElMessage as Message } from 'element-plus'; let loadingInstance; let loadingStatus = false; if (process.env.NODE_ENV == 'development') { - axios.defaults.baseURL = 'http://127.0.0.1:9991/'; + axios.defaults.baseURL = 'http://192.168.0.187:9991/'; } else if (process.env.NODE_ENV == 'debug') { axios.defaults.baseURL = 'http://127.0.0.1:9991/'; @@ -205,6 +205,7 @@ function createXHR () { } function redirect (responseText, message) { + console.log(typeof responseText); try { let responseData = typeof responseText == 'string' ? JSON.parse(responseText) : responseText; if ((responseData.hasOwnProperty('code') && responseData.code == 401) diff --git a/vol-vue3/src/assets/imgs/logo.png b/vol-vue3/src/assets/imgs/logo.png index 165d86a..0f2d4a9 100644 Binary files a/vol-vue3/src/assets/imgs/logo.png and b/vol-vue3/src/assets/imgs/logo.png differ diff --git a/vol-vue3/src/assets/imgs/logop.png b/vol-vue3/src/assets/imgs/logop.png new file mode 100644 index 0000000..165d86a Binary files /dev/null and b/vol-vue3/src/assets/imgs/logop.png differ diff --git a/vol-vue3/src/components/basic/VolTable.vue b/vol-vue3/src/components/basic/VolTable.vue index 02db672..d75646f 100644 --- a/vol-vue3/src/components/basic/VolTable.vue +++ b/vol-vue3/src/components/basic/VolTable.vue @@ -1511,7 +1511,6 @@ export default defineComponent({ if (!column.bind || !column.bind.data) { return row[column.field]; } - if (column.edit && (column.edit.type == 'selectList'||column.edit.type=='treeSelect')) { if (!Array.isArray(val)) { row[column.field] = val.split(','); diff --git a/vol-vue3/src/components/echarts/Bar.vue b/vol-vue3/src/components/echarts/Bar.vue new file mode 100644 index 0000000..d2bd4c3 --- /dev/null +++ b/vol-vue3/src/components/echarts/Bar.vue @@ -0,0 +1,196 @@ + + + + + + + + + \ No newline at end of file diff --git a/vol-vue3/src/components/echarts/Gauge.vue b/vol-vue3/src/components/echarts/Gauge.vue new file mode 100644 index 0000000..a5672b0 --- /dev/null +++ b/vol-vue3/src/components/echarts/Gauge.vue @@ -0,0 +1,159 @@ + + + + + + + + + \ No newline at end of file diff --git a/vol-vue3/src/components/echarts/Line.vue b/vol-vue3/src/components/echarts/Line.vue new file mode 100644 index 0000000..c06f989 --- /dev/null +++ b/vol-vue3/src/components/echarts/Line.vue @@ -0,0 +1,181 @@ + + + + + + + + + \ No newline at end of file diff --git a/vol-vue3/src/components/echarts/Number.vue b/vol-vue3/src/components/echarts/Number.vue new file mode 100644 index 0000000..864cb16 --- /dev/null +++ b/vol-vue3/src/components/echarts/Number.vue @@ -0,0 +1,80 @@ + + + + + + + + + \ No newline at end of file diff --git a/vol-vue3/src/extension/data/config/Data_Config.js b/vol-vue3/src/extension/data/config/Data_Config.js new file mode 100644 index 0000000..8935403 --- /dev/null +++ b/vol-vue3/src/extension/data/config/Data_Config.js @@ -0,0 +1,75 @@ +/***************************************************************************************** +** Author:jxx 2022 +** QQ:283591387 +**完整文档见:http://v2.volcore.xyz/document/api 【代码生成页面ViewGrid】 +**常用示例见:http://v2.volcore.xyz/document/vueDev +**后台操作见:http://v2.volcore.xyz/document/netCoreDev +*****************************************************************************************/ +//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码 + +let extension = { + components: { + //查询界面扩展组件 + gridHeader: '', + gridBody: '', + gridFooter: '', + //新建、编辑弹出框扩展组件 + modelHeader: '', + modelBody: '', + modelFooter: '' + }, + tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写) + buttons: { view: [], box: [], detail: [] }, //扩展的按钮 + methods: { + //下面这些方法可以保留也可以删除 + onInit() { //框架初始化配置前, + //示例:在按钮的最前面添加一个按钮 + // this.buttons.unshift({ //也可以用push或者splice方法来修改buttons数组 + // name: '按钮', //按钮名称 + // icon: 'el-icon-document', //按钮图标vue2版本见iview文档icon,vue3版本见element ui文档icon(注意不是element puls文档) + // type: 'primary', //按钮样式vue2版本见iview文档button,vue3版本见element ui文档button + // onClick: function () { + // this.$Message.success('点击了按钮'); + // } + // }); + + //示例:设置修改新建、编辑弹出框字段标签的长度 + // this.boxOptions.labelWidth = 150; + }, + onInited() { + //框架初始化配置后 + //如果要配置明细表,在此方法操作 + //this.detailOptions.columns.forEach(column=>{ }); + }, + searchBefore(param) { + //界面查询前,可以给param.wheres添加查询参数 + //返回false,则不会执行查询 + return true; + }, + searchAfter(result) { + //查询后,result返回的查询数据,可以在显示到表格前处理表格的值 + return true; + }, + addBefore(formData) { + //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值 + return true; + }, + updateBefore(formData) { + //编辑保存前formData为对象,包括明细表、删除行的Id + return true; + }, + rowClick({ row, column, event }) { + //查询界面点击行事件 + // this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行; + }, + modelOpenAfter(row) { + //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据 + //(1)判断是编辑还是新建操作: this.currentAction=='Add'; + //(2)给弹出框设置默认值 + //(3)this.editFormFields.字段='xxx'; + //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值 + //看不懂就把输出看:console.log(this.editFormOptions) + } + } +}; +export default extension; diff --git a/vol-vue3/src/extension/data/machine/Data_Machine.js b/vol-vue3/src/extension/data/machine/Data_Machine.js new file mode 100644 index 0000000..0b28328 --- /dev/null +++ b/vol-vue3/src/extension/data/machine/Data_Machine.js @@ -0,0 +1,164 @@ +/***************************************************************************************** +** Author:jxx 2022 +** QQ:283591387 +**完整文档见:http://v2.volcore.xyz/document/api 【代码生成页面ViewGrid】 +**常用示例见:http://v2.volcore.xyz/document/vueDev +**后台操作见:http://v2.volcore.xyz/document/netCoreDev +*****************************************************************************************/ +//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码 + +let extension = { + components: { + //查询界面扩展组件 + gridHeader: '', + gridBody: '', + gridFooter: '', + //新建、编辑弹出框扩展组件 + modelHeader: '', + modelBody: '', + modelFooter: '' + }, + tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写) + buttons: { view: [], box: [], detail: [] }, //扩展的按钮 + methods: { + onInit() { //框架初始化配置前, + //设置排序字段 + this.pagination.sortName = "id"; + this.pagination.order = "desc"; + + //设置页面上显示的按钮个数 + this.maxBtnLength = 3; + + // 格式化数据 + this.dataFormatter(); + }, + onInited() { + //框架初始化配置后 + let fixeds = ['id','com_status','config_id']; + this.columns.forEach(x=>{ + //设置title列固定 + if (fixeds.includes(x.field)) { + x.fixed=true//也可以设置为right,固定到最右边 + } + }) + //如果要配置明细表,在此方法操作 + //this.detailOptions.columns.forEach(column=>{ }); + }, + searchBefore(param) { + //界面查询前,可以给param.wheres添加查询参数 + //返回false,则不会执行查询 + return true; + }, + searchAfter(result) { + //查询后,result返回的查询数据,可以在显示到表格前处理表格的值 + return true; + }, + addBefore(formData) { + //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值 + return true; + }, + updateBefore(formData) { + //编辑保存前formData为对象,包括明细表、删除行的Id + return true; + }, + rowClick({ row, column, event }) { + //查询界面点击行事件 + this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行; + }, + modelOpenAfter(row) { + //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据 + //(1)判断是编辑还是新建操作: this.currentAction=='Add'; + //(2)给弹出框设置默认值 + //(3)this.editFormFields.字段='xxx'; + //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值 + //看不懂就把输出看:console.log(this.editFormOptions) + }, + dataFormatter() { + this.columns.forEach(column => { + if (column.field == 'temperature') { + column.formatter = (row) => { + return row.temperature && '' + row.temperature + ' ℃ ' + } + } + if (column.field == 'potential') { + column.formatter = (row) => { + return row.potential && '' + row.potential + ' V ' + } + } + if (column.field == 'current') { + column.formatter = (row) => { + return row.current && '' + row.current + ' A ' + } + } + if (column.field == 'quantity') { + column.formatter = (row) => { + return row.quantity && '' + row.quantity + ' 次 ' + } + } + if (column.field == 'cut_rate') { + column.formatter = (row) => { + return row.cut_rate && '' + row.cut_rate + ' % ' + } + } + if (column.field == 'main_rate') { + column.formatter = (row) => { + return row.main_rate && '' + row.main_rate + ' % ' + } + } + if (column.field == 'feed_rate') { + column.formatter = (row) => { + return row.feed_rate && '' + row.feed_rate + ' % ' + } + } + if (column.field == 'on_time') { + column.formatter = (row) => { + return row.on_time && '' + row.on_time + ' 秒 ' + } + } + if (column.field == 'run_time') { + column.formatter = (row) => { + return row.run_time && '' + row.run_time + ' 秒 ' + } + } + if (column.field == 'run_time_total') { + column.formatter = (row) => { + return row.run_time_total && '' + row.run_time_total + ' 分 ' + } + } + if (column.field == 'quantity_total') { + column.formatter = (row) => { + return row.quantity_total && '' + row.quantity_total + ' 次 ' + } + } + + // 标签改色 + if (column.field == 'com_status') { + column.getColor = (row, column) => { + if (row.com_status == 15) { + return 'danger'; + } else if (row.com_status == 5){ + return 'success'; + } else { + return ''; + } + } + } + + if (column.field == 'state') { + column.getColor = (row, column) => { + if (row.state == 1) { + return 'danger'; + } else if (row.state == 2){ + return 'success'; + } else if (row.state == 3){ + return 'warning'; + } else { + return ''; + } + } + } + }) + } + } +}; +export default extension; diff --git a/vol-vue3/src/extension/data/produce/Data_Produce.js b/vol-vue3/src/extension/data/produce/Data_Produce.js new file mode 100644 index 0000000..3bad0d4 --- /dev/null +++ b/vol-vue3/src/extension/data/produce/Data_Produce.js @@ -0,0 +1,153 @@ +/***************************************************************************************** +** Author:jxx 2022 +** QQ:283591387 +**完整文档见:http://v2.volcore.xyz/document/api 【代码生成页面ViewGrid】 +**常用示例见:http://v2.volcore.xyz/document/vueDev +**后台操作见:http://v2.volcore.xyz/document/netCoreDev +*****************************************************************************************/ +//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码 + +let extension = { + components: { + //查询界面扩展组件 + gridHeader: '', + gridBody: '', + gridFooter: '', + //新建、编辑弹出框扩展组件 + modelHeader: '', + modelBody: '', + modelFooter: '' + }, + tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写) + buttons: { view: [], box: [], detail: [] }, //扩展的按钮 + methods: { + //下面这些方法可以保留也可以删除 + onInit() { //框架初始化配置前, + //设置排序字段 + this.pagination.sortName = "id"; + this.pagination.order = "desc"; + + //设置页面上显示的按钮个数 + this.maxBtnLength = 3; + + // 格式化数据 + this.dataFormatter(); + }, + onInited() { + let fixeds = ['id','com_status','config_id']; + this.columns.forEach(x=>{ + //设置title列固定 + if (fixeds.includes(x.field)) { + x.fixed=true//也可以设置为right,固定到最右边 + } + }) + }, + searchBefore(param) { + //界面查询前,可以给param.wheres添加查询参数 + //返回false,则不会执行查询 + return true; + }, + searchAfter(result) { + //查询后,result返回的查询数据,可以在显示到表格前处理表格的值 + return true; + }, + addBefore(formData) { + //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值 + return true; + }, + updateBefore(formData) { + //编辑保存前formData为对象,包括明细表、删除行的Id + return true; + }, + rowClick({ row, column, event }) { + //单击行时选中当前行 + this.$refs.table.$refs.table.toggleRowSelection(row); + }, + modelOpenAfter(row) { + //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据 + //(1)判断是编辑还是新建操作: this.currentAction=='Add'; + //(2)给弹出框设置默认值 + //(3)this.editFormFields.字段='xxx'; + //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值 + //看不懂就把输出看:console.log(this.editFormOptions) + }, + dataFormatter() { + this.columns.forEach(column => { + if (column.field == 'run_time') { + column.formatter = (row) => { + return row.run_time && '' + row.run_time + ' 分 ' + } + } + if (column.field == 'turnout_1') { + column.formatter = (row) => { + return row.turnout_1 && '' + row.turnout_1 + ' 件 ' + } + } + if (column.field == 'turnout_2') { + column.formatter = (row) => { + return row.turnout_2 && '' + row.turnout_2 + ' 件 ' + } + } + if (column.field == 'turnout_3') { + column.formatter = (row) => { + return row.turnout_3 && '' + row.turnout_3 + ' 件 ' + } + } + if (column.field == 'turnout_all') { + column.formatter = (row) => { + return row.turnout_all && '' + row.turnout_all + ' 件 ' + } + } + if (column.field == 'schedule_1') { + column.formatter = (row) => { + return row.schedule_1 && '' + row.schedule_1 + ' % ' + } + } + if (column.field == 'schedule_2') { + column.formatter = (row) => { + return row.schedule_2 && '' + row.schedule_2 + ' % ' + } + } + if (column.field == 'schedule_3') { + column.formatter = (row) => { + return row.schedule_3 && '' + row.schedule_3 + ' % ' + } + } + if (column.field == 'yield_1') { + column.formatter = (row) => { + return row.yield_1 && '' + row.yield_1 * 100 + ' % ' + } + } + if (column.field == 'yield_2') { + column.formatter = (row) => { + return row.yield_2 && '' + row.yield_2 * 100 + ' % ' + } + } + if (column.field == 'yield_3') { + column.formatter = (row) => { + return row.yield_3 && '' + row.yield_3 * 100 + ' % ' + } + } + if (column.field == 'oee') { + column.formatter = (row) => { + return row.oee && '' + row.oee * 100 + ' % ' + } + } + + // 标签改色 + if (column.field == 'com_status') { + column.getColor = (row, column) => { + if (row.com_status == 15) { + return 'danger'; + } else if (row.com_status == 5){ + return 'success'; + } else { + return ''; + } + } + } + }) + } + } +}; +export default extension; diff --git a/vol-vue3/src/extension/order/SellOrder.js b/vol-vue3/src/extension/order/SellOrder.js index 015c19c..2524966 100644 --- a/vol-vue3/src/extension/order/SellOrder.js +++ b/vol-vue3/src/extension/order/SellOrder.js @@ -188,6 +188,7 @@ let extension = { //你可以指定param查询的参数,处如果返回false,则不会执行查询 // this.$message.success(this.table.cnName + ',查询前' }); // console.log("扩展的"this.detailOptions.cnName + '触发loadDetailTableBefore'); + console.log(param); return true; }, searchAfter(result) { //查询ViewGird表数据后param查询参数,result回返查询的结果 diff --git a/vol-vue3/src/main.js b/vol-vue3/src/main.js index 25ccdcb..2f9b980 100644 --- a/vol-vue3/src/main.js +++ b/vol-vue3/src/main.js @@ -12,7 +12,8 @@ import http from './api/http' // import locale from 'element-plus/lib/locale/lang/zh-cn' import * as ElementPlusIconsVue from '@element-plus/icons-vue' - +// vue3 引入dataV全局组件 +import dataV from '@jiaminghi/data-view' import permission from './api/permission' import viewgird from './components/basic/ViewGrid'; @@ -59,6 +60,7 @@ app.use(store) .use(ElementPlus, { size: 'default' }) .use(router) .use(viewgird) + .use(dataV) .mount('#app'); app.config.globalProperties.$Message = app.config.globalProperties.$message; diff --git a/vol-vue3/src/mixin/index.js b/vol-vue3/src/mixin/index.js new file mode 100644 index 0000000..f7f1bd7 --- /dev/null +++ b/vol-vue3/src/mixin/index.js @@ -0,0 +1,62 @@ +// 屏幕适配 mixin 函数 +// * 默认缩放值 +const scale = { + width: '1', + height: '1', + } + + // * 设计稿尺寸(px) + const baseWidth = 1920 + const baseHeight = 1080 + + // * 需保持的比例(默认1.77778) + const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) + + export default { + data() { + return { + // * 定时函数 + drawTiming: null + } + }, + mounted () { + this.calcRate() + window.addEventListener('resize', this.resize) + }, + beforeDestroy () { + window.removeEventListener('resize', this.resize) + }, + methods: { + calcRate () { + const appRef = this.$refs["appRef"] // 需要在指定节点上添加 ref="appRef" + console.log(this); + console.log(appRef); + if (!appRef) return + // 当前宽高比 + const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5)) + if (appRef) { + if (currentRate > baseProportion) { + // 表示更宽 + scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5) + scale.height = (window.innerHeight / baseHeight).toFixed(5) + appRef.style.transform = `scale(${scale.width}, ${scale.height})` + // appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)` + } else { + // 表示更高 + scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5) + scale.width = (window.innerWidth / baseWidth).toFixed(5) + appRef.style.transform = `scale(${scale.width}, ${scale.height})` + } + } + }, + resize () { + clearTimeout(this.drawTiming) + this.drawTiming = setTimeout(() => { + this.calcRate() + console.log(scale) + }, 200) + }, + + }, + } + \ No newline at end of file diff --git a/vol-vue3/src/router/index.js b/vol-vue3/src/router/index.js index 4b984ac..3f981cd 100644 --- a/vol-vue3/src/router/index.js +++ b/vol-vue3/src/router/index.js @@ -84,20 +84,38 @@ const routes = [ anonymous:true } }, + // { + // path: '/app/guide', + // name: 'apphome', + // meta: { + // anonymous: true + // }, + // component: () => import('@/views/h5/Guide.vue'), + // }, + // { + // path: '/bigdata', + // name: 'bigdata', + // component: () => import('@/views/charts/bigdata.vue'), + // meta: { + // keepAlive: false + // } + // }, { - path: '/app/guide', - name: 'apphome', + path: '/dataview', + name: 'dataview', + component: () => import('@/views/data/bigscreen/index.vue'), meta: { - anonymous: true - }, - component: () => import('@/views/h5/Guide.vue'), + keepAlive: false, + anonymous: true // 路由无需登录访问 + } }, { - path: '/bigdata', - name: 'bigdata', - component: () => import('@/views/charts/bigdata.vue'), + path: '/datatest', + name: 'datatest', + component: () => import('@/views/data/bigscreen/test.vue'), meta: { - keepAlive: false + keepAlive: false, + anonymous: true // 路由无需登录访问 } } ] diff --git a/vol-vue3/src/router/viewGird.js b/vol-vue3/src/router/viewGird.js index a047b90..6c38105 100644 --- a/vol-vue3/src/router/viewGird.js +++ b/vol-vue3/src/router/viewGird.js @@ -3,132 +3,162 @@ let viewgird = [ { path: '/Sys_Log', name: 'sys_Log', - component: () => import('@/views/system/Sys_Log.vue' ) + component: () => import('@/views/system/Sys_Log.vue') }, { path: '/Sys_User', name: 'Sys_User', - component: () => import('@/views/system/Sys_User.vue' ) + component: () => import('@/views/system/Sys_User.vue') }, { path: '/permission', name: 'permission', - component: () => import('@/views/system/Permission.vue' ) + component: () => import('@/views/system/Permission.vue') }, - + { path: '/Sys_Dictionary', name: 'Sys_Dictionary', - component: () => import('@/views/system/Sys_Dictionary.vue' ) + component: () => import('@/views/system/Sys_Dictionary.vue') }, { path: '/Sys_Role', name: 'Sys_Role', - component: () => import('@/views/system/Sys_Role.vue' ) - }, { + component: () => import('@/views/system/Sys_Role.vue') + }, + { path: '/Sys_Role1', name: 'Sys_Role1', - component: () => import('@/views/system/Sys_Role1.vue' ) - } - , { + component: () => import('@/views/system/Sys_Role1.vue') + }, + { path: '/Sys_DictionaryList', name: 'Sys_DictionaryList', - component: () => import('@/views/system/Sys_DictionaryList.vue' ) - } - , { + component: () => import('@/views/system/Sys_DictionaryList.vue') + }, + { path: '/SellOrder', name: 'SellOrder', - component: () => import('@/views/order/SellOrder.vue' ) - }, { + component: () => import('@/views/order/SellOrder.vue') + }, + { path: '/SellOrder2', name: 'SellOrder2', - component: () => import('@/views/order/SellOrder2.vue' ) - }, { + component: () => import('@/views/order/SellOrder2.vue') + }, + { path: '/SellOrder3', name: 'SellOrder3', - component: () => import('@/views/order/SellOrder3.vue' ) - }, { + component: () => import('@/views/order/SellOrder3.vue') + }, + { path: '/vSellOrderImg', name: 'vSellOrderImg', - component: () => import('@/views/order/vSellOrderImg.vue' ) + component: () => import('@/views/order/vSellOrderImg.vue') }, { path: '/App_Appointment', name: 'App_Appointment', - component: () => import('@/views/order/App_Appointment.vue' ) + component: () => import('@/views/order/App_Appointment.vue') }, { path: '/App_Appointment2', //二级表头 name: 'App_Appointment2', - component: () => import('@/views/order/App_Appointment2.vue' ) + component: () => import('@/views/order/App_Appointment2.vue') }, { path: '/App_TransactionAvgPrice', name: 'App_TransactionAvgPrice', - component: () => import('@/views/appmanager/App_TransactionAvgPrice.vue' ), + component: () => import('@/views/appmanager/App_TransactionAvgPrice.vue'), meta: { keepAlive: false } - } - , { + }, + { path: '/App_Expert', name: 'App_Expert', - component: () => import('@/views/appmanager/App_Expert.vue' ) - } - , { + component: () => import('@/views/appmanager/App_Expert.vue') + }, + { path: '/App_Expert2', name: 'App_Expert2', - component: () => import('@/views/appmanager/App_Expert2.vue' ) - } - , { + component: () => import('@/views/appmanager/App_Expert2.vue') + }, + { path: '/App_Transaction', name: 'App_Transaction', - component: () => import('@/views/appmanager/App_Transaction.vue' ) - } - , { + component: () => import('@/views/appmanager/App_Transaction.vue') + }, + { path: '/App_Transaction2', name: 'App_Transaction2', - component: () => import('@/views/appmanager/App_Transaction2.vue' ) - }, { + component: () => import('@/views/appmanager/App_Transaction2.vue') + }, + { path: '/App_ReportPrice', name: 'App_ReportPrice', - component: () => import('@/views/appmanager/App_ReportPrice.vue' ) - }, { + component: () => import('@/views/appmanager/App_ReportPrice.vue') + }, + { path: '/App_News', name: 'App_News', - component: () => import('@/views/appmanager/App_News.vue' ) - }, { + component: () => import('@/views/appmanager/App_News.vue') + }, + { path: '/App_NewsEditor', name: 'App_NewsEditor', - component: () => import('@/views/appmanager/App_NewsEditor.vue' ) - } ,{ - path: '/FormDesignOptions', - name: 'FormDesignOptions', - component: () => import('@/views/system/form/FormDesignOptions.vue') - } ,{ - path: '/FormCollectionObject', - name: 'FormCollectionObject', - component: () => import('@/views/system/form/FormCollectionObject.vue') - } ,{ - path: '/Sys_WorkFlow', - name: 'Sys_WorkFlow', - component: () => import('@/views/system/flow/Sys_WorkFlow.vue') - } ,{ - path: '/Sys_WorkFlowTable', - name: 'Sys_WorkFlowTable', - component: () => import('@/views/system/flow/Sys_WorkFlowTable.vue') - } ,{ - path: '/Sys_QuartzOptions', - name: 'Sys_QuartzOptions', - component: () => import('@/views/system/quartz/Sys_QuartzOptions.vue') - } ,{ - path: '/Sys_QuartzLog', - name: 'Sys_QuartzLog', - component: () => import('@/views/system/quartz/Sys_QuartzLog.vue') - } ,{ - path: '/Sys_Department', - name: 'Sys_Department', - component: () => import('@/views/system/system/Sys_Department.vue') - }] + component: () => import('@/views/appmanager/App_NewsEditor.vue') + }, + { + path: '/FormDesignOptions', + name: 'FormDesignOptions', + component: () => import('@/views/system/form/FormDesignOptions.vue') + }, + { + path: '/FormCollectionObject', + name: 'FormCollectionObject', + component: () => import('@/views/system/form/FormCollectionObject.vue') + }, + { + path: '/Sys_WorkFlow', + name: 'Sys_WorkFlow', + component: () => import('@/views/system/flow/Sys_WorkFlow.vue') + }, + { + path: '/Sys_WorkFlowTable', + name: 'Sys_WorkFlowTable', + component: () => import('@/views/system/flow/Sys_WorkFlowTable.vue') + }, + { + path: '/Sys_QuartzOptions', + name: 'Sys_QuartzOptions', + component: () => import('@/views/system/quartz/Sys_QuartzOptions.vue') + }, + { + path: '/Sys_QuartzLog', + name: 'Sys_QuartzLog', + component: () => import('@/views/system/quartz/Sys_QuartzLog.vue') + }, + { + path: '/Sys_Department', + name: 'Sys_Department', + component: () => import('@/views/system/system/Sys_Department.vue') + }, + { + path: '/Data_Produce', + name: 'Data_Produce', + component: () => import('@/views/data/produce/Data_Produce.vue') + }, + { + path: '/Data_Config', + name: 'Data_Config', + component: () => import('@/views/data/config/Data_Config.vue') + }, + { + path: '/Data_Machine', + name: 'Data_Machine', + component: () => import('@/views/data/machine/Data_Machine.vue') + } +] export default viewgird diff --git a/vol-vue3/src/uitils/common.js b/vol-vue3/src/uitils/common.js index a745d8d..ef13946 100644 --- a/vol-vue3/src/uitils/common.js +++ b/vol-vue3/src/uitils/common.js @@ -146,7 +146,7 @@ let base = { // $img.src = src; $img.setAttribute('src', src); $div.appendChild($img); - $div.addEventListener('click', function() { + $div.addEventListener('click', function () { this.style.display = 'none'; }); document.body.appendChild($div); @@ -195,7 +195,7 @@ let base = { xmlResquest.setRequestHeader(key, data.header[key]); } } - xmlResquest.onload = function() { + xmlResquest.onload = function () { if (this.status == 200) { var blob = this.response; callback(window.URL.createObjectURL(blob)); @@ -215,7 +215,7 @@ let base = { convertTree(data, callback) { var treeIds = []; var root_data = []; - if (data.length>100) { + if (data.length > 100) { data = JSON.parse(JSON.stringify(data)); } data.forEach((x) => { @@ -251,7 +251,7 @@ let base = { if (!(data instanceof Array)) { return nodes; } - if (data.length>100) { + if (data.length > 100) { data = JSON.parse(JSON.stringify(data)); } data.forEach((x) => { @@ -292,7 +292,7 @@ let base = { if (!(data instanceof Array)) { return nodes; } - if (data.length>100) { + if (data.length > 100) { data = JSON.parse(JSON.stringify(data)); } var _child = data.find((x) => { @@ -324,6 +324,24 @@ let base = { return this.getTreeAllChildren(id, data).map((c) => { return c.id; }); + }, + //使用递归的方式实现数组、对象的深拷贝 + deepClone(obj) { + //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝 + var objClone = Array.isArray(obj) ? [] : {}; + //进行深拷贝的不能为空,并且是对象或者是 + if (obj && typeof obj === "object") { + for (let key in obj) { + if (obj.hasOwnProperty(key)) { + if (obj[key] && typeof obj[key] === "object") { + objClone[key] = this.deepClone(obj[key]); + } else { + objClone[key] = obj[key]; + } + } + } + } + return objClone; } }; export default base; diff --git a/vol-vue3/src/views/Home.vue b/vol-vue3/src/views/Home.vue index 6120451..cf9200a 100644 --- a/vol-vue3/src/views/Home.vue +++ b/vol-vue3/src/views/Home.vue @@ -1,382 +1,20 @@ diff --git a/vol-vue3/src/views/HomeBk.vue b/vol-vue3/src/views/HomeBk.vue new file mode 100644 index 0000000..6120451 --- /dev/null +++ b/vol-vue3/src/views/HomeBk.vue @@ -0,0 +1,382 @@ + + + diff --git a/vol-vue3/src/views/Index.vue b/vol-vue3/src/views/Index.vue index 3dd1bbe..683d740 100644 --- a/vol-vue3/src/views/Index.vue +++ b/vol-vue3/src/views/Index.vue @@ -20,9 +20,9 @@
-
Vol开发框架Vue3版本
+
{{departName}}
-