diff --git a/CVDEMCS/CVDEMCS.csproj b/CVDEMCS/CVDEMCS.csproj
new file mode 100644
index 0000000..160f62b
--- /dev/null
+++ b/CVDEMCS/CVDEMCS.csproj
@@ -0,0 +1,37 @@
+
+
+
+ net6.0
+
+ enable
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+ bin\SDK\HslCommunication.dll
+
+
+
+
diff --git a/CVDEMCS/Common/Constant/Constant.cs b/CVDEMCS/Common/Constant/Constant.cs
new file mode 100644
index 0000000..c46fb5b
--- /dev/null
+++ b/CVDEMCS/Common/Constant/Constant.cs
@@ -0,0 +1,105 @@
+namespace PVDEMCS.Common.Constant
+{
+
+
+ ///
+ /// 点位所属动作
+ ///
+ public sealed class ActionType
+ {
+ ///
+ /// 启动停止
+ ///
+ public const String StartStop = "StartStop";
+
+ ///
+ /// 故障
+ ///
+ public const String Fault = "Fault";
+ }
+
+ ///
+ /// 设备类型
+ ///
+ public sealed class EquipmentType
+ {
+ ///
+ /// Ionbond
+ ///
+ public const String Ionbond = "Ionbond";
+
+ ///
+ /// Balzers
+ ///
+ public const String Balzers = "Balzers";
+
+ ///
+ /// Cemecon
+ ///
+ public const String CemeCon = "CemeCon";
+ }
+
+ ///
+ /// 设备类型补偿
+ ///
+ public sealed class EquipmentTypeOffset
+ {
+ ///
+ /// Ionbond补偿时间
+ ///
+ public const String IonbondOffset = "IonbondOffset";
+
+ ///
+ /// Balzers补偿时间
+ ///
+ public const String BalzersOffset = "BalzersOffset";
+
+ ///
+ /// Cemecon补偿时间
+ ///
+ public const String CemeConOffset = "CemeConOffset";
+ }
+
+
+ ///
+ /// 设备状态
+ ///
+ public sealed class EquipmentState
+ {
+ ///
+ /// 运行
+ ///
+ public const String Run = "Run";
+ ///
+ /// 待机
+ ///
+ public const String Stop = "Stop";
+ ///
+ /// 报警
+ ///
+ public const String Alarm = "Alarm";
+
+ public static readonly string[] States = new string[] { Run, Stop, Alarm };
+
+ public static bool HaveState(string state)
+ {
+ return States.Contains(state);
+ }
+ }
+
+ ///
+ /// 报警模式
+ ///
+ public sealed class EquipmentAlarmModel
+ {
+ ///
+ /// 自动
+ ///
+ public const String Auto = "Auto";
+
+ ///
+ /// 手动
+ ///
+ public const String Manual = "Manual";
+ }
+}
diff --git a/CVDEMCS/Common/DI/AutoFacBuilderExtensions.cs b/CVDEMCS/Common/DI/AutoFacBuilderExtensions.cs
new file mode 100644
index 0000000..eb49365
--- /dev/null
+++ b/CVDEMCS/Common/DI/AutoFacBuilderExtensions.cs
@@ -0,0 +1,59 @@
+using System.Reflection;
+using System.Security.AccessControl;
+using Autofac;
+using Autofac.Extensions.DependencyInjection;
+using Module = Autofac.Module;
+
+namespace PVDEMCS.Common.DI;
+
+///
+/// 自定义扩展 Autofac 方法
+///
+public static class AutoFacBuilderExtensions
+{
+ ///
+ /// 添加Autofac扩展
+ ///
+ ///
+ public static void AddAutofacExt(this WebApplicationBuilder builder)
+ {
+ // 通过工厂替换,把Autofac整合进来
+ builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
+ .ConfigureContainer(
+ build =>
+ {
+ build.RegisterModule(new AutoFacManager());
+ });
+ }
+}
+
+public class AutoFacManager : Module
+{
+ // 重写 Autofac 管道 Load方法, 在这里注入
+ protected override void Load(ContainerBuilder builder)
+ {
+ /* 2、获取接口类型
+ * 通过IDependency标记需要依赖注入的接口
+ * 注册所有实现了IDependency接口的类型
+ */
+ Type baseType = typeof(IDependency);
+ #region 依赖注入
+ /* 3、获取所有程序集
+ * 当CLR COM服务器初始化时,它会创建一个AppDomain。 AppDomain是一组程序集的逻辑容器
+ */
+ var assemblies = AppDomain.CurrentDomain.GetAssemblies();//这种写法AppDomain重新启动后会丢失程序集
+ //var assemblies = Assembly.GetAssembly(baseType);
+ /* 4、自动注册接口
+ * 筛选出对应条件的接口
+ * IsAssignableFrom:返回true的条件:是否直接或间接实现了IDependency
+ * IsAbstract:是否为抽象类
+ * AsImplementedInterfaces:以接口的形式注册
+ * InstancePerLifetimeScope:同一个Lifetime生成的对象是同一个实例
+ */
+ builder.RegisterAssemblyTypes(assemblies).Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract).AsImplementedInterfaces().SingleInstance();
+
+ #endregion
+
+ base.Load(builder);
+ }
+}
\ No newline at end of file
diff --git a/CVDEMCS/Common/DI/IDependency.cs b/CVDEMCS/Common/DI/IDependency.cs
new file mode 100644
index 0000000..25a30c5
--- /dev/null
+++ b/CVDEMCS/Common/DI/IDependency.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PVDEMCS.Common.DI
+{
+ ///
+ /// 依赖注入接口,表示该接口的实现类将自动注册到IoC容器中
+ ///
+ public interface IDependency
+ {
+
+ }
+}
diff --git a/CVDEMCS/Common/EF/EFSqlHelper.cs b/CVDEMCS/Common/EF/EFSqlHelper.cs
new file mode 100644
index 0000000..c890211
--- /dev/null
+++ b/CVDEMCS/Common/EF/EFSqlHelper.cs
@@ -0,0 +1,144 @@
+
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.Common;
+using System.Linq;
+using System.Reflection;
+
+namespace PVDEMCS.Common.EF
+{
+ public static class EFSqlHelper
+ {
+ private class PropertyMapp
+ {
+ public string Name { get; set; }
+ public Type Type { get; set; }
+ public bool IsSame(PropertyMapp mapp)
+ {
+ if (mapp == null)
+ {
+ return false;
+ }
+ bool same = mapp.Name == Name && mapp.Type == Type;
+ return same;
+ }
+ }
+
+ public static DbTransaction GetDbTransaction(this IDbContextTransaction source)
+ {
+ return (source as IInfrastructure).Instance;
+ }
+
+ public static IEnumerable FromSqlQuery(this DbContext context, string query, List parameters = null, CommandType commandType = CommandType.Text, int? commandTimeOutInSeconds = null) where T : new()
+ {
+ return FromSqlQuery(context.Database, query, parameters, commandType, commandTimeOutInSeconds);
+ }
+
+ public static IEnumerable FromSqlQuery(this DatabaseFacade database, string query, List parameters = null, CommandType commandType = CommandType.Text, int? commandTimeOutInSeconds = null) where T : new()
+ {
+ const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
+ List entityFields = (from PropertyInfo aProp in typeof(T).GetProperties(flags)
+ select new PropertyMapp
+ {
+ Name = aProp.Name,
+ Type = Nullable.GetUnderlyingType(aProp.PropertyType) ?? aProp.PropertyType
+ }).ToList();
+ List dbDataReaderFields = new List();
+ List commonFields = null;
+
+ using (var command = database.GetDbConnection().CreateCommand())
+ {
+ if (command.Connection.State != ConnectionState.Open)
+ {
+ command.Connection.Open();
+ }
+ var currentTransaction = database.CurrentTransaction;
+ if (currentTransaction != null)
+ {
+ command.Transaction = currentTransaction.GetDbTransaction();
+ }
+ command.CommandText = query;
+ command.CommandType = commandType;
+ if (commandTimeOutInSeconds != null)
+ {
+ command.CommandTimeout = (int)commandTimeOutInSeconds;
+ }
+ if (parameters != null)
+ {
+ command.Parameters.AddRange(parameters.ToArray());
+ }
+ using (var result = command.ExecuteReader())
+ {
+ while (result.Read())
+ {
+ if (commonFields == null)
+ {
+ for (int i = 0; i < result.FieldCount; i++)
+ {
+ dbDataReaderFields.Add(new PropertyMapp
+ {
+ Name = result.GetName(i),
+ Type = result.GetFieldType(i)
+ });
+ }
+ commonFields = entityFields.Where
+ (x => dbDataReaderFields.Any(d =>
+ d.IsSame(x))).Select(x => x).ToList();
+ }
+
+ var entity = new T();
+ foreach (var aField in commonFields)
+ {
+ PropertyInfo propertyInfos = entity.GetType().GetProperty(aField.Name);
+ var value = (result[aField.Name] == DBNull.Value) ? null : result[aField.Name]; //if field is nullable
+ propertyInfos.SetValue(entity, value, null);
+ }
+ yield return entity;
+ }
+ }
+ }
+ }
+
+ public static IEnumerable FromSqlQuery(this DbContext context, string query, Func map, List parameters = null, CommandType commandType = CommandType.Text, int? commandTimeOutInSeconds = null)
+ {
+ return FromSqlQuery(context.Database, query, map, parameters, commandType, commandTimeOutInSeconds);
+ }
+
+ public static IEnumerable FromSqlQuery(this DatabaseFacade database, string query, Func map, List parameters = null, CommandType commandType = CommandType.Text, int? commandTimeOutInSeconds = null)
+ {
+ using (var command = database.GetDbConnection().CreateCommand())
+ {
+ if (command.Connection.State != ConnectionState.Open)
+ {
+ command.Connection.Open();
+ }
+ var currentTransaction = database.CurrentTransaction;
+ if (currentTransaction != null)
+ {
+ command.Transaction = currentTransaction.GetDbTransaction();
+ }
+ command.CommandText = query;
+ command.CommandType = commandType;
+ if (commandTimeOutInSeconds != null)
+ {
+ command.CommandTimeout = (int)commandTimeOutInSeconds;
+ }
+ if (parameters != null)
+ {
+ command.Parameters.AddRange(parameters.ToArray());
+ }
+ using (var result = command.ExecuteReader())
+ {
+ while (result.Read())
+ {
+ yield return map(result);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/CVDEMCS/Common/Log/LogExtensions.cs b/CVDEMCS/Common/Log/LogExtensions.cs
new file mode 100644
index 0000000..b97b2fc
--- /dev/null
+++ b/CVDEMCS/Common/Log/LogExtensions.cs
@@ -0,0 +1,100 @@
+using GuideScreen.Common.Common;
+using PVDEMCS.Services;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PVDEMCS.Common.Log
+{
+ ///
+ /// 日志扩展
+ ///
+ public static class LogExtensions
+ {
+ private static ILogService _logService;
+
+ static LogExtensions()
+ {
+
+ }
+
+ ///
+ /// 日志服务
+ ///
+ public static void Load(ILogService logService)
+ {
+ _logService = logService;
+ }
+ ///
+ /// 写入Error级别日志
+ ///
+ /// 异常对象
+ public static void WriteErrorLog(this Exception ex)
+ {
+ var error = new StringBuilder();
+ while (ex != null)
+ {
+ error.AppendLine($"{ex.Message}:{Environment.NewLine}");
+ error.AppendLine($"{ex.StackTrace};");
+ ex = ex.InnerException;
+ }
+ _logService.Error(error.ToString());
+ }
+
+ ///
+ /// 写入Fatal级别日志
+ ///
+ /// 异常对象
+ public static void WriteFatalLog(this Exception ex)
+ {
+ var error = new StringBuilder();
+ while (ex != null)
+ {
+ error.AppendLine($"{ex.Message}:{Environment.NewLine}");
+ error.AppendLine($"{ex.StackTrace};");
+ ex = ex.InnerException;
+ }
+ _logService.Fatal(error.ToString());
+ }
+
+ ///
+ /// 写入info级别日志
+ ///
+ ///
+ public static void WriteInfoLog(this string str)
+ {
+ _logService.Info(str);
+ }
+
+ ///
+ /// 写入debug级别日志
+ ///
+ ///
+ public static void WriteDebugLog(this string str)
+ {
+ _logService.Debug(str);
+ }
+
+ ///
+ /// 写入Error级别日志
+ ///
+ ///
+ public static void WriteErrorLog(this string str)
+ {
+ _logService.Error(str);
+ }
+
+ ///
+ /// 写入Error级别日志
+ ///
+ ///
+ public static void WriteFatalLog(this string str)
+ {
+ _logService.Fatal(str);
+ }
+ }
+}
diff --git a/CVDEMCS/Common/Log/LogInfoLevel.cs b/CVDEMCS/Common/Log/LogInfoLevel.cs
new file mode 100644
index 0000000..34e42ab
--- /dev/null
+++ b/CVDEMCS/Common/Log/LogInfoLevel.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GuideScreen.Common.Common
+{
+ ///
+ /// 日志级别
+ ///
+ public enum LogInfoLevel
+ {
+ /*信息级别*/
+ Info,
+ /*debug级别*/
+ Debug,
+ /*错误级别*/
+ Error,
+ /*致命级别*/
+ Fatal
+ }
+
+}
diff --git a/CVDEMCS/Common/Result.cs b/CVDEMCS/Common/Result.cs
new file mode 100644
index 0000000..ad001c6
--- /dev/null
+++ b/CVDEMCS/Common/Result.cs
@@ -0,0 +1,79 @@
+using HslCommunication;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PVDEMCS.Common
+{
+ public class Result
+ {
+ //
+ // 摘要:
+ // 指示本次操作是否成功。
+ // Indicates whether this operation was successful.
+ public bool IsSuccess { get; set; } = true;
+
+ //
+ // 摘要:
+ // 具体的错误描述。
+ // Specific error description.
+ public string Message { get; set; }
+
+
+ public int ErrorCode { get; set; }
+
+ //
+ // 摘要:
+ // 实例化一个默认的结果对象
+ public Result()
+ {
+ }
+
+ //
+ // 摘要:
+ // 使用指定的消息实例化一个默认的结果对象
+ //
+ // 参数:
+ // msg:
+ // 错误消息
+ public Result(string msg)
+ {
+ IsSuccess = false;
+ Message = msg;
+ }
+
+ //
+ // 摘要:
+ // 使用错误代码,消息文本来实例化对象
+ //
+ // 参数:
+ // err:
+ // 错误代码
+ //
+ // msg:
+ // 错误消息
+ public Result(int err, string msg)
+ {
+ IsSuccess = false;
+ ErrorCode = err;
+ Message = msg;
+ }
+ }
+
+ public class Result : Result
+ {
+ public T Content { get; set; }
+
+ public Result()
+ {
+
+ }
+
+ public Result(T content)
+ {
+ Content = content;
+ }
+ }
+}
diff --git a/CVDEMCS/Common/Tools/ModelTools.cs b/CVDEMCS/Common/Tools/ModelTools.cs
new file mode 100644
index 0000000..9a9a0b0
--- /dev/null
+++ b/CVDEMCS/Common/Tools/ModelTools.cs
@@ -0,0 +1,96 @@
+using AngleSharp.Dom;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PVDEMCS.Common.Tools
+{
+ public class ModelTools
+ {
+ public static class PubClone
+ {
+ private static readonly Func cache = GetFunc();
+
+ private static Func GetFunc()
+ {
+ var parameterExpression = Expression.Parameter(typeof(TEntity), "p");
+ List memberBindingList = new List();
+
+ foreach (var item in typeof(TResult).GetProperties())
+ {
+ if (!item.CanWrite)
+ {
+ continue;
+ }
+
+ var _Property = typeof(TEntity).GetProperty(item.Name);
+ if (_Property == null)
+ {
+ continue;
+ }
+ if (item.PropertyType.FullName != _Property.PropertyType.FullName)
+ {
+ continue;
+ }
+
+ MemberExpression property = Expression.Property(parameterExpression, typeof(TEntity).GetProperty(item.Name));
+ MemberBinding memberBinding = Expression.Bind(item, property);
+ memberBindingList.Add(memberBinding);
+ }
+
+ MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TResult)), memberBindingList.ToArray());
+ Expression> lambda = Expression.Lambda>(memberInitExpression, new ParameterExpression[] { parameterExpression });
+
+ return lambda.Compile();
+ }
+
+ public static TResult Trans(TEntity tIn)
+ {
+ if (tIn == null)
+ {
+ return default;
+ }
+ return cache(tIn);
+ }
+
+ public static List TransList(List list)
+ {
+ List result = new List();
+ foreach (var item in list)
+ {
+ result.Add(Trans(item));
+ }
+ return result;
+ }
+ }
+
+ public static void SetUpdateModel(TEntity entity)
+ {
+ foreach (var item in typeof(TEntity).GetProperties())
+ {
+ if (!item.CanWrite)
+ {
+ continue;
+ }
+
+ var _Property = typeof(TEntity).GetProperty(item.Name);
+ if (_Property == null)
+ {
+ continue;
+ }
+ if (item.PropertyType.FullName != _Property.PropertyType.FullName)
+ {
+ continue;
+ }
+
+ if (item.Name == "")
+ {
+
+ }
+ }
+ }
+ }
+}
diff --git a/CVDEMCS/Controllers/DeviceController.cs b/CVDEMCS/Controllers/DeviceController.cs
new file mode 100644
index 0000000..09768e0
--- /dev/null
+++ b/CVDEMCS/Controllers/DeviceController.cs
@@ -0,0 +1,254 @@
+using AngleSharp.Dom;
+using Masuit.Tools;
+using Masuit.Tools.Models;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using PVDEMCS.Common;
+using PVDEMCS.Common.Constant;
+using PVDEMCS.Devices;
+using PVDEMCS.Devices.Impl;
+using PVDEMCS.Services;
+using PVDEMCS.Services.Models;
+using SharpCompress.Common;
+using System;
+
+namespace PVDEMCS.Controllers
+{
+ ///
+ /// PLC控制器
+ ///
+ [ApiController]
+ [Route("[controller]/[action]")]
+ public class DeviceController : Controller
+ {
+ private IDeviceService _deviceService;
+ private IDeviceRun _deviceRun;
+
+ public DeviceController(IDeviceService deviceService, IDeviceRun deviceRun)
+ {
+ _deviceService = deviceService;
+ _deviceRun = deviceRun;
+ }
+ #region PLC控制器
+
+ ///
+ /// 获取PLC控制器分页列表
+ ///
+ /// 控制器编号
+ /// 控制器名称
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ [HttpGet]
+ public Result> GetDevicePageList(string deviceCode, string deviceName, bool? activated, int page, int size = 20)
+ {
+ var result = _deviceService.GetDevicePageList(deviceCode, deviceName, activated, page, size);
+ if (result.IsSuccess)
+ {
+ GetDeviceIsConnected(result.Content.Data);
+ }
+ return result;
+ }
+
+
+ ///
+ /// 获取PLC控制器列表
+ ///
+ /// 控制器编号
+ /// 控制器名称
+ /// 是否启用
+ /// ///
+ [HttpGet]
+ public Result> GetDeviceInfoList(string deviceCode, string deviceName, bool? activated = null)
+ {
+ var result = _deviceService.GetDeviceInfoList(deviceCode, deviceName, activated);
+ if (result.IsSuccess)
+ {
+ GetDeviceIsConnected(result.Content);
+ }
+ return result;
+ }
+
+ [NonAction]
+ private void GetDeviceIsConnected(List list)
+ {
+ if (!list.IsNullOrEmpty() && !_deviceRun.GetDeviceIsConnected.IsNullOrEmpty())
+ {
+ foreach (var item in list)
+ {
+ if (_deviceRun.GetDeviceIsConnected.Keys.Contains(item.DeviceCode))
+ {
+ item.isConnected = _deviceRun.GetDeviceIsConnected[item.DeviceCode];
+ }
+ }
+ }
+ }
+
+ ///
+ /// 获取PLC控制器明细
+ ///
+ /// 主键Id
+ ///
+ [HttpGet]
+ public Result GetDeviceDetail(string id)
+ {
+ var result = _deviceService.GetDeviceDetail(id);
+ return result;
+ }
+
+ ///
+ /// 添加PLC控制器
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result AddDevice(DeviceInfo entity)
+ {
+ var result = _deviceService.AddDevice(entity);
+ _deviceRun.Run();
+ return result;
+ }
+
+ ///
+ /// 更新PLC控制器
+ ///
+ ///
+ [HttpPost]
+ public Result UpdateDevice(DeviceInfo entity)
+ {
+ var result = _deviceService.UpdateDevice(entity);
+ _deviceRun.Run();
+ return result;
+ }
+
+ ///
+ /// 删除PLC控制器
+ ///
+ ///
+ [HttpPost]
+ public Result DeleteDevice(string id)
+ {
+ var result = _deviceService.DeleteDevice(id);
+ _deviceRun.Run();
+ return result;
+ }
+
+ #endregion
+
+ #region PLC点位
+
+ ///
+ /// 获取PLC控制器点位分页列表
+ ///
+ /// 控制器Id
+ /// 控制器编号
+ /// 控制器名称
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 点位编号
+ /// 点位列表
+ /// 当前页
+ /// 页大小
+ ///
+ [HttpGet]
+ public Result> GetDevicePointPageList(string deviceId, string deviceName, string deviceCode, string equipmentName, string equipmentCode, string equipmentType, string pointCode, string pointName, bool? activated, int page, int size = 20)
+ {
+ var result = _deviceService.GetDevicePointPageList(deviceId, deviceName, deviceCode, equipmentName, equipmentCode, equipmentType, pointCode, pointName, activated, page, size);
+ if (result.IsSuccess)
+ {
+ GetPointValue(result.Content.Data);
+ }
+ return result;
+ }
+
+ ///
+ /// 获取PLC控制器点位列表
+ ///
+ /// 控制器Id
+ /// 控制器编号
+ /// 控制器名称
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 点位编号
+ /// 点位列表
+ ///
+ [HttpGet]
+ public Result> GetDevicePointList(string deviceId, string deviceName, string deviceCode, string equipmentName, string equipmentCode, string equipmentType, string pointCode, string pointName, bool? activated)
+ {
+ var result = _deviceService.GetDevicePointList(deviceId, deviceName, deviceCode, equipmentName, equipmentCode, equipmentType, pointCode, pointName, activated);
+ GetPointValue(result.Content);
+ return result;
+ }
+
+ [NonAction]
+ private void GetPointValue(List list)
+ {
+ var points = _deviceRun.GetDevicePoints;
+ if (!list.IsNullOrEmpty() && !points.IsNullOrEmpty())
+ {
+ foreach (var item in list)
+ {
+ item.ObjectValue = points.Where(f => f.PointCode == item.PointCode).Select(f => f.ObjectValue).FirstOrDefault();
+ }
+ }
+ }
+
+ ///
+ /// 获取PLC控制器点位明细
+ ///
+ /// Id
+ ///
+ [HttpGet]
+ public Result GetDevicePointDetail(string id)
+ {
+ var result = _deviceService.GetDevicePointDetail(id);
+ return result;
+ }
+
+ ///
+ /// 添加PLC控制器点位
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result AddDevicePoint(DevicePoint entity)
+ {
+ var result = _deviceService.AddDevicePoint(entity);
+ _deviceRun.Run();
+ return result;
+ }
+
+ ///
+ /// 更新PLC控制器点位
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result UpdateDevicePoint(DevicePoint entity)
+ {
+ var result = _deviceService.UpdateDevicePoint(entity);
+ _deviceRun.Run();
+ return result;
+ }
+
+ ///
+ /// 删除PLC控制器点位
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result DeleteDevicePoint(string id)
+ {
+ var result = _deviceService.DeleteDevicePoint(id);
+ _deviceRun.Run();
+ return result;
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/CVDEMCS/Controllers/EquipmentController.cs b/CVDEMCS/Controllers/EquipmentController.cs
new file mode 100644
index 0000000..8d88d52
--- /dev/null
+++ b/CVDEMCS/Controllers/EquipmentController.cs
@@ -0,0 +1,114 @@
+using Masuit.Tools;
+using Masuit.Tools.Models;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using PVDEMCS.Common;
+using PVDEMCS.Common.Constant;
+using PVDEMCS.Devices;
+using PVDEMCS.Services;
+using PVDEMCS.Services.Impl;
+using PVDEMCS.Services.Models;
+using System;
+
+namespace PVDEMCS.Controllers
+{
+ ///
+ /// 设备管理
+ ///
+ [ApiController]
+ [Route("[controller]/[action]")]
+ public class EquipmentController : Controller
+ {
+ private IEquipmentService _equipmentService;
+ private IDeviceRun _deviceRun;
+
+ public EquipmentController(IEquipmentService equipmentService, IDeviceRun deviceRun)
+ {
+ this._equipmentService = equipmentService;
+ _deviceRun = deviceRun;
+ }
+ ///
+ /// 获取设备分页列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ [HttpGet]
+ public Result> GetEquipmentPageList(string equipmentName, string equipmentCode, string equipmentType, bool? activated, int page, int size = 20)
+ {
+ var result = this._equipmentService.GetEquipmentPageList(equipmentName, equipmentCode, equipmentType, activated, page, size);
+
+ return result;
+ }
+
+ ///
+ /// 获取设备列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 是否启用
+ [HttpGet]
+ public Result> GetEquipmentList(string equipmentName, string equipmentCode, string equipmentType, bool? activated)
+ {
+ var result = this._equipmentService.GetEquipmentList(equipmentName, equipmentCode, equipmentType, activated);
+
+ return result;
+ }
+
+
+ ///
+ /// 获取设备明显
+ ///
+ ///
+ ///
+ [HttpGet]
+ public Result GetEquipmentDetail(string id)
+ {
+ var result = this._equipmentService.GetEquipmentDetail(id);
+ return result;
+ }
+
+ ///
+ /// 添加设备信息
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result AddEquipment(EquipmentInfo info)
+ {
+ var result = this._equipmentService.AddEquipment(info);
+ _deviceRun.Run();
+ return result;
+ }
+
+ ///
+ /// 更新设备信息
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result UpdateEquipment(EquipmentInfo info)
+ {
+ var result = this._equipmentService.UpdateEquipment(info);
+ _deviceRun.Run();
+ return result;
+ }
+
+ ///
+ /// 删除设备信息
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result DeleteEquipment(string id)
+ {
+ var result = this._equipmentService.DeleteEquipment(id);
+ _deviceRun.Run();
+ return result;
+ }
+ }
+}
diff --git a/CVDEMCS/Controllers/EquipmentRecordController.cs b/CVDEMCS/Controllers/EquipmentRecordController.cs
new file mode 100644
index 0000000..fead807
--- /dev/null
+++ b/CVDEMCS/Controllers/EquipmentRecordController.cs
@@ -0,0 +1,344 @@
+using Masuit.Tools;
+using Masuit.Tools.Models;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using PVDEMCS.Common;
+using PVDEMCS.Common.Constant;
+using PVDEMCS.Services;
+using PVDEMCS.Services.Models;
+using System;
+
+namespace PVDEMCS.Controllers
+{
+ ///
+ /// 设备数据记录与统计
+ ///
+ [ApiController]
+ [Route("[controller]/[action]")]
+ public class EquipmentRecordController : Controller
+ {
+ private IEquipmentRecordService _equipmentRecordService;
+ private IEquipmentService _equipmentService;
+
+ public EquipmentRecordController(IEquipmentRecordService equipmentRecordService, IEquipmentService equipmentService)
+ {
+ this._equipmentRecordService = equipmentRecordService;
+ this._equipmentService = equipmentService;
+ }
+
+ #region 设备状态记录
+
+ ///
+ /// 获取设备状态记录分页列表(分钟)
+ ///
+ /// 设备Id
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ ///
+ [HttpGet]
+ public Result> GetEquipmentRecordPageList(string equipmentId, string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size = 20)
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordPageList(equipmentId, equipmentName, equipmentCode, equipmentType, begTime, endTime, page, size);
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录列表(分钟)
+ ///
+ /// 设备Id
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ ///
+ [HttpGet]
+ public Result> GetEquipmentRecordList(string equipmentId, string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime)
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordList(equipmentId, equipmentName, equipmentCode, equipmentType, begTime, endTime);
+ return result;
+ }
+
+ ///
+ /// 添加或更新设备状态记录
+ /// 1.如果设备最新记录状态没有改变则更新结束时间
+ /// 2.如果没有记录则添加记录
+ ///
+ /// 设备Id
+ /// 设备状态,运行:Run,待机:Stop,报警:Alarm
+ /// 记录时间
+ ///
+ //[HttpPost]
+ //public Result AddUpdateEquipmentRecord(string equipmentId, string state, DateTime dateTime)
+ //{
+ // var result = _equipmentRecordService.AddUpdateEquipmentRecord(equipmentId, state, dateTime);
+ // return result;
+ //}
+
+ /////
+ ///// 进行设备状态记录统计(日统计)
+ /////
+ /////
+ /////
+ //[HttpPost]
+ //public Result RunEquipmentRecordTotal(DateTime date)
+ //{
+ // var result = _equipmentRecordService.RunEquipmentRecordTotal(date);
+ // return result;
+ //}
+
+ #endregion
+
+ #region 设备记录统计
+
+ ///
+ /// 获取设备状态记录统计(日)分页列表(分钟)
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ [HttpGet]
+ public Result> GetEquipmentRecordDayTotalPageList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size = 20)
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordDayTotalPageList(equipmentName, equipmentCode, equipmentType, begTime, endTime, page, size);
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录统计(日)列表(分钟)
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ [HttpGet]
+ public Result> GetEquipmentRecordDayTotalList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime)
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordDayTotalList(equipmentName, equipmentCode, equipmentType, begTime, endTime);
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录统计分页列表(小时)
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ [HttpGet]
+ public Result> GetEquipmentRecordTotalPageList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size = 20)
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordTotalPageList(equipmentName, equipmentCode, equipmentType, begTime, endTime, page, size);
+ if (result.IsSuccess)
+ {
+ foreach (var item in result.Content.Data)
+ {
+ item.TotalAlarmTime = Math.Round(item.TotalAlarmTime / 60, 2);
+ item.TotalStopTime = Math.Round(item.TotalStopTime / 60, 2);
+ item.TotalRunningTime = Math.Round(item.TotalRunningTime / 60, 2);
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录统计列表(小时)
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ [HttpGet]
+ public Result> GetEquipmentRecordTotalList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime)
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordTotalList(equipmentName, equipmentCode, equipmentType, begTime, endTime);
+ if (result.IsSuccess)
+ {
+ foreach (var item in result.Content)
+ {
+ item.TotalAlarmTime = Math.Round(item.TotalAlarmTime / 60, 2);
+ item.TotalStopTime = Math.Round(item.TotalStopTime / 60, 2);
+ item.TotalRunningTime = Math.Round(item.TotalRunningTime / 60, 2);
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// 根据设备Id获取记录统计(小时)
+ ///
+ /// 设备Id
+ ///
+ [HttpGet]
+ public Result GetEquipmentRecordTotalDetail(string equipmentId)
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordTotalDetail(equipmentId);
+ if (result.IsSuccess && !result.Content.IsNullOrEmpty())
+ {
+ result.Content.TotalAlarmTime = Math.Round(result.Content.TotalAlarmTime / 60, 2);
+ result.Content.TotalStopTime = Math.Round(result.Content.TotalStopTime / 60, 2);
+ result.Content.TotalRunningTime = Math.Round(result.Content.TotalRunningTime / 60, 2);
+ }
+ return result;
+ }
+
+ ///
+ /// 获取设备OEE信息
+ ///
+ /// 设备Id
+ /// 开始时间
+ /// 结束时间
+ ///
+ [HttpGet]
+ public Result GetEquipmentOEEMonthTotal(string equipmentId, DateTime begDate, DateTime endDate)
+ {
+ var result = _equipmentRecordService.GetEquipmentOEEMonthTotal(equipmentId, begDate, endDate);
+ if (result.IsSuccess && !result.Content.IsNullOrEmpty())
+ {
+ result.Content.TotalAlarmTime = Math.Round(result.Content.TotalAlarmTime / 60, 2);
+ result.Content.TotalStopTime = Math.Round(result.Content.TotalStopTime / 60, 2);
+ result.Content.TotalRunningTime = Math.Round(result.Content.TotalRunningTime / 60, 2);
+ }
+ return result;
+ }
+
+ ///
+ /// 获取设备总览
+ ///
+ ///
+ [HttpGet]
+ public Result> GetEquipmentStateView()
+ {
+ var equipments = _equipmentService.GetEquipmentList();
+ var ret = new List();
+ //获取所有设备状态汇总
+ var allTotal = equipments.Content.GroupBy(f => f.State).Select(f => new
+ {
+ State = f.Key,
+ count = f.Count()
+ }).ToList();
+ var equipmentStateView = new EquipmentStateView();
+ equipmentStateView.EquipmentType = "All";
+ var alarm = allTotal.Where(f => f.State == EquipmentState.Alarm).FirstOrDefault();
+ if (!alarm.IsNullOrEmpty())
+ {
+ equipmentStateView.Alarm = alarm.count;
+ }
+ var run = allTotal.Where(f => f.State == EquipmentState.Run).FirstOrDefault();
+ if (!run.IsNullOrEmpty())
+ {
+ equipmentStateView.Run = run.count;
+ }
+ var stop = allTotal.Where(f => f.State == EquipmentState.Stop).FirstOrDefault();
+ if (!stop.IsNullOrEmpty())
+ {
+ equipmentStateView.Stop = stop.count;
+ }
+ ret.Add(equipmentStateView);
+ //根据设备类型获取状态汇总
+ var equimentTypeTotal = equipments.Content.GroupBy(f => new { f.EquipmentType, f.State }).Select(f => new
+ {
+ equipmentType = f.Key.EquipmentType,
+ State = f.Key.State,
+ count = f.Count()
+ }).ToList();
+ var equimentTypes = new string[] { EquipmentType.Balzers, EquipmentType.CemeCon, EquipmentType.Ionbond };
+ foreach (var type in equimentTypes)
+ {
+ equipmentStateView = new EquipmentStateView();
+ equipmentStateView.EquipmentType = type;
+ if (equimentTypeTotal.Count > 0)
+ {
+ var alarmType = equimentTypeTotal.Where(f => f.State == EquipmentState.Alarm && f.equipmentType == type).FirstOrDefault();
+ if (!alarmType.IsNullOrEmpty())
+ {
+ equipmentStateView.Alarm = alarmType.count;
+ }
+ var runType = equimentTypeTotal.Where(f => f.State == EquipmentState.Run && f.equipmentType == type).FirstOrDefault();
+ if (!runType.IsNullOrEmpty())
+ {
+ equipmentStateView.Run = runType.count;
+ }
+ var stopType = equimentTypeTotal.Where(f => f.State == EquipmentState.Stop && f.equipmentType == type).FirstOrDefault();
+ if (!stopType.IsNullOrEmpty())
+ {
+ equipmentStateView.Stop = stopType.count;
+ }
+ }
+ ret.Add(equipmentStateView);
+ }
+
+ return new Result>(ret);
+ }
+
+ ///
+ /// 获取报警设备列表
+ ///
+ ///
+ [HttpGet]
+ public Result> GetEquipmentAlarmList()
+ {
+ var equipments = _equipmentService.GetEquipmentList();
+ var alarmList = equipments.Content.Where(f => f.State == EquipmentState.Alarm).ToList();
+ return new Result>(alarmList);
+ }
+
+ ///
+ /// 获取设备状态记录月统计(小时)
+ ///
+ ///
+ [HttpGet]
+ public Result> GetEquipmentRecordStateMonthTotal()
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordStateMonthTotal();
+ if (result.IsSuccess)
+ {
+ foreach (var item in result.Content)
+ {
+ item.TotalAlarmTime = Math.Round(item.TotalAlarmTime / 60, 2);
+ item.TotalStopTime = Math.Round(item.TotalStopTime / 60, 2);
+ item.TotalRunningTime = Math.Round(item.TotalRunningTime / 60, 2);
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// 获取设备记录开炉次数月统计
+ ///
+ ///
+ [HttpGet]
+ public Result> GetEquipmentRecordFurnaceMonthTotal()
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordFurnaceMonthTotal();
+ return result;
+ }
+
+ ///
+ /// 获取设备记录OEE月统计
+ ///
+ ///
+ [HttpGet]
+ public Result> GetEquipmentRecordOEEMonthTotal()
+ {
+ var result = _equipmentRecordService.GetEquipmentRecordOEEMonthTotal();
+ return result;
+ }
+
+ #endregion
+ }
+}
diff --git a/CVDEMCS/Controllers/SysConfigController.cs b/CVDEMCS/Controllers/SysConfigController.cs
new file mode 100644
index 0000000..c93b4ea
--- /dev/null
+++ b/CVDEMCS/Controllers/SysConfigController.cs
@@ -0,0 +1,111 @@
+using Masuit.Tools.Models;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using PVDEMCS.Common;
+using PVDEMCS.Services;
+using PVDEMCS.Services.Models;
+using System.Xml.Linq;
+
+namespace PVDEMCS.Controllers
+{
+ ///
+ /// 系统参数设置
+ ///
+ [ApiController]
+ [Route("[controller]/[action]")]
+ public class SysConfigController : Controller
+ {
+ private ISysConfigService _sysConfigService;
+ public SysConfigController(ISysConfigService sysConfigService)
+ {
+ this._sysConfigService = sysConfigService;
+ }
+ ///
+ /// 获取系统参数设置分页列表
+ ///
+ /// 参数名称
+ /// 参数键值
+ /// 当前页
+ /// 页大小
+ ///
+ [HttpGet]
+ public Result> GetSysConfigPageList(string configName, string configKey, int page, int size = 20)
+ {
+ var result = this._sysConfigService.GetSysConfigPageList(configName, configKey, page, size);
+ return result;
+ }
+
+ ///
+ /// 获取系统参数设置列表
+ ///
+ /// 参数名称
+ /// 参数键值
+ ///
+ [HttpGet]
+ public Result> GetSysConfigList(string configName, string configKey)
+ {
+ var result = this._sysConfigService.GetSysConfigList(configName, configKey);
+ return result;
+ }
+
+ ///
+ /// 获取获取系统参数设置明细
+ ///
+ ///
+ ///
+ [HttpGet]
+ public Result GetSysConfigDetailById(string id)
+ {
+ var result = this._sysConfigService.GetSysConfigDetailById(id);
+ return result;
+ }
+
+ ///
+ /// 获取获取系统参数设置明细
+ ///
+ ///
+ /// ///
+ ///
+ [HttpGet]
+ public Result GetSysConfigDetailNameOrKey(string name, string key = "")
+ {
+ var result = this._sysConfigService.GetSysConfigDetailNameOrKey(name, key);
+ return result;
+ }
+
+ ///
+ /// 添加系统参数设置
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result AddSysConfig(SysConfig info)
+ {
+ var result = this._sysConfigService.AddSysConfig(info);
+ return result;
+ }
+
+ ///
+ /// 更新系统参数设置
+ ///
+ ///
+ [HttpPost]
+ public Result UpdateSysConfig(SysConfig info)
+ {
+ var result = this._sysConfigService.UpdateSysConfig(info);
+ return result;
+ }
+
+ ///
+ /// 删除系统参数设置
+ ///
+ ///
+ [HttpPost]
+ public Result DeleteSysConfig(string id)
+ {
+ var result = this._sysConfigService.DeleteSysConfig(id);
+ return result;
+ }
+ }
+}
diff --git a/CVDEMCS/Controllers/UserController.cs b/CVDEMCS/Controllers/UserController.cs
new file mode 100644
index 0000000..528d371
--- /dev/null
+++ b/CVDEMCS/Controllers/UserController.cs
@@ -0,0 +1,166 @@
+using Masuit.Tools.Models;
+using Microsoft.AspNetCore.Mvc;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services;
+using System;
+using Masuit.Tools.Security;
+using Masuit.Tools;
+using Microsoft.AspNetCore.Identity;
+using System.Security.Policy;
+
+namespace PVDEMCS.Controllers
+{
+ ///
+ /// 用户信息
+ ///
+ [ApiController]
+ [Route("[controller]/[action]")]
+ public class UserController : Controller
+ {
+ private string salt = "75846542";
+ private ISysUserService _sysUserService;
+
+ public UserController(ISysUserService sysUserService)
+ {
+ this._sysUserService = sysUserService;
+ }
+
+ ///
+ /// 获取用户信息分页列表
+ ///
+ /// 用户名
+ /// 是否其哟个
+ /// 当前页
+ /// 页大小
+ ///
+ [HttpGet]
+ public Result> GetSysUserPageList(string userName, bool? activated, int page, int size = 20)
+ {
+ var result = this._sysUserService.GetSysUserPageList(userName, activated, page, size);
+ return result;
+ }
+
+ ///
+ /// 登录
+ ///
+ /// 用户名
+ /// 密码
+ ///
+ [HttpPost]
+ public Result Lgoin(string userName, string pwd)
+ {
+ var user = _sysUserService.GetSysUserDetail("", userName);
+ if (!user.IsSuccess)
+ {
+ return user;
+ }
+ if (!user.Content.IsNullOrEmpty())
+ {
+ var value = Hash(pwd);
+ if (user.Content.Password == value)
+ {
+ user.Content.Password = null;
+ return user;
+ }
+ }
+ user.Content = null;
+ user.Message = "用户名或密码不正确!";
+ return user;
+ }
+
+ ///
+ /// 修改密码
+ ///
+ /// 用户id
+ /// 旧密码
+ /// 新密码
+ ///
+ [HttpPost]
+ public Result UpdatePassword(string id, string oldPwd, string newPwd)
+ {
+ var result = this._sysUserService.GetSysUserDetail(id, "");
+ if (!result.IsSuccess)
+ {
+ return result;
+ }
+
+ var old = Hash(oldPwd);
+ if (old != result.Content.Password)
+ {
+ return new Result("原密码不正确!");
+ }
+
+ var pwd = Hash(newPwd);
+ var res = _sysUserService.UpdatePassword(id, pwd);
+ if (!res.IsSuccess)
+ {
+ return res;
+ }
+ return new Result();
+
+ }
+
+ ///
+ /// 获取用户明细
+ ///
+ /// 用户id
+ ///
+ [HttpGet]
+ public Result GetSysUserDetail(string id)
+ {
+ var result = this._sysUserService.GetSysUserDetail(id, "");
+ if (result.IsSuccess)
+ {
+ result.Content.Password = null;
+ }
+ return result;
+ }
+ ///
+ /// 添加用户
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result AddSysUser(SysUser info)
+ {
+ info.Password = Hash(info.Password);
+ var result = this._sysUserService.AddSysUser(info);
+ return result;
+ }
+
+ ///
+ /// 更新用户
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result UpdateSysUser(SysUser info)
+ {
+ info.Password = null;
+ var result = this._sysUserService.UpdateSysUser(info);
+ return result;
+ }
+
+ ///
+ /// 删除用户
+ ///
+ ///
+ ///
+ [HttpPost]
+ public Result DeleteSysUser(string id)
+ {
+ var result = this._sysUserService.DeleteUser(id);
+ return result;
+ }
+
+ [NonAction]
+ private string Hash(string value)
+ {
+ byte[] passwordAndSaltBytes = System.Text.Encoding.UTF8.GetBytes(value + salt);
+ byte[] hashBytes = new System.Security.Cryptography.SHA256Managed().ComputeHash(passwordAndSaltBytes);
+ string hashString = Convert.ToBase64String(hashBytes);
+ return hashString;
+ }
+ }
+}
diff --git a/CVDEMCS/Devices/DeviceType.cs b/CVDEMCS/Devices/DeviceType.cs
new file mode 100644
index 0000000..80e6900
--- /dev/null
+++ b/CVDEMCS/Devices/DeviceType.cs
@@ -0,0 +1,31 @@
+namespace PVDEMCS.Devices
+{
+ public sealed class DeviceProtocol
+ {
+ //
+ // 摘要:
+ // 1200系列
+ public const string S7_1200 = "S7_1200";
+ //
+ // 摘要:
+ // 300系列
+ public const string S7_300 = "S7_300";
+ //
+ // 摘要:
+ // 400系列
+ public const string S7_400 = "S7_400";
+ //
+ // 摘要:
+ // 1500系列PLC
+ public const string S7_1500 = "S7_1500";
+ //
+ // 摘要:
+ // 200的smart系列
+ public const string S7_200Smart = "S7_200Smart";
+ //
+ // 摘要:
+ // 200系统,需要额外配置以太网模块
+ public const string S7_200 = "S7_200";
+ }
+
+}
diff --git a/CVDEMCS/Devices/IDeviceRun.cs b/CVDEMCS/Devices/IDeviceRun.cs
new file mode 100644
index 0000000..a0710aa
--- /dev/null
+++ b/CVDEMCS/Devices/IDeviceRun.cs
@@ -0,0 +1,34 @@
+using PVDEMCS.Common.DI;
+using PVDEMCS.Services;
+using PVDEMCS.Services.Models;
+using System.Threading;
+
+namespace PVDEMCS.Devices
+{
+ ///
+ /// 设备运行
+ ///
+ public interface IDeviceRun : IDependency
+ {
+
+ ///
+ /// 获取所有点位信息
+ ///
+ List GetDevicePoints { get; }
+
+ ///
+ /// 获取控制器连接状态
+ ///
+ Dictionary GetDeviceIsConnected { get; }
+
+ ///
+ /// 开始运行
+ ///
+ void Run();
+
+ ///
+ /// 停止运行
+ ///
+ void Stop();
+ }
+}
diff --git a/CVDEMCS/Devices/IPLCCommunicationService.cs b/CVDEMCS/Devices/IPLCCommunicationService.cs
new file mode 100644
index 0000000..a671483
--- /dev/null
+++ b/CVDEMCS/Devices/IPLCCommunicationService.cs
@@ -0,0 +1,262 @@
+using HslCommunication.Core.Address;
+using HslCommunication;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+using HslCommunication.Profinet.Siemens;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+
+namespace PVDEMCS.Devices
+{
+ ///
+ /// PLC通信接口
+ ///
+ public interface IPLCCommunicationService
+ {
+ ///
+ /// 是否已连接
+ ///
+ bool IsConnected { get; }
+
+ #region 同步
+ ///
+ /// 连接PLC(长连接)
+ ///
+ ///
+ ///
+ Result Connection(string address, int port = 0);
+
+
+ ///
+ /// 关闭连接PLC(长连接)
+ ///
+ Result ColseConnection();
+
+ ///
+ /// 读取指定地址的byte[]值
+ ///
+ ///
+ ///
+ Result ReadBytes(string address, ushort length);
+
+ ///
+ /// 读取指定地址的bool值
+ ///
+ ///
+ ///
+ Result ReadBool(string address);
+
+ ///
+ /// 读取指定地址的byte值
+ ///
+ ///
+ ///
+ Result ReadByte(string address);
+
+ ///
+ /// 读取指定地址的Int16值
+ ///
+ ///
+ ///
+ Result ReadInt16(string address);
+
+ ///
+ /// 读取指定地址的Int32值
+ ///
+ ///
+ ///
+ Result ReadInt32(string address);
+
+ ///
+ /// 读取指定地址的long值
+ ///
+ ///
+ ///
+ Result ReadLong(string address);
+
+ ///
+ /// 读取指定地址的Float值
+ ///
+ ///
+ Result ReadFloat(string address);
+
+ ///
+ /// 读取指定地址的double值
+ ///
+ ///
+ Result ReadDouble(string address);
+
+ ///
+ /// 写入bool值
+ ///
+ /// 写入地址
+ ///
+ Result Write(string address, bool value);
+
+ ///
+ /// 写入byte值
+ ///
+ /// 写入地址
+ ///
+ Result Write(string address, byte value);
+
+ ///
+ /// 写入Int16值
+ ///
+ /// 写入地址
+ ///
+ Result Write(string address, short value);
+
+ ///
+ /// 写入Int32值
+ ///
+ /// 写入地址
+ ///
+ Result Write(string address, int value);
+
+ ///
+ /// 写入float值
+ ///
+ /// 写入地址
+ ///
+ Result Write(string address, float value);
+
+ ///
+ /// 写入double值
+ ///
+ /// 写入地址
+ ///
+ Result Write(string address, double value);
+
+ ///
+ /// 写入long值
+ ///
+ /// 写入地址
+ ///
+ Result Write(string address, long value);
+
+ #endregion
+
+ #region 异步
+ ///
+ /// 连接PLC(长连接)
+ ///
+ ///
+ ///
+ Task ConnectionAsync(string address, int port = 0);
+
+ ///
+ /// 关闭连接PLC(长连接)
+ ///
+ Task ColseConnectionAsyn();
+
+ ///
+ /// 读取指定地址的byte[]值
+ ///
+ ///
+ ///
+ Task> ReadBytesAsync(string address, ushort length);
+
+ ///
+ /// 读取指定地址的bool值
+ ///
+ ///
+ ///
+ Task> ReadBoolAsync(string address);
+
+ ///
+ /// 读取指定地址的byte值
+ ///
+ ///
+ ///
+ Task> ReadByteAsync(string address);
+
+ ///
+ /// 读取指定地址的Int16值
+ ///
+ ///
+ ///
+ Task> ReadInt16Async(string address);
+
+ ///
+ /// 读取指定地址的Int32值
+ ///
+ ///
+ ///
+ Task> ReadInt32Async(string address);
+
+ ///
+ /// 读取指定地址的long值
+ ///
+ ///
+ ///
+ Task> ReadLongAsync(string address);
+
+ ///
+ /// 读取指定地址的Float值
+ ///
+ ///
+ Task> ReadFloatAsync(string address);
+
+ ///
+ /// 读取指定地址的double值
+ ///
+ ///
+ Task> ReadDoubleAsync(string address);
+
+ ///
+ /// 写入bool值
+ ///
+ /// 写入地址
+ ///
+ Task WriteAsync(string address, bool value);
+
+ ///
+ /// 写入byte值
+ ///
+ /// 写入地址
+ ///
+ Task WriteAsync(string address, byte value);
+
+ ///
+ /// 写入Int16值
+ ///
+ /// 写入地址
+ ///
+ Task WriteAsync(string address, short value);
+
+ ///
+ /// 写入Int32值
+ ///
+ /// 写入地址
+ ///
+ Task WriteAsync(string address, int value);
+
+ ///
+ /// 写入float值
+ ///
+ /// 写入地址
+ ///
+ Task WriteAsync(string address, float value);
+
+ ///
+ /// 写入double值
+ ///
+ /// 写入地址
+ ///
+ Task WriteAsync(string address, double value);
+
+ ///
+ /// 写入long值
+ ///
+ /// 写入地址
+ ///
+ Task WriteAsync(string address, long value);
+
+ #endregion
+ }
+}
diff --git a/CVDEMCS/Devices/Impl/DeviceMonitor.cs b/CVDEMCS/Devices/Impl/DeviceMonitor.cs
new file mode 100644
index 0000000..66e32a7
--- /dev/null
+++ b/CVDEMCS/Devices/Impl/DeviceMonitor.cs
@@ -0,0 +1,282 @@
+using Masuit.Tools;
+using PVDEMCS.Common;
+using PVDEMCS.Common.Log;
+using PVDEMCS.Devices;
+using PVDEMCS.Services.Models;
+using System.Security.Cryptography;
+
+namespace PVDEMCS.Devices.Impl
+{
+ ///
+ /// 控制器点位监控
+ ///
+ public class DeviceMonitor
+ {
+ private DeviceInfo deviceInfo;
+ private IPLCCommunicationService plcCommunicationService;
+ private List devicePoints;
+ private object lockObj = new object();
+ private bool isRun = false;
+ public DeviceMonitor(DeviceInfo deviceInfo)
+ {
+ this.deviceInfo = deviceInfo;
+ devicePoints = new List();
+ PointMonitor();
+ }
+ ///
+ /// PLC 点位改变触发
+ ///
+ public event EventHandler PointChange;
+
+ ///
+ /// 获取错误相信
+ ///
+ public event EventHandler ErrorMessage;
+
+ ///
+ /// 控制器编号
+ ///
+ public string DeviceCode
+ {
+ get
+ {
+ return deviceInfo.DeviceCode;
+ }
+ }
+
+ ///
+ /// 间隔时间
+ ///
+ public int Interval { get; set; } = 2000;
+ public IPLCCommunicationService PLCCommunicationService
+ {
+ get
+ {
+ return plcCommunicationService;
+ }
+ }
+
+ ///
+ /// 连接状态
+ ///
+ public bool IsConnected
+ {
+ get
+ {
+ return plcCommunicationService.IsConnected;
+ }
+ }
+
+ ///
+ /// 监控是否运行
+ ///
+ public bool IsRun
+ {
+ get { return isRun; }
+ }
+
+ ///
+ /// 当前点位集合
+ ///
+ public ICollection Points
+ {
+ get
+ {
+ return devicePoints;
+ }
+ }
+
+ ///
+ /// PLC地址与端口
+ ///
+ public void Init(string address, int port = 0)
+ {
+ deviceInfo.Host = address;
+ deviceInfo.Port = port;
+ }
+
+ ///
+ /// 获取PLC通信接口
+ ///
+ ///
+ public void Init(IPLCCommunicationService plcCommunicationService)
+ {
+ this.plcCommunicationService = plcCommunicationService;
+
+ }
+
+ ///
+ /// 加载点位集合
+ ///
+ ///
+ public void Load(params DevicePoint[] points)
+ {
+ if (points.IsNullOrEmpty())
+ {
+ throw new ArgumentException($"{nameof(points)}: 不能为空!");
+ }
+ if (devicePoints.Where(f => points.Select(ff => ff.PointCode).Contains(f.PointCode)).Count() > 0)
+ {
+ throw new ArgumentException($"{nameof(points)}: PointCode 不能重复!");
+ }
+ devicePoints.AddRange(points);
+ }
+
+ ///
+ /// 清理所有点位
+ ///
+ public void Clear()
+ {
+ devicePoints.Clear();
+ }
+
+ ///
+ /// 开始监控
+ ///
+ public async Task StartAsync()
+ {
+ if (plcCommunicationService == null)
+ {
+ plcCommunicationService = new S7CommunicationService(deviceInfo.Protocol);
+ }
+ if (!plcCommunicationService.IsConnected)
+ {
+ var result = await plcCommunicationService.ConnectionAsync(deviceInfo.Host, deviceInfo.Port);
+ if (!result.IsSuccess)
+ {
+ ErrorMessage?.Invoke(this, "开始PLC连接失败:" + result.Message);
+ return await Task.FromResult(false);
+ }
+
+ isRun = true;
+ $"PLC控制器:{deviceInfo.DeviceCode}连接成功".WriteInfoLog();
+ }
+ return await Task.FromResult(true);
+ }
+
+ ///
+ /// 停止监控
+ ///
+ public async Task StopAsync()
+ {
+ if (plcCommunicationService.IsConnected)
+ {
+ var result = await plcCommunicationService.ColseConnectionAsyn();
+ if (!result.IsSuccess)
+ {
+ ErrorMessage?.Invoke(this, "关闭PLC连接失败:" + result.Message);
+ return await Task.FromResult(false);
+ }
+ isRun = false;
+ return await Task.FromResult(true);
+
+ }
+ return await Task.FromResult(true);
+ }
+
+ private void PointMonitor()
+ {
+ Task.Run(() =>
+ {
+ while (true)
+ {
+ lock (lockObj)
+ {
+ if (Points.Count > 0 && isRun && plcCommunicationService.IsConnected)
+ {
+ devicePoints.ForEach(async point =>
+ {
+ await CallDevicePoint(point);
+ });
+ }
+ Thread.Sleep(Interval);
+ }
+ }
+ });
+ }
+
+ ///
+ /// 获取PLC点位信息
+ ///
+ ///
+ ///
+ private async Task CallDevicePoint(DevicePoint point)
+ {
+ var type = Type.GetType(point.DataType);
+ var plcService = plcCommunicationService;
+ //Boolean
+ if (type.Equals(typeof(bool)))
+ {
+ var result = await plcService.ReadBoolAsync(point.Address);
+ GetReturnValue(point, result);
+ return;
+ }
+ //Byte
+ if (type.Equals(typeof(byte)))
+ {
+ var result = await plcService.ReadByteAsync(point.Address);
+ GetReturnValue(point, result);
+ return;
+ }
+ //Byte
+ if (type.Equals(typeof(byte)))
+ {
+ var result = await plcService.ReadByteAsync(point.Address);
+ GetReturnValue(point, result);
+ return;
+ }
+ //Int16
+ if (type.Equals(typeof(short)))
+ {
+ var result = await plcService.ReadInt16Async(point.Address);
+ GetReturnValue(point, result);
+ return;
+ }
+ //Int32
+ if (type.Equals(typeof(int)))
+ {
+ var result = await plcService.ReadInt32Async(point.Address);
+ GetReturnValue(point, result);
+ return;
+ }
+ //Int64
+ if (type.Equals(typeof(long)))
+ {
+ var result = await plcService.ReadLongAsync(point.Address);
+ GetReturnValue(point, result);
+ return;
+ }
+ //float
+ if (type.Equals(typeof(float)))
+ {
+ var result = await plcService.ReadFloatAsync(point.Address);
+ GetReturnValue(point, result);
+ return;
+ }
+ //double
+ if (type.Equals(typeof(double)))
+ {
+ var result = await plcService.ReadDoubleAsync(point.Address);
+ GetReturnValue(point, result);
+ return;
+ }
+ }
+
+ private void GetReturnValue(DevicePoint point, Result result)
+ {
+ if (result.IsSuccess)
+ {
+ if (point.ObjectValue == null || !point.ObjectValue.Equals(result.Content))
+ {
+ point.ObjectValue = result.Content;
+ PointChange?.Invoke(this, point);
+ $"点位发生变更:{point.ToJsonString()}".WriteInfoLog();
+ }
+ }
+ else
+ {
+ ErrorMessage?.Invoke(this, result.Message);
+ }
+ }
+ }
+}
diff --git a/CVDEMCS/Devices/Impl/DeviceRun.cs b/CVDEMCS/Devices/Impl/DeviceRun.cs
new file mode 100644
index 0000000..0c1b745
--- /dev/null
+++ b/CVDEMCS/Devices/Impl/DeviceRun.cs
@@ -0,0 +1,232 @@
+using AngleSharp.Css.Dom;
+using Masuit.Tools;
+using PVDEMCS.Common.Constant;
+using PVDEMCS.Common.Log;
+using PVDEMCS.Devices;
+using PVDEMCS.Services;
+using PVDEMCS.Services.Impl;
+using PVDEMCS.Services.Models;
+using System.Linq;
+using System.Threading;
+
+namespace PVDEMCS.Devices.Impl
+{
+ ///
+ /// 设备运行
+ ///
+ public class DeviceRun : IDeviceRun
+ {
+ private IDeviceService deviceService;
+ private IEquipmentRecordService equipmentRecordService;
+ private List monitors = new List();
+ private object lockObj = new object();
+ private object lockObj1 = new object();
+
+ public DeviceRun(IDeviceService deviceService, IEquipmentRecordService equipmentRecordService)
+ {
+ this.deviceService = deviceService;
+ this.equipmentRecordService = equipmentRecordService;
+ TaskRun();
+ }
+
+ ///
+ /// 获取所有点位信息
+ ///
+ public List GetDevicePoints
+ {
+ get
+ {
+ return monitors.SelectMany(f => f.Points).ToList();
+ }
+ }
+
+ ///
+ /// 获取控制器连接状态
+ ///
+ public Dictionary GetDeviceIsConnected
+ {
+ get
+ {
+ return monitors.ToDictionary(f => f.DeviceCode, f => f.IsConnected);
+ }
+ }
+
+ ///
+ /// 开始运行
+ ///
+ public void Run()
+ {
+ Stop();
+
+ monitors.Clear();
+
+ var result = deviceService.GetDeviceInfoList("", "", true);
+ if (result.IsSuccess)
+ {
+ var devices = result.Content;
+ foreach (var device in devices)
+ {
+ var deviceMonitor = new DeviceMonitor(device);
+ var devicePoints = deviceService.GetDevicePointList(device.Id, activated: true);
+ if (devicePoints.IsSuccess && devicePoints.Content.Count > 0)
+ {
+ deviceMonitor.Load(devicePoints.Content.ToArray());
+ }
+ deviceMonitor.ErrorMessage += DeviceMonitor_ErrorMessage;
+ deviceMonitor.PointChange += DeviceMonitor_PointChnage; ;
+ monitors.Add(deviceMonitor);
+ Task task = deviceMonitor.StartAsync();
+ ($"PLC控制器:{device.DeviceCode},开始启动...").WriteInfoLog();
+ }
+ }
+ }
+
+ ///
+ /// 停止运行
+ ///
+ public void Stop()
+ {
+ foreach (var item in monitors)
+ {
+ var task = item.StopAsync();
+ }
+ }
+
+ //
+ private void TaskRun()
+ {
+ //监控设备连接
+ Task.Run(() =>
+ {
+ while (true)
+ {
+ foreach (var item in monitors)
+ {
+ var task = item.StartAsync();
+ }
+ Thread.Sleep(5000);
+ }
+ });
+
+ //添加设备记录
+ Task.Run(() =>
+ {
+ while (true)
+ {
+ try
+ {
+ RunEquipmentRecord();
+
+ Thread.Sleep(3000);
+ }
+ catch (Exception ex)
+ {
+ ex.WriteErrorLog();
+ }
+
+ }
+ });
+
+ //设备记录日统计
+ Task.Run(() =>
+ {
+ while (true)
+ {
+ try
+ {
+ equipmentRecordService.RunEquipmentRecordDayTotal(DateTime.Now);
+
+ Thread.Sleep(1000 * 60);
+ }
+ catch (Exception ex)
+ {
+ ex.WriteErrorLog();
+ }
+
+ }
+ });
+
+ //设备记录统计
+ Task.Run(() =>
+ {
+ while (true)
+ {
+ equipmentRecordService.RunEquipmentRecordTotal();
+ Thread.Sleep(1000 * 1800);
+ }
+ });
+ }
+
+ //记录设备数据
+ private void RunEquipmentRecord()
+ {
+ try
+ {
+ foreach (var monitor in monitors)
+ {
+ if (!monitor.IsRun)
+ {
+ continue;
+ }
+ var points = monitor.Points;
+ if (points.IsNullOrEmpty())
+ {
+ continue;
+ }
+
+ var equipmentIds = points.Select(f => f.EquipmentId).Distinct();
+ foreach (var id in equipmentIds)
+ {
+ var list = points.Where(f => f.EquipmentId == id).ToList();
+ if (list.Count >= 2)
+ {
+ var startStop = list.Where(f => f.ActionType == ActionType.StartStop).FirstOrDefault();
+ var fault = list.Where(f => f.ActionType == ActionType.Fault).FirstOrDefault();
+ if (!startStop.IsNullOrEmpty() &&
+ !fault.IsNullOrEmpty() &&
+ !startStop.ObjectValue.IsNullOrEmpty() &&
+ !fault.ObjectValue.IsNullOrEmpty())
+ {
+ var state = EquipmentState.Stop;
+ //如果运行状态比警告状态高,这里先判断运行状态,如果运行状态为false,在判断警告状态
+ if (startStop.GetValue())
+ {
+ state = EquipmentState.Run;
+ }
+ else if (fault.GetValue())
+ {
+ state = EquipmentState.Alarm;
+
+ }
+ //如果为报警状态,则判断是否设为手动,且为不报警,则屏蔽报警信号,不做记录
+ if (state == EquipmentState.Alarm &&
+ startStop.Model == EquipmentAlarmModel.Manual &&
+ !startStop.IsAlarm)
+ {
+ continue;
+ }
+ equipmentRecordService.AddUpdateEquipmentRecord(id, state, DateTime.Now);
+ }
+ }
+ }
+ }
+
+
+ }
+ catch (Exception ex)
+ {
+ ex.WriteErrorLog();
+ }
+ }
+
+ private void DeviceMonitor_PointChnage(object sender, DevicePoint e)
+ {
+
+ }
+
+ private void DeviceMonitor_ErrorMessage(object sender, string e)
+ {
+ e.WriteErrorLog();
+ }
+ }
+}
diff --git a/CVDEMCS/Devices/Impl/S7CommunicationService.cs b/CVDEMCS/Devices/Impl/S7CommunicationService.cs
new file mode 100644
index 0000000..20a05c1
--- /dev/null
+++ b/CVDEMCS/Devices/Impl/S7CommunicationService.cs
@@ -0,0 +1,537 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using HslCommunication.BasicFramework;
+using HslCommunication.Core.Address;
+using HslCommunication.Core.IMessage;
+using HslCommunication.Core;
+using HslCommunication;
+using HslCommunication.Profinet.Siemens;
+using HslCommunication.Reflection;
+using PVDEMCS.Common.Tools;
+using PVDEMCS.Devices;
+using PVDEMCS.Common;
+
+namespace PVDEMCS.Devices.Impl
+{
+ ///
+ /// PLC通信服务 SiemensS7 smart200 实现
+ ///
+ internal class S7CommunicationService : IPLCCommunicationService
+ {
+ private SiemensS7Net siemensS7Net = null;
+
+ ///
+ /// 是否已连接
+ ///
+ public bool IsConnected { get; private set; }
+
+ public S7CommunicationService(string deviceProtocol)
+ {
+ switch (deviceProtocol)
+ {
+ case DeviceProtocol.S7_400:
+ siemensS7Net = new SiemensS7Net(SiemensPLCS.S400);
+ break;
+ case DeviceProtocol.S7_1200:
+ siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200);
+ break;
+ case DeviceProtocol.S7_1500:
+ siemensS7Net = new SiemensS7Net(SiemensPLCS.S1500);
+ break;
+ case DeviceProtocol.S7_200:
+ siemensS7Net = new SiemensS7Net(SiemensPLCS.S200);
+ break;
+ case DeviceProtocol.S7_300:
+ siemensS7Net = new SiemensS7Net(SiemensPLCS.S300);
+ break;
+ case DeviceProtocol.S7_200Smart:
+ siemensS7Net = new SiemensS7Net(SiemensPLCS.S200Smart);
+ break;
+ default:
+ throw new ArgumentException($"DeviceProtocol 参数不正确,没有{deviceProtocol}协议");
+ }
+ siemensS7Net.ConnectTimeOut = 3000;
+ }
+
+ #region 同步
+ ///
+ /// 连接PLC(长连接)
+ ///
+ ///
+ ///
+ public Result Connection(string address, int port = 0)
+ {
+ siemensS7Net.IpAddress = address;
+ if (port > 0)
+ {
+ siemensS7Net.Port = port;
+ }
+ var operateResult = siemensS7Net.ConnectServer();
+ var result = ConvertResult(operateResult);
+ if (result.IsSuccess)
+ {
+ IsConnected = true;
+ }
+ return result;
+ }
+
+ ///
+ /// 关闭连接PLC(长连接)
+ ///
+ public Result ColseConnection()
+ {
+ var operateResult = siemensS7Net.ConnectClose();
+ var result = ConvertResult(operateResult);
+ if (result.IsSuccess)
+ {
+ IsConnected = false;
+ }
+ return result;
+ }
+ ///
+ /// 读取指定地址的byte[]值
+ ///
+ ///
+ ///
+ public Result ReadBytes(string address, ushort length)
+ {
+ var operateResult = siemensS7Net.Read(address, length);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+ ///
+ /// 读取指定地址的bool值
+ ///
+ ///
+ ///
+ public Result ReadBool(string address)
+ {
+ var operateResult = siemensS7Net.ReadBool(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的byte值
+ ///
+ ///
+ ///
+ public Result ReadByte(string address)
+ {
+ var operateResult = siemensS7Net.ReadByte(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的Int16值
+ ///
+ ///
+ ///
+ public Result ReadInt16(string address)
+ {
+ var operateResult = siemensS7Net.ReadInt16(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的Int32值
+ ///
+ ///
+ ///
+ public Result ReadInt32(string address)
+ {
+ var operateResult = siemensS7Net.ReadInt32(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的long值
+ ///
+ ///
+ ///
+ public Result ReadLong(string address)
+ {
+ var operateResult = siemensS7Net.ReadInt64(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的Float值
+ ///
+ ///
+ public Result ReadFloat(string address)
+ {
+ var operateResult = siemensS7Net.ReadFloat(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的double值
+ ///
+ ///
+ public Result ReadDouble(string address)
+ {
+ var operateResult = siemensS7Net.ReadDouble(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入bool值
+ ///
+ /// 写入地址
+ ///
+ public Result Write(string address, bool value)
+ {
+ var operateResult = siemensS7Net.Write(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入byte值
+ ///
+ /// 写入地址
+ ///
+ public Result Write(string address, byte value)
+ {
+ var operateResult = siemensS7Net.Write(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+
+ }
+
+ ///
+ /// 写入Int16值
+ ///
+ /// 写入地址
+ ///
+ public Result Write(string address, short value)
+ {
+ var operateResult = siemensS7Net.Write(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入Int32值
+ ///
+ /// 写入地址
+ ///
+ public Result Write(string address, int value)
+ {
+ var operateResult = siemensS7Net.Write(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入float值
+ ///
+ /// 写入地址
+ ///
+ public Result Write(string address, float value)
+ {
+ var operateResult = siemensS7Net.Write(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入double值
+ ///
+ /// 写入地址
+ ///
+ public Result Write(string address, double value)
+ {
+ var operateResult = siemensS7Net.Write(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入long值
+ ///
+ /// 写入地址
+ ///
+ public Result Write(string address, long value)
+ {
+ var operateResult = siemensS7Net.Write(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ #endregion
+
+ #region 异步
+ ///
+ /// 连接PLC(长连接)
+ ///
+ ///
+ ///
+ public async Task ConnectionAsync(string address, int port = 0)
+ {
+ siemensS7Net.IpAddress = address;
+ if (port > 0)
+ {
+ siemensS7Net.Port = port;
+ }
+ var operateResult = await siemensS7Net.ConnectServerAsync();
+ var result = ConvertResult(operateResult);
+ if (operateResult.IsSuccess)
+ {
+ IsConnected = true;
+ }
+ return result;
+ }
+
+ ///
+ /// 关闭连接PLC(长连接)
+ ///
+ public async Task ColseConnectionAsyn()
+ {
+ var operateResult = await siemensS7Net.ConnectCloseAsync();
+ var result = ConvertResult(operateResult);
+ if (operateResult.IsSuccess)
+ {
+ IsConnected = false;
+ }
+ return result;
+ }
+ ///
+ /// 读取指定地址的byte[]值
+ ///
+ ///
+ ///
+ public async Task> ReadBytesAsync(string address, ushort length)
+ {
+ var operateResult = await siemensS7Net.ReadAsync(address, length);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+ ///
+ /// 读取指定地址的bool值
+ ///
+ ///
+ ///
+ public async Task> ReadBoolAsync(string address)
+ {
+ var operateResult = await siemensS7Net.ReadBoolAsync(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的byte值
+ ///
+ ///
+ ///
+ public async Task> ReadByteAsync(string address)
+ {
+ var operateResult = await siemensS7Net.ReadByteAsync(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的Int16值
+ ///
+ ///
+ ///
+ public async Task> ReadInt16Async(string address)
+ {
+ var operateResult = await siemensS7Net.ReadInt16Async(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的Int32值
+ ///
+ ///
+ ///
+ public async Task> ReadInt32Async(string address)
+ {
+ var operateResult = await siemensS7Net.ReadInt32Async(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的long值
+ ///
+ ///
+ ///
+ public async Task> ReadLongAsync(string address)
+ {
+ var operateResult = await siemensS7Net.ReadInt64Async(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的Float值
+ ///
+ ///
+ public async Task> ReadFloatAsync(string address)
+ {
+ var operateResult = await siemensS7Net.ReadFloatAsync(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 读取指定地址的double值
+ ///
+ ///
+ public async Task> ReadDoubleAsync(string address)
+ {
+ var operateResult = await siemensS7Net.ReadDoubleAsync(address);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入bool值
+ ///
+ /// 写入地址
+ ///
+ public async Task WriteAsync(string address, bool value)
+ {
+ var operateResult = await siemensS7Net.WriteAsync(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入byte值
+ ///
+ /// 写入地址
+ ///
+ public async Task WriteAsync(string address, byte value)
+ {
+
+ var operateResult = await siemensS7Net.WriteAsync(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入Int16值
+ ///
+ /// 写入地址
+ ///
+ public async Task WriteAsync(string address, short value)
+ {
+ var operateResult = await siemensS7Net.WriteAsync(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入Int32值
+ ///
+ /// 写入地址
+ ///
+ public async Task WriteAsync(string address, int value)
+ {
+ var operateResult = await siemensS7Net.WriteAsync(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入float值
+ ///
+ /// 写入地址
+ ///
+ public async Task WriteAsync(string address, float value)
+ {
+ var operateResult = await siemensS7Net.WriteAsync(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入double值
+ ///
+ /// 写入地址
+ ///
+ public async Task WriteAsync(string address, double value)
+ {
+ var operateResult = await siemensS7Net.WriteAsync(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ ///
+ /// 写入long值
+ ///
+ /// 写入地址
+ ///
+ public async Task WriteAsync(string address, long value)
+ {
+ var operateResult = await siemensS7Net.WriteAsync(address, value);
+ var result = ConvertResult(operateResult);
+ return result;
+ }
+
+ #endregion
+
+
+ ///
+ /// 转换 result (将框架结果结构转换成当前程序结果结构)
+ ///
+ ///
+ ///
+
+ private Result ConvertResult(OperateResult result)
+ {
+ var retResult = ModelTools.PubClone.Trans(result);
+ return retResult;
+ }
+
+ ///
+ /// 转换 result (将框架结果结构转换成当前程序结果结构)
+ ///
+ ///
+ ///
+
+ private Result ConvertResult(OperateResult result)
+ {
+ VerifyTimeOut(result);
+
+ var retResult = ModelTools.PubClone, Result>.Trans(result);
+ retResult.Content = result.Content;
+ return retResult;
+ }
+
+ ///
+ /// 判断连接是否中断
+ ///
+ ///
+ private void VerifyTimeOut(OperateResult result)
+ {
+ var msg = result.Message;
+
+ if (result!=null && !result.IsSuccess)
+ {
+ var isTimeOut = msg.Contains("连接") && msg.Contains("失败") && msg.Contains("超时时间为");
+ if (isTimeOut)
+ {
+ IsConnected = false;
+ }
+ }
+ }
+ }
+}
diff --git a/CVDEMCS/Nlog.config b/CVDEMCS/Nlog.config
new file mode 100644
index 0000000..752d919
--- /dev/null
+++ b/CVDEMCS/Nlog.config
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CVDEMCS/Program.cs b/CVDEMCS/Program.cs
new file mode 100644
index 0000000..39b5519
--- /dev/null
+++ b/CVDEMCS/Program.cs
@@ -0,0 +1,100 @@
+using Masuit.Tools;
+using Masuit.Tools.Reflection;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.OpenApi.Models;
+using PVDEMCS;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common.Log;
+using PVDEMCS.Devices;
+using PVDEMCS.Services;
+using System.Configuration;
+using System.Reflection;
+
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+
+builder.Services.AddControllers();
+// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen(options =>
+{
+ //options.SwaggerDoc("v1", new OpenApiInfo { Title = "PVDEMCS Api", Version = "v1" });
+ var xmlPathApp = Path.Combine(AppContext.BaseDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml");
+ options.IncludeXmlComments(xmlPathApp, true);
+});
+//ӿ
+builder.Services.AddCors(options =>
+{
+ options.AddPolicy("CorsPolicy", opt => opt.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().WithExposedHeaders("X-Pagination"));
+});
+//ע
+builder.AddAutofacExt();
+//
+//builder.Services.AddDbContext(options =>
+//{
+// options.UseMySQL(builder.Configuration.GetConnectionString("MySqlConnection"));
+//});
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+//if (app.Environment.IsDevelopment())
+//{
+
+//}
+
+app.UseSwagger();
+app.UseSwaggerUI();
+
+//ʹÿ
+app.UseCors("CorsPolicy");
+
+//app.UseHttpsRedirection();
+
+app.UseAuthorization();
+
+app.MapControllers();
+
+app.Lifetime.ApplicationStarted.Register(() =>
+{
+ var logService = app.Services.GetService();
+
+ LogExtensions.Load(logService);
+
+ var deviceRun = app.Services.GetService();
+
+ deviceRun.Run();
+
+ //var equipmentList = app.Services.GetService();
+ //var equipmentRecord = app.Services.GetService();
+ //var ids = equipmentList.GetEquipmentList().Content.Select(f => f.Id).ToList();
+ //var startDate = DateTime.Parse("2023-01-01");
+ //var obj = new object();
+
+ //var result = System.Threading.Tasks.Parallel.ForEach(ids, id =>
+ // {
+ // Test.CreateData(startDate, id, (id, state, dt) =>
+ // {
+ // lock (obj)
+ // {
+ // equipmentRecord.AddUpdateEquipmentRecord(id, state, dt);
+ // }
+ // });
+ // });
+
+
+ //while (true)
+ //{
+ // if (startDate > DateTime.Now)
+ // {
+ // return;
+ // }
+ // equipmentRecord.RunEquipmentRecordDayTotal(startDate);
+ // startDate = startDate.AddDays(1);
+
+ // Thread.Sleep(100);
+ //}
+
+});
+
+app.Run();
diff --git a/CVDEMCS/Properties/PublishProfiles/FolderProfile.pubxml b/CVDEMCS/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 0000000..36847ea
--- /dev/null
+++ b/CVDEMCS/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,17 @@
+
+
+
+
+ false
+ false
+ true
+ Release
+ Any CPU
+ FileSystem
+ bin\Release\net6.0\publish\
+ FileSystem
+ <_TargetId>Folder
+
+
\ No newline at end of file
diff --git a/CVDEMCS/Properties/launchSettings.json b/CVDEMCS/Properties/launchSettings.json
new file mode 100644
index 0000000..6ac7807
--- /dev/null
+++ b/CVDEMCS/Properties/launchSettings.json
@@ -0,0 +1,31 @@
+{
+ "profiles": {
+ "PVDEMCS": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "dotnetRunMessages": true,
+ "applicationUrl": "http://localhost:5223"
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ },
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:34771",
+ "sslPort": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/IDeviceService.cs b/CVDEMCS/Services/IDeviceService.cs
new file mode 100644
index 0000000..6a01460
--- /dev/null
+++ b/CVDEMCS/Services/IDeviceService.cs
@@ -0,0 +1,129 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services.Repositories;
+using PVDEMCS.Services.Repositories.Entities;
+
+namespace PVDEMCS.Services
+{
+ ///
+ /// PLC控制器 服务层 接口
+ ///
+ public interface IDeviceService : IDependency
+ {
+ #region PLC控制器
+
+ ///
+ /// 获取PLC控制器分页列表
+ ///
+ /// 控制器编号
+ /// 控制器名称
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ Result> GetDevicePageList(string deviceCode, string deviceName, bool? activated, int page, int size);
+
+ ///
+ /// 获取PLC控制器列表
+ ///
+ /// 控制器编号
+ /// 控制器名称
+ /// 是否启用
+ ///
+ Result> GetDeviceInfoList(string deviceCode="", string deviceName = "", bool? activated = false);
+
+ ///
+ /// 获取PLC控制器明细
+ ///
+ /// 主键Id
+ ///
+ Result GetDeviceDetail(string id);
+
+ ///
+ /// 添加PLC控制器
+ ///
+ ///
+ ///
+ Result AddDevice(DeviceInfo entity);
+
+ ///
+ /// 更新PLC控制器
+ ///
+ ///
+
+ Result UpdateDevice(DeviceInfo entity);
+ ///
+ /// 删除PLC控制器
+ ///
+ ///
+ Result DeleteDevice(string id);
+
+ #endregion
+
+ #region PLC点位
+
+ ///
+ /// 获取PLC控制器点位分页列表
+ ///
+ /// 控制器Id
+ /// 控制器编号
+ /// 控制器名称
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 点位编号
+ /// 点位列表
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ Result> GetDevicePointPageList(string deviceId, string deviceName, string deviceCode, string equipmentName, string equipmentCode, string equipmentType, string pointCode, string pointName, bool? activated, int page, int size);
+
+ ///
+ /// 获取PLC控制器点位列表
+ ///
+ /// 控制器Id
+ /// 控制器编号
+ /// 控制器名称
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 点位编号
+ /// 点位列表
+ /// 是否启用
+ ///
+ Result> GetDevicePointList(string deviceId, string deviceName="", string deviceCode = "", string equipmentName = "", string equipmentCode = "", string equipmentType = "", string pointCode = "", string pointName = "", bool? activated = true);
+
+ ///
+ /// 获取PLC控制器点位明细
+ ///
+ /// Id
+ ///
+ Result GetDevicePointDetail(string id);
+
+ ///
+ /// 添加PLC控制器点位
+ ///
+ ///
+ ///
+ Result AddDevicePoint(DevicePoint entity);
+
+ ///
+ /// 更新PLC控制器点位
+ ///
+ ///
+ ///
+ Result UpdateDevicePoint(DevicePoint entity);
+
+ ///
+ /// 删除PLC控制器点位
+ ///
+ ///
+ ///
+ Result DeleteDevicePoint(string id);
+
+ #endregion
+ }
+}
diff --git a/CVDEMCS/Services/IEquipmentRecordService.cs b/CVDEMCS/Services/IEquipmentRecordService.cs
new file mode 100644
index 0000000..c12da14
--- /dev/null
+++ b/CVDEMCS/Services/IEquipmentRecordService.cs
@@ -0,0 +1,150 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services.Repositories.Entities;
+
+namespace PVDEMCS.Services
+{
+ ///
+ /// 设备数据记录与统计 服务层 接口
+ ///
+ public interface IEquipmentRecordService : IDependency
+ {
+ #region 设备状态记录
+
+ ///
+ /// 获取设备状态记录分页列表
+ ///
+ /// 设备Id
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ ///
+ Result> GetEquipmentRecordPageList(string equipmentId, string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size);
+
+ ///
+ /// 获取设备状态记录列表
+ ///
+ /// 设备Id
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ ///
+ Result> GetEquipmentRecordList(string equipmentId, string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime);
+
+ ///
+ /// 根据设备Id获取记录统计
+ ///
+ /// 设备Id
+ ///
+ Result GetEquipmentRecordTotalDetail(string equipmentId);
+
+ ///
+ /// 添加或更新设备状态记录
+ /// 1.如果设备最新记录状态没有改变则更新结束时间
+ /// 2.如果没有记录则添加记录
+ ///
+ /// 设备Id
+ /// 设备状态,运行:Run,待机:Stop,报警:Alarm
+ /// 记录时间
+ ///
+ Result AddUpdateEquipmentRecord(string equipmentId, string state, DateTime dateTime);
+
+ ///
+ /// 进行设备状态记录统计(日统计)
+ ///
+ ///
+ ///
+ Result RunEquipmentRecordDayTotal(DateTime date);
+
+ ///
+ /// 进行设备状态记录统计
+ ///
+ ///
+ Result RunEquipmentRecordTotal();
+
+ #endregion
+
+ #region 设备记录统计
+
+ ///
+ /// 获取设备状态记录统计分页列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ Result> GetEquipmentRecordDayTotalPageList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size);
+
+ ///
+ /// 获取设备状态记录统计列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ Result> GetEquipmentRecordDayTotalList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime);
+
+ ///
+ /// 获取设备状态记录统计分页列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ Result> GetEquipmentRecordTotalPageList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size);
+
+ ///
+ /// 获取设备状态记录统计列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ Result> GetEquipmentRecordTotalList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime);
+
+ ///
+ /// 获取设备状态记录月统计
+ ///
+ ///
+ Result> GetEquipmentRecordStateMonthTotal();
+
+ ///
+ /// 获取设备记录开炉次数月统计
+ ///
+ ///
+ Result> GetEquipmentRecordFurnaceMonthTotal();
+
+ ///
+ /// 获取设备记录OEE月统计
+ ///
+ ///
+ Result> GetEquipmentRecordOEEMonthTotal();
+
+ ///
+ /// 获取设备OEE信息
+ ///
+ /// 设备Id
+ /// 开始时间
+ /// 结束时间
+ ///
+ Result GetEquipmentOEEMonthTotal(string equipmentId, DateTime begDate, DateTime endDate);
+
+ #endregion
+ }
+}
diff --git a/CVDEMCS/Services/IEquipmentService.cs b/CVDEMCS/Services/IEquipmentService.cs
new file mode 100644
index 0000000..42d30f1
--- /dev/null
+++ b/CVDEMCS/Services/IEquipmentService.cs
@@ -0,0 +1,63 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Repositories.Entities;
+using PVDEMCS.Services.Models;
+
+namespace PVDEMCS.Services
+{
+ ///
+ /// 设备管理 服务层 接口
+ ///
+ public interface IEquipmentService : IDependency
+ {
+ ///
+ /// 获取设备分页列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ Result> GetEquipmentPageList(string equipmentName = "", string equipmentCode = "", string equipmentType = "", bool? activated = true, int page = 1, int size = 20);
+
+ ///
+ /// 获取设备列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 是否启用
+ Result> GetEquipmentList(string equipmentName = "", string equipmentCode = "", string equipmentType = "", bool? activated = true);
+
+ ///
+ /// 获取设备明显
+ ///
+ ///
+ ///
+ Result GetEquipmentDetail(string id);
+
+ ///
+ /// 添加设备信息
+ ///
+ ///
+ ///
+ Result AddEquipment(EquipmentInfo info);
+
+ ///
+ /// 更新设备信息
+ ///
+ ///
+ ///
+ Result UpdateEquipment(EquipmentInfo info);
+
+ ///
+ /// 删除设备信息
+ ///
+ ///
+ ///
+ Result DeleteEquipment(string id);
+ }
+}
diff --git a/CVDEMCS/Services/ILogService.cs b/CVDEMCS/Services/ILogService.cs
new file mode 100644
index 0000000..c0e1d7b
--- /dev/null
+++ b/CVDEMCS/Services/ILogService.cs
@@ -0,0 +1,36 @@
+using GuideScreen.Common.Common;
+using PVDEMCS.Common.DI;
+using System;
+
+namespace PVDEMCS.Services
+{
+ ///
+ /// 日志服务 接口
+ ///
+ public interface ILogService : IDependency
+ {
+ string LogDirectory { get; }
+
+ void ClearAgoDays(int day);
+
+ void Debug(string msg, Exception err);
+
+ void Debug(string msg, params object[] args);
+
+ void Error(string msg, Exception err);
+
+ void Error(string msg, params object[] args);
+
+ void Fatal(string msg, Exception err);
+
+ void Fatal(string msg, params object[] args);
+
+ void Info(string msg, Exception err);
+
+ void Info(string msg, params object[] args);
+
+ void Trace(string msg, Exception err);
+
+ void Trace(string msg, params object[] args);
+ }
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/ISysConfigService.cs b/CVDEMCS/Services/ISysConfigService.cs
new file mode 100644
index 0000000..d792d01
--- /dev/null
+++ b/CVDEMCS/Services/ISysConfigService.cs
@@ -0,0 +1,67 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Repositories.Entities;
+using PVDEMCS.Services.Models;
+
+namespace PVDEMCS.Services
+{
+ ///
+ /// 系统参数设置 服务层 接口
+ ///
+ public interface ISysConfigService : IDependency
+ {
+ ///
+ /// 获取系统参数设置分页列表
+ ///
+ /// 参数名称
+ /// 参数键值
+ /// 当前页
+ /// 页大小
+ ///
+ Result> GetSysConfigPageList(string configName, string configKey, int page, int size);
+
+ ///
+ /// 获取系统参数设置列表
+ ///
+ /// 参数名称
+ /// 参数键值
+ ///
+ Result> GetSysConfigList(string configName, string configKey);
+
+ ///
+ /// 获取获取系统参数设置明细
+ ///
+ ///
+ ///
+ Result GetSysConfigDetailById(string id);
+
+ ///
+ /// 获取获取系统参数设置明细
+ ///
+ ///
+ ///
+ ///
+ Result GetSysConfigDetailNameOrKey(string name, string key = "");
+
+ ///
+ /// 添加系统参数设置
+ ///
+ ///
+ ///
+ Result AddSysConfig(SysConfig info);
+
+ ///
+ /// 更新系统参数设置
+ ///
+ ///
+
+ Result UpdateSysConfig(SysConfig info);
+
+ ///
+ /// 删除系统参数设置
+ ///
+ ///
+ Result DeleteSysConfig(string id);
+ }
+}
diff --git a/CVDEMCS/Services/ISysUserService.cs b/CVDEMCS/Services/ISysUserService.cs
new file mode 100644
index 0000000..7d76536
--- /dev/null
+++ b/CVDEMCS/Services/ISysUserService.cs
@@ -0,0 +1,61 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services.Repositories.Entities;
+
+namespace PVDEMCS.Services
+{
+ ///
+ /// 用户信息 服务层 接口
+ ///
+ public interface ISysUserService : IDependency
+ {
+ ///
+ /// 获取用户信息分页列表
+ ///
+ /// 用户名
+ /// 是否其哟个
+ /// 当前页
+ /// 页大小
+ ///
+ Result> GetSysUserPageList(string userName, bool? activated, int page, int size);
+
+ ///
+ /// 获取用户明细
+ ///
+ /// id
+ /// 名称
+ ///
+ Result GetSysUserDetail(string id, string userName);
+
+ ///
+ /// 添加用户
+ ///
+ ///
+ ///
+ Result AddSysUser(SysUser info);
+
+ ///
+ /// 更新用户
+ ///
+ ///
+ ///
+ Result UpdateSysUser(SysUser info);
+
+ ///
+ /// 更新用户密码
+ ///
+ /// 用户id
+ /// 密码
+ ///
+ Result UpdatePassword(string id, string pwd);
+
+ ///
+ /// 删除用户
+ ///
+ ///
+ ///
+ Result DeleteUser(string id);
+ }
+}
diff --git a/CVDEMCS/Services/Impl/DeviceService.cs b/CVDEMCS/Services/Impl/DeviceService.cs
new file mode 100644
index 0000000..6696571
--- /dev/null
+++ b/CVDEMCS/Services/Impl/DeviceService.cs
@@ -0,0 +1,214 @@
+using Masuit.Tools.Models;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using PVDEMCS.Common;
+using PVDEMCS.Common.Tools;
+using PVDEMCS.Devices;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services.Repositories;
+using PVDEMCS.Services.Repositories.Entities;
+using PVDEMCS.Services.Repositories.Impl;
+using System;
+
+namespace PVDEMCS.Services.Impl
+{
+ ///
+ /// PLC控制器 服务层 实现
+ ///
+ internal class DeviceService : IDeviceService
+ {
+ private readonly IDeviceRepository _deviceRepository;
+
+ public DeviceService(IDeviceRepository deviceRepository)
+ {
+ this._deviceRepository = deviceRepository;
+
+ }
+ #region PLC控制器
+
+ ///
+ /// 获取PLC控制器分页列表
+ ///
+ /// 控制器编号
+ /// 控制器名称
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ public Result> GetDevicePageList(string deviceCode, string deviceName, bool? activated, int page, int size)
+ {
+ var result = _deviceRepository.GetDevicePageList(deviceCode, deviceName, activated, page, size);
+
+ return result;
+ }
+
+ ///
+ /// 获取PLC控制器列表
+ ///
+ /// 控制器编号
+ /// 控制器名称
+ /// 是否启用
+ ///
+ public Result> GetDeviceInfoList(string deviceCode, string deviceName, bool? activated = false)
+ {
+ var result = _deviceRepository.GetDeviceInfoList(deviceCode, deviceName, activated);
+
+ return result;
+ }
+
+ ///
+ /// 获取PLC控制器明细
+ ///
+ /// 主键Id
+ ///
+ public Result GetDeviceDetail(string id)
+ {
+ var result = new Result();
+
+ var value = _deviceRepository.GetDeviceDetail(id);
+ if (!value.IsSuccess)
+ {
+ result.Message = value.Message;
+ return result;
+ }
+ result.Content = ModelTools.PubClone.Trans(value.Content);
+
+ return result;
+ }
+
+ ///
+ /// 添加PLC控制器
+ ///
+ ///
+ ///
+ public Result AddDevice(DeviceInfo info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _deviceRepository.AddDevice(entity);
+ return result;
+ }
+
+ ///
+ /// 更新PLC控制器
+ ///
+ ///
+ public Result UpdateDevice(DeviceInfo info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _deviceRepository.UpdateDevice(entity);
+ return result;
+ }
+
+ ///
+ /// 删除PLC控制器
+ ///
+ ///
+ public Result DeleteDevice(string id)
+ {
+ var result = _deviceRepository.DeleteDevice(id);
+ return result;
+ }
+
+ #endregion
+
+ #region PLC点位
+
+ ///
+ /// 获取PLC控制器点位分页列表
+ ///
+ /// 控制器Id
+ /// 控制器编号
+ /// 控制器名称
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 点位编号
+ /// 点位列表
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ public Result> GetDevicePointPageList(string deviceId, string deviceName, string deviceCode, string equipmentName, string equipmentCode, string equipmentType, string pointCode, string pointName, bool? activated, int page, int size)
+ {
+ var result = _deviceRepository.GetDevicePointPageList(deviceId, deviceName, deviceCode, equipmentName, equipmentCode, equipmentType, pointCode, pointName, activated, page, size);
+
+ return result;
+ }
+
+ ///
+ /// 获取PLC控制器点位列表
+ ///
+ /// 控制器Id
+ /// 控制器编号
+ /// 控制器名称
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 点位编号
+ /// 点位列表
+ /// 是否启用
+ ///
+ public Result> GetDevicePointList(string deviceId, string deviceName, string deviceCode, string equipmentName, string equipmentCode, string equipmentType, string pointCode, string pointName, bool? activated)
+ {
+ var result = _deviceRepository.GetDevicePointList(deviceId, deviceName, deviceCode, equipmentName, equipmentCode, equipmentType, pointCode, pointName, activated);
+
+ return result;
+ }
+
+ ///
+ /// 获取PLC控制器点位明细
+ ///
+ /// Id
+ ///
+ public Result GetDevicePointDetail(string id)
+ {
+ var result = new Result();
+
+ var value = _deviceRepository.GetDevicePointDetail(id);
+ if (!value.IsSuccess)
+ {
+ result.Message = value.Message;
+ return result;
+ }
+ result.Content = ModelTools.PubClone.Trans(value.Content);
+
+ return result;
+ }
+
+ ///
+ /// 添加PLC控制器点位
+ ///
+ ///
+ ///
+ public Result AddDevicePoint(DevicePoint info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _deviceRepository.AddDevicePoint(entity);
+ return result;
+ }
+
+ ///
+ /// 更新PLC控制器点位
+ ///
+ ///
+ ///
+ public Result UpdateDevicePoint(DevicePoint info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _deviceRepository.UpdateDevicePoint(entity);
+ return result;
+ }
+
+ ///
+ /// 删除PLC控制器点位
+ ///
+ ///
+ ///
+ public Result DeleteDevicePoint(string id)
+ {
+ var result = _deviceRepository.DeleteDevicePoint(id);
+ return result;
+ }
+
+ #endregion
+ }
+}
diff --git a/CVDEMCS/Services/Impl/EquipmentRecordService.cs b/CVDEMCS/Services/Impl/EquipmentRecordService.cs
new file mode 100644
index 0000000..0973703
--- /dev/null
+++ b/CVDEMCS/Services/Impl/EquipmentRecordService.cs
@@ -0,0 +1,226 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services.Repositories;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using PVDEMCS.Common.Constant;
+using System;
+using PVDEMCS.Common.Tools;
+using PVDEMCS.Services.Repositories.Entities;
+
+namespace PVDEMCS.Services.Impl
+{
+ ///
+ /// 设备数据记录与统计 服务层 实现
+ ///
+ internal class EquipmentRecordService : IEquipmentRecordService
+ {
+ private readonly IEquipmentRecordRepository _equipmentRecordRepository;
+ public EquipmentRecordService(IEquipmentRecordRepository equipmentRecordRepository)
+ {
+ this._equipmentRecordRepository = equipmentRecordRepository;
+ }
+
+ #region 设备状态记录
+
+ ///
+ /// 获取设备状态记录分页列表
+ ///
+ /// 设备Id
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ ///
+ public Result> GetEquipmentRecordPageList(string equipmentId, string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size)
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordPageList(equipmentId, equipmentName, equipmentCode, equipmentType, begTime, endTime, page, size);
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录列表
+ ///
+ /// 设备Id
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ ///
+ public Result> GetEquipmentRecordList(string equipmentId, string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime)
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordList(equipmentId, equipmentName, equipmentCode, equipmentType, begTime, endTime);
+ return result;
+ }
+
+ ///
+ /// 添加或更新设备状态记录
+ /// 1.如果设备最新记录状态没有改变则更新结束时间
+ /// 2.如果没有记录则添加记录
+ ///
+ /// 设备Id
+ /// 设备状态,运行:Run,待机:Stop,报警:Alarm
+ ///
+ public Result AddUpdateEquipmentRecord(string equipmentId, string state, DateTime dateTime)
+ {
+ var result = this._equipmentRecordRepository.AddUpdateEquipmentRecord(equipmentId, state, dateTime);
+ return result;
+ }
+
+ ///
+ /// 进行设备状态记录统计(日统计)
+ ///
+ ///
+ ///
+ public Result RunEquipmentRecordDayTotal(DateTime date)
+ {
+ var result = this._equipmentRecordRepository.RunEquipmentRecordDayTotal(date);
+ return result;
+ }
+
+ ///
+ /// 进行设备状态记录统计
+ ///
+ ///
+ public Result RunEquipmentRecordTotal()
+ {
+ var result = this._equipmentRecordRepository.RunEquipmentRecordTotal();
+ return result;
+ }
+
+ #endregion
+
+ #region 设备记录统计
+
+ ///
+ /// 获取设备状态记录统计分页列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ public Result> GetEquipmentRecordDayTotalPageList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size)
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordDayTotalPageList(equipmentName, equipmentCode, equipmentType, begTime, endTime, page, size);
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录统计列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ public Result> GetEquipmentRecordDayTotalList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime)
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordDayTotalList(equipmentName, equipmentCode, equipmentType, begTime, endTime);
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录统计分页列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ /// 当前页
+ /// 页大小
+ public Result> GetEquipmentRecordTotalPageList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime, int page, int size)
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordTotalPageList(equipmentName, equipmentCode, equipmentType, begTime, endTime, page, size);
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录统计列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 开始时间
+ /// 结束时间
+ public Result> GetEquipmentRecordTotalList(string equipmentName, string equipmentCode, string equipmentType, DateTime? begTime, DateTime? endTime)
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordTotalList(equipmentName, equipmentCode, equipmentType, begTime, endTime);
+ return result;
+ }
+
+
+ ///
+ /// 根据设备Id获取记录统计
+ ///
+ /// 设备Id
+ ///
+ public Result GetEquipmentRecordTotalDetail(string equipmentId)
+ {
+ var result = new Result();
+
+ var value = this._equipmentRecordRepository.GetEquipmentRecordTotalDetail(equipmentId);
+ if (!value.IsSuccess)
+ {
+ result.Message = value.Message;
+ return result;
+ }
+ result.Content = ModelTools.PubClone.Trans(value.Content);
+
+ return result;
+ }
+
+ ///
+ /// 获取设备状态记录月统计
+ ///
+ ///
+ public Result> GetEquipmentRecordStateMonthTotal()
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordStateMonthTotal();
+ return result;
+ }
+
+ ///
+ /// 获取设备记录开炉次数月统计
+ ///
+ ///
+ public Result> GetEquipmentRecordFurnaceMonthTotal()
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordFurnaceMonthTotal();
+ return result;
+ }
+
+ ///
+ /// 获取设备记录OEE月统计
+ ///
+ ///
+ public Result> GetEquipmentRecordOEEMonthTotal()
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentRecordOEEMonthTotal();
+ return result;
+ }
+
+ ///
+ /// 获取设备OEE信息
+ ///
+ /// 设备Id
+ /// 开始时间
+ /// 结束时间
+ ///
+ public Result GetEquipmentOEEMonthTotal(string equipmentId, DateTime begDate, DateTime endDate)
+ {
+ var result = this._equipmentRecordRepository.GetEquipmentOEEMonthTotal(equipmentId, begDate, endDate);
+ return result;
+ }
+
+ #endregion
+ }
+}
diff --git a/CVDEMCS/Services/Impl/EquipmentService.cs b/CVDEMCS/Services/Impl/EquipmentService.cs
new file mode 100644
index 0000000..2eab554
--- /dev/null
+++ b/CVDEMCS/Services/Impl/EquipmentService.cs
@@ -0,0 +1,159 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services.Repositories;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using PVDEMCS.Common.Constant;
+using PVDEMCS.Common.Tools;
+using PVDEMCS.Services.Repositories.Entities;
+using PVDEMCS.Services.Repositories.Impl;
+using PVDEMCS.Devices;
+using Masuit.Tools;
+
+namespace PVDEMCS.Services.Impl
+{
+ ///
+ /// 设备管理 服务层 接口
+ ///
+ internal class EquipmentService : IEquipmentService
+ {
+ private readonly IEquipmentRepository _equipmentRepository;
+ private readonly IDeviceRun _deviceRun;
+
+ public EquipmentService(IEquipmentRepository equipmentRepository, IDeviceRun deviceRun)
+ {
+ this._equipmentRepository = equipmentRepository;
+ this._deviceRun = deviceRun;
+ }
+
+ ///
+ /// 获取设备分页列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 设备类型
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ public Result> GetEquipmentPageList(string equipmentName, string equipmentCode, string equipmentType, bool? activated, int page, int size)
+ {
+ var result = this._equipmentRepository.GetEquipmentPageList(equipmentName, equipmentCode, equipmentType, activated, page, size);
+ if (result.IsSuccess)
+ {
+ GetEquipmentState(result.Content.Data);
+ }
+ return result;
+ }
+
+ ///
+ /// 获取设备列表
+ ///
+ /// 设备名称
+ /// 设备编号
+ /// 是否启用
+ public Result> GetEquipmentList(string equipmentName, string equipmentCode, string equipmentType, bool? activated)
+ {
+ var result = this._equipmentRepository.GetEquipmentList(equipmentName, equipmentCode, equipmentType, activated);
+ if (result.IsSuccess)
+ {
+ GetEquipmentState(result.Content);
+ }
+ return result;
+ }
+
+ ///
+ /// 获取设备状态
+ ///
+ ///
+ private void GetEquipmentState(List equipmentInfos)
+ {
+ var points = _deviceRun.GetDevicePoints;
+ if (!equipmentInfos.IsNullOrEmpty() && !points.IsNullOrEmpty())
+ {
+ foreach (var equipmentInfo in equipmentInfos)
+ {
+ var list = points.Where(f => f.EquipmentId == equipmentInfo.Id).ToList();
+ if (list.Count >= 2)
+ {
+ var startStop = list.Where(f => f.ActionType == ActionType.StartStop).FirstOrDefault();
+ var fault = list.Where(f => f.ActionType == ActionType.Fault).FirstOrDefault();
+ if (!startStop.IsNullOrEmpty() &&
+ !fault.IsNullOrEmpty() &&
+ !startStop.ObjectValue.IsNullOrEmpty() &&
+ !fault.ObjectValue.IsNullOrEmpty())
+ {
+ var state = EquipmentState.Stop;
+ //如果运行状态比警告状态高,这里先判断运行状态,如果运行状态为false,在判断警告状态
+ if (startStop.GetValue())
+ {
+ state = EquipmentState.Run;
+ }
+ else if (fault.GetValue())
+ {
+ state = EquipmentState.Alarm;
+ }
+ equipmentInfo.State = state;
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// 获取设备明显
+ ///
+ ///
+ ///
+ public Result GetEquipmentDetail(string id)
+ {
+ var result = new Result();
+
+ var value = _equipmentRepository.GetEquipmentDetail(id);
+ if (!value.IsSuccess)
+ {
+ result.Message = value.Message;
+ return result;
+ }
+ result.Content = ModelTools.PubClone.Trans(value.Content);
+
+ return result;
+ }
+
+ ///
+ /// 添加设备信息
+ ///
+ ///
+ ///
+ public Result AddEquipment(EquipmentInfo info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _equipmentRepository.AddEquipment(entity);
+ return result;
+ }
+
+ ///
+ /// 更新设备信息
+ ///
+ ///
+ ///
+ public Result UpdateEquipment(EquipmentInfo info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _equipmentRepository.UpdateEquipment(entity);
+ return result;
+ }
+
+ ///
+ /// 删除设备信息
+ ///
+ ///
+ ///
+ public Result DeleteEquipment(string id)
+ {
+ var result = _equipmentRepository.DeleteEquipment(id);
+ return result;
+ }
+ }
+}
diff --git a/CVDEMCS/Services/Impl/LogService.cs b/CVDEMCS/Services/Impl/LogService.cs
new file mode 100644
index 0000000..967737a
--- /dev/null
+++ b/CVDEMCS/Services/Impl/LogService.cs
@@ -0,0 +1,129 @@
+using GuideScreen.Common.Common;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using NLog;
+using PVDEMCS.Services;
+
+namespace PVDEMCS.Services.Impl
+{
+ ///
+ /// 日志服务 实现
+ ///
+ internal class LogService : ILogService
+ {
+
+ private Logger logger;
+
+ private LogService(Logger logger)
+ {
+ this.logger = logger;
+ }
+
+ public LogService(string name)
+ : this(LogManager.GetLogger(name))
+ {
+
+ }
+
+ public LogService()
+ {
+ logger = LogManager.GetCurrentClassLogger();
+ }
+
+ public string LogDirectory
+ {
+ get
+ {
+ return Path.Combine(AppContext.BaseDirectory, "Logs");
+ }
+
+ }
+
+ public void Debug(string msg, params object[] args)
+ {
+ logger.Debug(msg, args);
+ }
+
+ public void Debug(string msg, Exception err)
+ {
+ logger.Debug(msg, err);
+ }
+
+ public void Info(string msg, params object[] args)
+ {
+ logger.Info(msg, args);
+ }
+
+ public void Info(string msg, Exception err)
+ {
+ logger.Info(msg, err);
+ }
+
+ public void Trace(string msg, params object[] args)
+ {
+ logger.Trace(msg, args);
+ }
+
+ public void Trace(string msg, Exception err)
+ {
+ logger.Trace(msg, err);
+ }
+
+ public void Error(string msg, params object[] args)
+ {
+ logger.Error(msg, args);
+ }
+
+ public void Error(string msg, Exception err)
+ {
+ logger.Error(msg, err);
+ }
+
+ public void Fatal(string msg, params object[] args)
+ {
+ logger.Fatal(msg, args);
+ }
+
+ public void Fatal(string msg, Exception err)
+ {
+ logger.Fatal(msg, err);
+ }
+
+ ///
+ /// 清理多少天前日志
+ ///
+ ///
+ public void ClearAgoDays(int day)
+ {
+ if (!Directory.Exists(LogDirectory))
+ {
+ return;
+ }
+ var files = Directory.GetFiles(LogDirectory);
+ if (files.Length == 0)
+ {
+ return;
+ }
+ var date = DateTime.Now.AddDays(-day);
+ var clearFiles = files.Select(f => new FileInfo(f)).Where(f => f.CreationTime <= date).Select(f => f.FullName);
+ foreach (var filePath in clearFiles)
+ {
+ try
+ {
+ Info($"日志文件:{filePath} 已过期,将进行清理...");
+ File.Delete(filePath);
+ Info($"日志文件:{filePath} 清理完成");
+ }
+ catch (Exception ex)
+ {
+ Info($"日志文件:{filePath} 清理失败!" + ex.StackTrace);
+ }
+ }
+ }
+ }
+}
diff --git a/CVDEMCS/Services/Impl/SysConfigService.cs b/CVDEMCS/Services/Impl/SysConfigService.cs
new file mode 100644
index 0000000..d284b6a
--- /dev/null
+++ b/CVDEMCS/Services/Impl/SysConfigService.cs
@@ -0,0 +1,125 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services.Repositories.Entities;
+using PVDEMCS.Services.Repositories;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using PVDEMCS.Common.Tools;
+using PVDEMCS.Services.Repositories.Impl;
+
+namespace PVDEMCS.Services.Impl
+{
+ ///
+ /// 系统参数设置 服务层 实现
+ ///
+ internal class SysConfigService : ISysConfigService
+ {
+ private readonly ISysConfigRepository _sysConfigRepository;
+
+ public SysConfigService(ISysConfigRepository sysConfigRepository)
+ {
+ this._sysConfigRepository = sysConfigRepository;
+ }
+ ///
+ /// 获取系统参数设置分页列表
+ ///
+ /// 参数名称
+ /// 参数键值
+ /// 当前页
+ /// 页大小
+ ///
+ public Result> GetSysConfigPageList(string configName, string configKey, int page, int size)
+ {
+ var result = _sysConfigRepository.GetSysConfigPageList(configName, configKey, page, size);
+ return result;
+ }
+
+ ///
+ /// 获取系统参数设置列表
+ ///
+ /// 参数名称
+ /// 参数键值
+ ///
+ public Result> GetSysConfigList(string configName, string configKey)
+ {
+ var result = _sysConfigRepository.GetSysConfigList(configName, configKey);
+ return result;
+ }
+
+ ///
+ /// 获取获取系统参数设置明细
+ ///
+ ///
+ ///
+ public Result GetSysConfigDetailById(string id)
+ {
+ var result = new Result();
+
+ var value = _sysConfigRepository.GetSysConfigDetailById(id);
+ if (!value.IsSuccess)
+ {
+ result.Message = value.Message;
+ return result;
+ }
+ result.Content = ModelTools.PubClone.Trans(value.Content);
+
+ return result;
+ }
+
+ ///
+ /// 获取获取系统参数设置明细
+ ///
+ /// 名称
+ /// 键值
+ ///
+ public Result GetSysConfigDetailNameOrKey(string name, string key = "")
+ {
+ var result = new Result();
+
+ var value = _sysConfigRepository.GetSysConfigDetailNameOrKey(name, key);
+ if (!value.IsSuccess)
+ {
+ result.Message = value.Message;
+ return result;
+ }
+ result.Content = ModelTools.PubClone.Trans(value.Content);
+
+ return result;
+ }
+
+ ///
+ /// 添加系统参数设置
+ ///
+ ///
+ ///
+ public Result AddSysConfig(SysConfig info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _sysConfigRepository.AddSysConfig(entity);
+ return result;
+ }
+
+ ///
+ /// 更新系统参数设置
+ ///
+ ///
+
+ public Result UpdateSysConfig(SysConfig info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _sysConfigRepository.UpdateSysConfig(entity);
+ return result;
+ }
+
+ ///
+ /// 删除系统参数设置
+ ///
+ ///
+ public Result DeleteSysConfig(string id)
+ {
+ var result = _sysConfigRepository.DeleteSysConfig(id);
+ return result;
+ }
+ }
+}
diff --git a/CVDEMCS/Services/Impl/SysUserService.cs b/CVDEMCS/Services/Impl/SysUserService.cs
new file mode 100644
index 0000000..c81c8b3
--- /dev/null
+++ b/CVDEMCS/Services/Impl/SysUserService.cs
@@ -0,0 +1,107 @@
+using Masuit.Tools.Models;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Common;
+using PVDEMCS.Services.Models;
+using PVDEMCS.Services.Repositories.Entities;
+using PVDEMCS.Services.Repositories;
+using PVDEMCS.Common.Tools;
+using PVDEMCS.Services.Repositories.Impl;
+using AngleSharp.Dom;
+
+namespace PVDEMCS.Services.Impl
+{
+ ///
+ /// 用户信息 服务层 实现
+ ///
+ public class SysUserService : ISysUserService
+ {
+ private ISysUserRepository _sysUserRepository;
+
+ public SysUserService(ISysUserRepository sysUserRepository)
+ {
+ this._sysUserRepository = sysUserRepository;
+ }
+ ///
+ /// 获取用户信息分页列表
+ ///
+ /// 用户名
+ /// 是否其哟个
+ /// 当前页
+ /// 页大小
+ ///
+ public Result> GetSysUserPageList(string userName, bool? activated, int page, int size)
+ {
+ var pageList = _sysUserRepository.GetSysUserPageList(userName, activated, page, size);
+ return pageList;
+ }
+
+ ///
+ /// 获取用户明细
+ ///
+ /// id
+ /// 名称
+ ///
+ public Result GetSysUserDetail(string id, string userName)
+ {
+ var result = new Result();
+
+ var value = _sysUserRepository.GetSysUserDetail(id, userName);
+ if (!value.IsSuccess)
+ {
+ result.Message = value.Message;
+ return result;
+ }
+ result.Content = ModelTools.PubClone.Trans(value.Content);
+
+ return result;
+
+ }
+
+ ///
+ /// 添加用户
+ ///
+ ///
+ ///
+ public Result AddSysUser(SysUser info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _sysUserRepository.AddSysUser(entity);
+ return result;
+ }
+
+ ///
+ /// 更新用户
+ ///
+ ///
+ ///
+ public Result UpdateSysUser(SysUser info)
+ {
+ var entity = ModelTools.PubClone.Trans(info);
+ var result = _sysUserRepository.UpdateSysUser(entity);
+ return result;
+ }
+
+ ///
+ /// 更新用户密码
+ ///
+ /// 用户id
+ /// 密码
+ ///
+ public Result UpdatePassword(string id, string pwd)
+ {
+ var result = _sysUserRepository.UpdatePassword(id, pwd);
+ return result;
+ }
+
+ ///
+ /// 删除用户
+ ///
+ ///
+ ///
+ public Result DeleteUser(string id)
+ {
+ var result = _sysUserRepository.DeleteUser(id);
+ return result;
+ }
+ }
+}
diff --git a/CVDEMCS/Services/Models/DeviceInfo.cs b/CVDEMCS/Services/Models/DeviceInfo.cs
new file mode 100644
index 0000000..4b37d76
--- /dev/null
+++ b/CVDEMCS/Services/Models/DeviceInfo.cs
@@ -0,0 +1,55 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using System;
+using System.Collections.Generic;
+
+namespace PVDEMCS.Services.Models;
+
+///
+/// PLC控制器
+///
+public partial class DeviceInfo
+{
+ public string Id { get; set; }
+
+ ///
+ /// 控制器编号
+ ///
+ public string DeviceCode { get; set; }
+
+ ///
+ /// 控制器名称
+ ///
+ public string DeviceName { get; set; }
+
+ ///
+ /// 控制器状态,1:启用,0:停用
+ ///
+ public bool Activated { get; set; }
+
+ ///
+ /// 控制器协议:PLC,HTTP,Socket
+ ///
+ public string Protocol { get; set; }
+
+ ///
+ /// 控制器主机地址
+ ///
+ public string Host { get; set; }
+
+ ///
+ /// 控制器主机端口
+ ///
+ public int Port { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string Remark { get; set; }
+
+ ///
+ /// 设备连接状态
+ ///
+ public Boolean isConnected { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Models/DevicePoint.cs b/CVDEMCS/Services/Models/DevicePoint.cs
new file mode 100644
index 0000000..2195f98
--- /dev/null
+++ b/CVDEMCS/Services/Models/DevicePoint.cs
@@ -0,0 +1,109 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+
+namespace PVDEMCS.Services.Models;
+
+///
+/// PLC点位
+///
+public partial class DevicePoint
+{
+ public string Id { get; set; }
+
+ ///
+ /// 控制器Id
+ ///
+ public string DeviceId { get; set; }
+
+ ///
+ /// 控制器编号
+ ///
+ public string DeviceCode { get; set; }
+
+ ///
+ /// 控制器名称
+ ///
+ public string DeviceName { get; set; }
+
+ ///
+ /// 设备编码
+ ///
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 设备编码
+ ///
+ public string EquipmentCode { get; set; }
+
+ ///
+ /// 设备名称
+ ///
+ public string EquipmentName { get; set; }
+
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 点位所属动作,启动停止:start_stop;故障:fault
+ ///
+ public string ActionType { get; set; }
+
+ ///
+ /// 点位编号
+ ///
+ public string PointCode { get; set; }
+
+ ///
+ /// 点位名称
+ ///
+ public string PointName { get; set; }
+
+ ///
+ /// S7 数据存储地址,直连 存储区地址
+ ///
+ public string Address { get; set; }
+
+ ///
+ /// 字段类型
+ ///
+ public string DataType { get; set; }
+
+ ///
+ /// PLC 点位是否启用 (1 启用, 0 禁用)
+ ///
+ public bool Activated { get; set; }
+
+
+ ///
+ /// 模式:Auto 自动;Manual手动
+ ///
+ public String Model { get; set; }
+
+ ///
+ /// 是否报警:true 报警;false 不报警(为Auto)
+ ///
+ public bool IsAlarm { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string Remark { get; set; }
+
+ public Object ObjectValue { get; set; }
+
+ public T GetValue()
+ {
+ if (ObjectValue is T)
+ {
+ return (T)ObjectValue;
+ }
+ return default;
+ }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Models/EquipmentInfo.cs b/CVDEMCS/Services/Models/EquipmentInfo.cs
new file mode 100644
index 0000000..c01711e
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentInfo.cs
@@ -0,0 +1,61 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace PVDEMCS.Services.Models;
+
+///
+/// 设备信息
+///
+public partial class EquipmentInfo
+{
+ public string Id { get; set; }
+
+ ///
+ /// 设备编码
+ ///
+ public string EquipmentCode { get; set; }
+
+ ///
+ /// 设备名称
+ ///
+ public string EquipmentName { get; set; }
+
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 设备状态,运行:Run,待机:Stop,报警:Alarm
+ ///
+ public string State { get; set; }
+
+ ///
+ /// 设备启停用,1:启用,0:停用
+ ///
+ public bool Activated { get; set; }
+
+ ///
+ /// 排序号
+ ///
+ public int OrdrNo { get; set; }
+
+ ///
+ /// 模式:Auto 自动;Manual手动
+ ///
+ public String Model { get; set; }
+
+ ///
+ /// 是否报警:true 报警;false 不报警(model为Auto)
+ ///
+ public bool IsAlarm { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string Remark { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Models/EquipmentOEEMonthTotal.cs b/CVDEMCS/Services/Models/EquipmentOEEMonthTotal.cs
new file mode 100644
index 0000000..a8646f2
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentOEEMonthTotal.cs
@@ -0,0 +1,18 @@
+namespace PVDEMCS.Services.Models
+{
+ ///
+ /// 设备OEE月统计
+ ///
+ public class EquipmentOEEMonthTotal
+ {
+ ///
+ /// 日期
+ ///
+ public string TotalMonth { get; set; }
+
+ ///
+ /// OEE值
+ ///
+ public decimal OEE { get; set; }
+ }
+}
diff --git a/CVDEMCS/Services/Models/EquipmentOEETotal.cs b/CVDEMCS/Services/Models/EquipmentOEETotal.cs
new file mode 100644
index 0000000..ae0234b
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentOEETotal.cs
@@ -0,0 +1,38 @@
+namespace PVDEMCS.Services.Models
+{
+ ///
+ /// 设备OEE月统计
+ ///
+ public class EquipmentOEETotal
+ {
+ ///
+ /// 设备Id
+ ///
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 总运行时长
+ ///
+ public decimal TotalRunningTime { get; set; }
+
+ ///
+ /// 总报警时长
+ ///
+ public decimal TotalAlarmTime { get; set; }
+
+ ///
+ /// 总待机时长
+ ///
+ public decimal TotalStopTime { get; set; }
+
+ ///
+ /// OEE值
+ ///
+ public decimal OEE { get; set; }
+ }
+}
diff --git a/CVDEMCS/Services/Models/EquipmentRecord.cs b/CVDEMCS/Services/Models/EquipmentRecord.cs
new file mode 100644
index 0000000..c6eead0
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentRecord.cs
@@ -0,0 +1,68 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using System;
+using System.Collections.Generic;
+
+namespace PVDEMCS.Services.Models;
+
+///
+/// 设备状态记录明显
+///
+public partial class EquipmentRecord
+{
+ public string Id { get; set; }
+
+ ///
+ /// 设备ID
+ ///
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 设备编码
+ ///
+ public string EquipmentCode { get; set; }
+
+ ///
+ /// 设备名称
+ ///
+ public string EquipmentName { get; set; }
+
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 设备状态,运行:Run,待机:Stop,报警:Alarm
+ ///
+ public string State { get; set; }
+
+ ///
+ /// 设备编码
+ ///
+ public DateTime StartTime { get; set; }
+
+ ///
+ /// 设备名称
+ ///
+ public DateTime EndTime { get; set; }
+
+ ///
+ /// 累计时长(分钟)
+ ///
+ public decimal TimeTotal
+ {
+ get
+ {
+ var val = (EndTime - StartTime).TotalMinutes;
+ if (val > 0)
+ {
+ return Math.Round(Convert.ToDecimal(val),2);
+ }
+
+ return 0;
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Models/EquipmentRecordDayTotal.cs b/CVDEMCS/Services/Models/EquipmentRecordDayTotal.cs
new file mode 100644
index 0000000..f35abad
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentRecordDayTotal.cs
@@ -0,0 +1,18 @@
+
+using System;
+using System.Collections.Generic;
+
+namespace PVDEMCS.Services.Models;
+
+///
+/// 设备状态记录日统计
+///
+///
+public partial class EquipmentRecordDayTotal: EquipmentRecordTotal
+{
+ ///
+ /// 日期
+ ///
+ public DateTime? TotalDay { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Models/EquipmentRecordFurnaceMonthTotal.cs b/CVDEMCS/Services/Models/EquipmentRecordFurnaceMonthTotal.cs
new file mode 100644
index 0000000..9775ea1
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentRecordFurnaceMonthTotal.cs
@@ -0,0 +1,23 @@
+namespace PVDEMCS.Services.Models
+{
+ ///
+ /// 设备记录开炉次数月统计
+ ///
+ public class EquipmentRecordFurnaceMonthTotal
+ {
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 开炉次数
+ ///
+ public decimal FurnaceNum { get; set; }
+
+ ///
+ /// 日期
+ ///
+ public string TotalMonth { get; set; }
+ }
+}
diff --git a/CVDEMCS/Services/Models/EquipmentRecordStateMonthTotal.cs b/CVDEMCS/Services/Models/EquipmentRecordStateMonthTotal.cs
new file mode 100644
index 0000000..30382d4
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentRecordStateMonthTotal.cs
@@ -0,0 +1,28 @@
+namespace PVDEMCS.Services.Models
+{
+ ///
+ /// 设备状态记录月统计
+ ///
+ public class EquipmentRecordStateMonthTotal
+ {
+ ///
+ /// 总运行时长
+ ///
+ public decimal TotalRunningTime { get; set; }
+
+ ///
+ /// 总报警时长
+ ///
+ public decimal TotalAlarmTime { get; set; }
+
+ ///
+ /// 总待机时长
+ ///
+ public decimal TotalStopTime { get; set; }
+
+ ///
+ /// 日期
+ ///
+ public string TotalMonth { get; set; }
+ }
+}
diff --git a/CVDEMCS/Services/Models/EquipmentRecordStateOEEMonthTotal.cs b/CVDEMCS/Services/Models/EquipmentRecordStateOEEMonthTotal.cs
new file mode 100644
index 0000000..f94b46b
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentRecordStateOEEMonthTotal.cs
@@ -0,0 +1,47 @@
+using Microsoft.EntityFrameworkCore;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace PVDEMCS.Services.Models
+{
+ ///
+ /// 设备状态记录OEE月统计
+ ///
+ public class EquipmentRecordStateOEEMonthTotal
+ {
+
+ ///
+ /// 设备Id
+ ///
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 总运行时长
+ ///
+ public decimal TotalRunningTime { get; set; }
+
+ ///
+ /// 总报警时长
+ ///
+ public decimal TotalAlarmTime { get; set; }
+
+ ///
+ /// 总待机时长
+ ///
+ public decimal TotalStopTime { get; set; }
+
+ ///
+ /// 日期
+ ///
+ public string TotalMonth { get; set; }
+
+ ///
+ /// OEE值
+ ///
+ public decimal OEE { get; set; }
+ }
+}
diff --git a/CVDEMCS/Services/Models/EquipmentRecordTotal.cs b/CVDEMCS/Services/Models/EquipmentRecordTotal.cs
new file mode 100644
index 0000000..500ece7
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentRecordTotal.cs
@@ -0,0 +1,56 @@
+
+using System;
+using System.Collections.Generic;
+
+namespace PVDEMCS.Services.Models;
+
+///
+/// 设备状态记录统计
+///
+///
+public partial class EquipmentRecordTotal
+{
+ public string Id { get; set; }
+
+ ///
+ /// 设备Id
+ ///
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 设备编码
+ ///
+ public string EquipmentCode { get; set; }
+
+ ///
+ /// 设备名称
+ ///
+ public string EquipmentName { get; set; }
+
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 开炉次数
+ ///
+ public decimal FurnaceNum { get; set; }
+
+ ///
+ /// 总运行时长
+ ///
+ public decimal TotalRunningTime { get; set; }
+
+ ///
+ /// 总报警时长
+ ///
+ public decimal TotalAlarmTime { get; set; }
+
+ ///
+ /// 总待机时长
+ ///
+ public decimal TotalStopTime { get; set; }
+
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Models/EquipmentStateView.cs b/CVDEMCS/Services/Models/EquipmentStateView.cs
new file mode 100644
index 0000000..242d83d
--- /dev/null
+++ b/CVDEMCS/Services/Models/EquipmentStateView.cs
@@ -0,0 +1,28 @@
+namespace PVDEMCS.Services.Models
+{
+ ///
+ /// 设备状态总览
+ ///
+ public class EquipmentStateView
+ {
+ ///
+ /// 设备类型:ALL(所有),Ionbond,Balzers,Cemecon
+ ///
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 运行数量
+ ///
+ public int Run { get; set; }
+
+ ///
+ /// 待机数量
+ ///
+ public int Stop { get; set; }
+
+ ///
+ /// 报警数量
+ ///
+ public int Alarm { get; set; }
+ }
+}
diff --git a/CVDEMCS/Services/Models/SysConfig.cs b/CVDEMCS/Services/Models/SysConfig.cs
new file mode 100644
index 0000000..34ec60d
--- /dev/null
+++ b/CVDEMCS/Services/Models/SysConfig.cs
@@ -0,0 +1,42 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using System;
+using System.Collections.Generic;
+
+namespace PVDEMCS.Services.Models;
+
+///
+/// 参数配置表
+///
+public partial class SysConfig
+{
+ ///
+ /// 参数主键
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// 参数名称
+ ///
+ public string ConfigName { get; set; }
+
+ ///
+ /// 参数键名
+ ///
+ public string ConfigKey { get; set; }
+
+ ///
+ /// 参数键值
+ ///
+ public string ConfigValue { get; set; }
+
+ ///
+ /// 系统内置(Y是 N否)
+ ///
+ public string ConfigType { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string Remark { get; set; }
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Models/SysUser.cs b/CVDEMCS/Services/Models/SysUser.cs
new file mode 100644
index 0000000..d9990c9
--- /dev/null
+++ b/CVDEMCS/Services/Models/SysUser.cs
@@ -0,0 +1,78 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using System;
+using System.Collections.Generic;
+
+namespace PVDEMCS.Services.Models;
+
+///
+/// 用户信息表
+///
+public partial class SysUser
+{
+ ///
+ /// 用户ID
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// 用户账号
+ ///
+ public string UserName { get; set; }
+
+ ///
+ /// 用户昵称
+ ///
+ public string NickName { get; set; }
+
+ ///
+ /// 用户类型(admin系统用户,normal普通用户)
+ ///
+ public string UserType { get; set; }
+
+ ///
+ /// 用户邮箱
+ ///
+ public string Email { get; set; }
+
+ ///
+ /// 手机号码
+ ///
+ public string Phonenumber { get; set; }
+
+ ///
+ /// 用户性别(0男 1女 2未知)
+ ///
+ public string Sex { get; set; }
+
+ ///
+ /// 头像地址
+ ///
+ public string Avatar { get; set; }
+
+ ///
+ /// 密码
+ ///
+ public string Password { get; set; }
+
+ ///
+ /// 用户状态,1:启用,0:停用
+ ///
+ public bool Activated { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string Remark { get; set; }
+
+ ///
+ /// 最后登录IP
+ ///
+ public string LoginIp { get; set; }
+
+ ///
+ /// 最后登录时间
+ ///
+ public DateTime? LoginDate { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/BaseEntity/CUDBaseEntity.cs b/CVDEMCS/Services/Repositories/Entities/BaseEntity/CUDBaseEntity.cs
new file mode 100644
index 0000000..341f146
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/BaseEntity/CUDBaseEntity.cs
@@ -0,0 +1,92 @@
+using Microsoft.EntityFrameworkCore;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using Masuit.Tools.Systems;
+
+namespace PVDEMCS.Services.Repositories.Entities.BaseEntity
+{
+ public abstract class BaseEntity
+ {
+ [Key]
+ [Column("id")]
+ [StringLength(64)]
+ public string Id { get; set; }
+ }
+
+ public abstract class CUBaseEntity : BaseEntity
+ {
+
+ ///
+ /// 创建者
+ ///
+ [Column("create_by")]
+ [StringLength(32)]
+ [MySqlCollation("utf8mb4_bin")]
+ public string CreateBy { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ [Column("create_at", TypeName = "datetime")]
+ public DateTime? CreateAt { get; set; }
+
+ ///
+ /// 修改者
+ ///
+ [Column("update_by")]
+ [StringLength(32)]
+ [MySqlCollation("utf8mb4_bin")]
+ public string UpdateBy { get; set; }
+
+ ///
+ /// 修改时间
+ ///
+ [Column("update_at", TypeName = "datetime")]
+ public DateTime? UpdateAt { get; set; }
+
+ public void Update()
+ {
+ UpdateAt = DateTime.Now;
+ UpdateBy = "1";
+ }
+
+ public void Create()
+ {
+ Id = SnowFlakeNew.LongId.ToString();
+ CreateAt = DateTime.Now;
+ CreateBy = "1";
+ Update();
+ }
+ }
+
+ public abstract class CUDBaseEntity: CUBaseEntity
+ {
+
+ ///
+ /// 删除者
+ ///
+ [Column("delete_by")]
+ [StringLength(32)]
+ [MySqlCollation("utf8mb4_bin")]
+ public string DeleteBy { get; set; }
+
+ ///
+ /// 删除时间
+ ///
+ [Column("delete_at", TypeName = "datetime")]
+ public DateTime? DeleteAt { get; set; }
+
+ ///
+ /// 是否删除
+ ///
+ [Column("is_delete", TypeName = "bit(1)")]
+ public bool IsDelete { get; set; }
+
+ public void Delete()
+ {
+ DeleteAt = DateTime.Now;
+ DeleteBy = "1";
+ IsDelete = true;
+ }
+ }
+}
diff --git a/CVDEMCS/Services/Repositories/Entities/DeviceInfoEntity.cs b/CVDEMCS/Services/Repositories/Entities/DeviceInfoEntity.cs
new file mode 100644
index 0000000..dd7ae5f
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/DeviceInfoEntity.cs
@@ -0,0 +1,71 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using PVDEMCS.Services.Repositories.Entities.BaseEntity;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+
+///
+/// PLC控制器
+///
+[Table("device_info")]
+public partial class DeviceInfoEntity : CUDBaseEntity
+{
+
+ ///
+ /// 控制器编号
+ ///
+ [Required]
+ [Column("device_code")]
+ [StringLength(32)]
+ public string DeviceCode { get; set; }
+
+ ///
+ /// 控制器名称
+ ///
+ [Required]
+ [Column("device_name")]
+ [StringLength(32)]
+ public string DeviceName { get; set; }
+
+ ///
+ /// 控制器状态,1:启用,0:停用
+ ///
+ [Column("activated", TypeName = "bit(1)")]
+ public bool Activated { get; set; }
+
+ ///
+ /// 控制器协议:PLC,HTTP,Socket
+ ///
+ [Required]
+ [Column("protocol")]
+ [StringLength(32)]
+ public string Protocol { get; set; }
+
+ ///
+ /// 控制器主机地址
+ ///
+ [Required]
+ [Column("host")]
+ [StringLength(32)]
+ public string Host { get; set; }
+
+ ///
+ /// 控制器主机端口
+ ///
+ [Required]
+ [Column("port")]
+ public int Port { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [Column("remark")]
+ [StringLength(255)]
+ public string Remark { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/DevicePointEntity.cs b/CVDEMCS/Services/Repositories/Entities/DevicePointEntity.cs
new file mode 100644
index 0000000..1083f74
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/DevicePointEntity.cs
@@ -0,0 +1,88 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using PVDEMCS.Services.Repositories.Entities.BaseEntity;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+
+///
+/// PLC点位
+///
+[Table("device_point")]
+public partial class DevicePointEntity : CUDBaseEntity
+{
+
+ ///
+ /// 控制器Id
+ ///
+ [Required]
+ [Column("device_id")]
+ [StringLength(64)]
+ public string DeviceId { get; set; }
+
+ ///
+ /// 设备Id
+ ///
+ [Required]
+ [Column("equipment_id")]
+ [StringLength(64)]
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 点位编号
+ ///
+ [Required]
+ [Column("point_code")]
+ [StringLength(32)]
+ public string PointCode { get; set; }
+
+ ///
+ /// 点位名称
+ ///
+ [Required]
+ [Column("point_name")]
+ [StringLength(32)]
+ public string PointName { get; set; }
+
+ ///
+ /// S7 数据存储地址,直连 存储区地址
+ ///
+ [Required]
+ [Column("address")]
+ [StringLength(64)]
+ public string Address { get; set; }
+
+ ///
+ /// 字段类型
+ ///
+ [Required]
+ [Column("data_type")]
+ [StringLength(32)]
+ public string DataType { get; set; }
+
+ ///
+ /// 点位所属动作,启动停止:start_stop;故障:fault
+ ///
+ [Required]
+ [Column("action_type")]
+ [StringLength(32)]
+ public string ActionType { get; set; }
+
+ ///
+ /// PLC 点位是否启用 (1 启用, 0 禁用)
+ ///
+ [Column("activated", TypeName = "bit(1)")]
+ public bool Activated { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [Column("remark")]
+ [StringLength(255)]
+ public string Remark { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/EFContext.cs b/CVDEMCS/Services/Repositories/Entities/EFContext.cs
new file mode 100644
index 0000000..90870d3
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/EFContext.cs
@@ -0,0 +1,271 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using PVDEMCS.Services.Models;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+
+public partial class EFContext : DbContext
+{
+ private IConfiguration configuration;
+
+ public EFContext()
+ {
+ configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
+ }
+
+ public EFContext(DbContextOptions options)
+ : base(options)
+ {
+ }
+
+ public virtual DbSet DeviceInfos { get; set; }
+
+ public virtual DbSet DevicePoints { get; set; }
+
+ public virtual DbSet EquipmentInfos { get; set; }
+
+ public virtual DbSet EquipmentRecords { get; set; }
+
+ public virtual DbSet EquipmentRecordDayTotals { get; set; }
+
+ public virtual DbSet EquipmentRecordTotals { get; set; }
+
+ public virtual DbSet SysConfigs { get; set; }
+
+ public virtual DbSet SysUsers { get; set; }
+
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
+ => optionsBuilder.UseMySql(configuration.GetConnectionString("MySqlConnection"), Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.34-mysql"));
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .UseCollation("utf8mb4_0900_ai_ci")
+ .HasCharSet("utf8mb4");
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PRIMARY");
+
+ entity.ToTable("device_info", tb => tb.HasComment("PLC控制器"));
+
+ entity.Property(e => e.Activated)
+ .HasDefaultValueSql("b'1'")
+ .HasComment("控制器状态,1:启用,0:停用");
+ entity.Property(e => e.CreateAt).HasComment("创建时间");
+ entity.Property(e => e.CreateBy).HasComment("创建者");
+ entity.Property(e => e.DeleteAt).HasComment("删除时间");
+ entity.Property(e => e.DeleteBy).HasComment("删除者");
+ entity.Property(e => e.DeviceCode).HasComment("控制器编号");
+ entity.Property(e => e.DeviceName).HasComment("控制器名称");
+ entity.Property(e => e.Host).HasComment("控制器主机地址");
+ entity.Property(e => e.IsDelete)
+ .HasDefaultValueSql("b'0'")
+ .HasComment("是否删除");
+ entity.Property(e => e.Port).HasComment("控制器主机端口");
+ entity.Property(e => e.Protocol).HasComment("控制器协议:PLC,HTTP,Socket");
+ entity.Property(e => e.Remark).HasComment("备注");
+ entity.Property(e => e.UpdateAt).HasComment("修改时间");
+ entity.Property(e => e.UpdateBy).HasComment("修改者");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PRIMARY");
+
+ entity.ToTable("device_point", tb => tb.HasComment("PLC点位"));
+
+ entity.Property(e => e.Activated)
+ .HasDefaultValueSql("b'1'")
+ .HasComment("PLC 点位是否启用 (1 启用, 0 禁用)");
+ entity.Property(e => e.Address).HasComment("S7 数据存储地址,直连 存储区地址");
+ entity.Property(e => e.CreateAt).HasComment("创建时间");
+ entity.Property(e => e.CreateBy).HasComment("创建者");
+ entity.Property(e => e.DeleteAt).HasComment("删除时间");
+ entity.Property(e => e.DeleteBy).HasComment("删除者");
+ entity.Property(e => e.DeviceId).HasComment("控制器Id");
+ entity.Property(e => e.IsDelete).HasDefaultValueSql("b'0'").HasComment("是否删除");
+ entity.Property(e => e.PointCode).HasComment("点位编号");
+ entity.Property(e => e.PointName).HasComment("点位名称");
+ entity.Property(e => e.Remark).HasComment("备注");
+ entity.Property(e => e.DataType).HasComment("字段类型");
+ entity.Property(e => e.UpdateAt).HasComment("修改时间");
+ entity.Property(e => e.UpdateBy).HasComment("修改者");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PRIMARY");
+
+ entity.ToTable("equipment_info", tb => tb.HasComment("设备信息"));
+
+ entity.Property(e => e.Activated)
+ .HasDefaultValueSql("b'1'")
+ .HasComment("设备状态,1:启用,0:停用");
+ entity.Property(e => e.CreateAt).HasComment("创建时间");
+ entity.Property(e => e.CreateBy).HasComment("创建者");
+ entity.Property(e => e.DeleteAt).HasComment("删除时间");
+ entity.Property(e => e.DeleteBy).HasComment("删除者");
+ entity.Property(e => e.EquipmentCode).HasComment("设备编码");
+ entity.Property(e => e.EquipmentName).HasComment("设备名称");
+ entity.Property(e => e.EquipmentType).HasComment("设备类型:Ionbond,Balzers,Cemecon");
+ entity.Property(e => e.Model).HasComment("模式:Auto 自动;Manual手动");
+ entity.Property(e => e.IsAlarm).HasComment("是否报警:1 报警;0 不报警(model为Auto)");
+ entity.Property(e => e.OrdrNo).HasComment("排序号");
+ entity.Property(e => e.IsDelete)
+ .HasDefaultValueSql("b'0'")
+ .HasComment("是否删除");
+ entity.Property(e => e.Remark).HasComment("备注");
+ entity.Property(e => e.UpdateAt).HasComment("修改时间");
+ entity.Property(e => e.UpdateBy).HasComment("修改者");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PRIMARY");
+
+ entity.ToTable("equipment_record", tb => tb.HasComment("设备状态记录明显"));
+
+ entity.Property(e => e.CreateAt).HasComment("创建时间");
+ entity.Property(e => e.CreateBy).HasComment("创建者");
+ entity.Property(e => e.EndTime).HasComment("设备名称");
+ entity.Property(e => e.EquipmentId).HasComment("设备id");
+ entity.Property(e => e.StartTime).HasComment("设备编码");
+ entity.Property(e => e.State).HasComment("设备状态,1:运行,2:待机,3:报警");
+ entity.Property(e => e.UpdateAt).HasComment("修改时间");
+ entity.Property(e => e.UpdateBy).HasComment("修改者");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PRIMARY");
+
+ entity.ToTable("equipment_record_day_total", tb => tb.HasComment("设备状态记录日统计\r\n"));
+
+ entity.Property(e => e.CreateAt).HasComment("创建时间");
+ entity.Property(e => e.CreateBy).HasComment("创建者");
+ entity.Property(e => e.EquipmentId).HasComment("设备Id");
+ entity.Property(e => e.FurnaceNum).HasComment("开炉次数");
+ entity.Property(e => e.TotalAlarmTime).HasComment("总报警时长");
+ entity.Property(e => e.TotalStopTime).HasComment("总待机时长");
+ entity.Property(e => e.TotalDay).HasComment("日期");
+ entity.Property(e => e.TotalRunningTime).HasComment("总运行时长");
+ entity.Property(e => e.UpdateAt).HasComment("修改时间");
+ entity.Property(e => e.UpdateBy).HasComment("修改者");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PRIMARY");
+
+ entity.ToTable("equipment_record_total", tb => tb.HasComment("设备状态记录统计\r\n"));
+
+ entity.Property(e => e.CreateAt).HasComment("创建时间");
+ entity.Property(e => e.CreateBy).HasComment("创建者");
+ entity.Property(e => e.EquipmentId).HasComment("设备Id");
+ entity.Property(e => e.FurnaceNum).HasComment("开炉次数");
+ entity.Property(e => e.TotalAlarmTime).HasComment("总报警时长");
+ entity.Property(e => e.TotalStopTime).HasComment("总待机时长");
+ entity.Property(e => e.TotalRunningTime).HasComment("总运行时长");
+ entity.Property(e => e.UpdateAt).HasComment("修改时间");
+ entity.Property(e => e.UpdateBy).HasComment("修改者");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PRIMARY");
+
+ entity.ToTable("sys_config", tb => tb.HasComment("参数配置表"));
+
+ entity.Property(e => e.Id).HasComment("参数主键");
+ entity.Property(e => e.ConfigKey)
+ .HasDefaultValueSql("''")
+ .HasComment("参数键名");
+ entity.Property(e => e.ConfigName)
+ .HasDefaultValueSql("''")
+ .HasComment("参数名称");
+ entity.Property(e => e.ConfigType)
+ .HasDefaultValueSql("'N'")
+ .IsFixedLength()
+ .HasComment("系统内置(Y是 N否)");
+ entity.Property(e => e.ConfigValue)
+ .HasDefaultValueSql("''")
+ .HasComment("参数键值");
+ entity.Property(e => e.CreateAt).HasComment("创建时间");
+ entity.Property(e => e.CreateBy)
+ .HasDefaultValueSql("''")
+ .HasComment("创建者");
+ entity.Property(e => e.DeleteAt).HasComment("删除时间");
+ entity.Property(e => e.DeleteBy).HasComment("删除者");
+ entity.Property(e => e.IsDelete)
+ .HasDefaultValueSql("b'0'")
+ .HasComment("是否删除");
+ entity.Property(e => e.Remark).HasComment("备注");
+ entity.Property(e => e.UpdateAt).HasComment("更新时间");
+ entity.Property(e => e.UpdateBy)
+ .HasDefaultValueSql("''")
+ .HasComment("更新者");
+ });
+
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PRIMARY");
+
+ entity.ToTable("sys_user", tb => tb.HasComment("用户信息表"));
+
+ entity.Property(e => e.Id).HasComment("用户ID");
+ entity.Property(e => e.Avatar)
+ .HasDefaultValueSql("''")
+ .HasComment("头像地址");
+ entity.Property(e => e.CreateAt).HasComment("创建时间");
+ entity.Property(e => e.CreateBy)
+ .HasDefaultValueSql("''")
+ .HasComment("创建者");
+ entity.Property(e => e.DeleteAt).HasComment("删除时间");
+ entity.Property(e => e.DeleteBy).HasComment("删除者");
+ entity.Property(e => e.Email)
+ .HasDefaultValueSql("''")
+ .HasComment("用户邮箱");
+ entity.Property(e => e.IsDelete)
+ .HasDefaultValueSql("b'0'")
+ .HasComment("是否删除");
+ entity.Property(e => e.LoginDate).HasComment("最后登录时间");
+ entity.Property(e => e.LoginIp)
+ .HasDefaultValueSql("''")
+ .HasComment("最后登录IP");
+ entity.Property(e => e.NickName).HasComment("用户昵称");
+ entity.Property(e => e.Password)
+ .HasDefaultValueSql("''")
+ .HasComment("密码");
+ entity.Property(e => e.Phonenumber)
+ .HasDefaultValueSql("''")
+ .HasComment("手机号码");
+ entity.Property(e => e.Remark).HasComment("备注");
+ entity.Property(e => e.Sex)
+ .HasDefaultValueSql("'0'")
+ .IsFixedLength()
+ .HasComment("用户性别(0男 1女 2未知)");
+ entity.Property(e => e.Activated)
+ .HasDefaultValueSql("b'1'")
+ .IsFixedLength()
+ .HasComment("帐号状态(1:启用,0:停用)");
+ entity.Property(e => e.UpdateAt).HasComment("更新时间");
+ entity.Property(e => e.UpdateBy)
+ .HasDefaultValueSql("''")
+ .HasComment("更新者");
+ entity.Property(e => e.UserName).HasComment("用户账号");
+ entity.Property(e => e.UserType)
+ .HasDefaultValueSql("'admin'")
+ .HasComment("用户类型(admin系统用户,normal普通用户)");
+ });
+
+ OnModelCreatingPartial(modelBuilder);
+ }
+
+ partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/EquipmentInfoEntity.cs b/CVDEMCS/Services/Repositories/Entities/EquipmentInfoEntity.cs
new file mode 100644
index 0000000..5a1992c
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/EquipmentInfoEntity.cs
@@ -0,0 +1,72 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using PVDEMCS.Services.Repositories.Entities.BaseEntity;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+///
+/// 设备信息
+///
+[Table("equipment_info")]
+public partial class EquipmentInfoEntity : CUDBaseEntity
+{
+ ///
+ /// 设备编码
+ ///
+ [Required]
+ [Column("equipment_code")]
+ [StringLength(32)]
+ public string EquipmentCode { get; set; }
+
+ ///
+ /// 设备名称
+ ///
+ [Required]
+ [Column("equipment_name")]
+ [StringLength(32)]
+ public string EquipmentName { get; set; }
+
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ [Required]
+ [Column("equipment_type")]
+ [StringLength(32)]
+ public string EquipmentType { get; set; }
+
+ ///
+ /// 设备启停用,1:启用,0:停用
+ ///
+ [Column("activated", TypeName = "bit(1)")]
+ public bool Activated { get; set; }
+
+ ///
+ /// 模式:Auto 自动;Manual手动
+ ///
+ [Column("model")]
+ public String Model { get; set; }
+
+ ///
+ /// 是否报警:true 报警;false 不报警(model为Auto)
+ ///
+ [Column("isAlarm", TypeName = "bit(1)")]
+ public bool IsAlarm { get; set; }
+
+ ///
+ /// 排序号
+ ///
+ [Column("ordrNo")]
+ public int OrdrNo { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [Column("remark")]
+ [StringLength(255)]
+ public string Remark { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/EquipmentRecordDayTotalEntity.cs b/CVDEMCS/Services/Repositories/Entities/EquipmentRecordDayTotalEntity.cs
new file mode 100644
index 0000000..85a7c0c
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/EquipmentRecordDayTotalEntity.cs
@@ -0,0 +1,60 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using PVDEMCS.Services.Repositories.Entities.BaseEntity;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+
+
+///
+/// 设备状态记录日统计
+///
+///
+[Table("equipment_record_day_total")]
+public partial class EquipmentRecordDayTotalEntity : CUBaseEntity
+{
+ ///
+ /// 设备Id
+ ///
+ [Required]
+ [Column("equipment_id")]
+ [StringLength(32)]
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 开炉次数
+ ///
+ [Column("furnace_num")]
+ public int FurnaceNum { get; set; }
+
+ ///
+ /// 总运行时长
+ ///
+ [Column("total_running_time")]
+ [Precision(32, 2)]
+ public decimal TotalRunningTime { get; set; }
+
+ ///
+ /// 总报警时长
+ ///
+ [Column("total_alarm_time")]
+ [Precision(32, 2)]
+ public decimal TotalAlarmTime { get; set; }
+
+ ///
+ /// 总待机时长
+ ///
+ [Column("total_stop_time")]
+ [Precision(32, 2)]
+ public decimal TotalStopTime { get; set; }
+ ///
+ /// 日期
+ ///
+ [Column("total_day", TypeName = "datetime")]
+ public DateTime? TotalDay { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/EquipmentRecordEntity.cs b/CVDEMCS/Services/Repositories/Entities/EquipmentRecordEntity.cs
new file mode 100644
index 0000000..25b6991
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/EquipmentRecordEntity.cs
@@ -0,0 +1,50 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using PVDEMCS.Services.Repositories.Entities.BaseEntity;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+
+
+///
+/// 设备状态记录明显
+///
+[Table("equipment_record")]
+public partial class EquipmentRecordEntity : CUBaseEntity
+{
+
+ ///
+ /// 设备类型:Ionbond,Balzers,Cemecon
+ ///
+ [Required]
+ [Column("equipment_id")]
+ [StringLength(32)]
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 设备编码
+ ///
+ [Required]
+ [Column("start_time", TypeName = "datetime")]
+ [StringLength(32)]
+ public DateTime StartTime { get; set; }
+
+ ///
+ /// 设备名称
+ ///
+ [Required]
+ [Column("end_time", TypeName = "datetime")]
+ [StringLength(32)]
+ public DateTime EndTime { get; set; }
+
+ ///
+ /// 设备状态,运行:Run,待机:Stop,报警:Alarm
+ ///
+ [Column("state")]
+ public string State { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/EquipmentRecordTotalEntity.cs b/CVDEMCS/Services/Repositories/Entities/EquipmentRecordTotalEntity.cs
new file mode 100644
index 0000000..53d9dc9
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/EquipmentRecordTotalEntity.cs
@@ -0,0 +1,56 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using PVDEMCS.Services.Repositories.Entities.BaseEntity;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+
+
+///
+/// 设备状态记录日统计
+///
+///
+[Table("equipment_record_total")]
+public partial class EquipmentRecordTotalEntity : CUBaseEntity
+{
+
+ ///
+ /// 设备Id
+ ///
+ [Required]
+ [Column("equipment_id")]
+ [StringLength(32)]
+ public string EquipmentId { get; set; }
+
+ ///
+ /// 开炉次数
+ ///
+ [Column("furnace_num")]
+ public int FurnaceNum { get; set; }
+
+ ///
+ /// 总运行时长
+ ///
+ [Column("total_running_time")]
+ [Precision(32, 2)]
+ public decimal TotalRunningTime { get; set; }
+
+ ///
+ /// 总报警时长
+ ///
+ [Column("total_alarm_time")]
+ [Precision(32, 2)]
+ public decimal TotalAlarmTime { get; set; }
+
+ ///
+ /// 总待机时长
+ ///
+ [Column("total_stop_time")]
+ [Precision(32, 2)]
+ public decimal TotalStopTime { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/SysConfigEntity.cs b/CVDEMCS/Services/Repositories/Entities/SysConfigEntity.cs
new file mode 100644
index 0000000..6b9dc00
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/SysConfigEntity.cs
@@ -0,0 +1,55 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using PVDEMCS.Services.Repositories.Entities.BaseEntity;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+
+///
+/// 参数配置表
+///
+[Table("sys_config")]
+[MySqlCollation("utf8mb4_bin")]
+public partial class SysConfigEntity:CUDBaseEntity
+{
+
+ ///
+ /// 参数名称
+ ///
+ [Column("config_name")]
+ [StringLength(100)]
+ public string ConfigName { get; set; }
+
+ ///
+ /// 参数键名
+ ///
+ [Column("config_key")]
+ [StringLength(100)]
+ public string ConfigKey { get; set; }
+
+ ///
+ /// 参数键值
+ ///
+ [Column("config_value")]
+ [StringLength(500)]
+ public string ConfigValue { get; set; }
+
+ ///
+ /// 系统内置(Y是 N否)
+ ///
+ [Column("config_type")]
+ [StringLength(1)]
+ public string ConfigType { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [Column("remark")]
+ [StringLength(500)]
+ public string Remark { get; set; }
+
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/Entities/SysUserEntity.cs b/CVDEMCS/Services/Repositories/Entities/SysUserEntity.cs
new file mode 100644
index 0000000..82de7bd
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/Entities/SysUserEntity.cs
@@ -0,0 +1,104 @@
+// This file has been auto generated by EF Core Power Tools.
+#nullable disable
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using PVDEMCS.Services.Repositories.Entities.BaseEntity;
+
+namespace PVDEMCS.Services.Repositories.Entities;
+
+///
+/// 用户信息表
+///
+[Table("sys_user")]
+[MySqlCollation("utf8mb4_bin")]
+public partial class SysUserEntity : CUDBaseEntity
+{
+
+ ///
+ /// 用户账号
+ ///
+ [Required]
+ [Column("user_name")]
+ [StringLength(30)]
+ public string UserName { get; set; }
+
+ ///
+ /// 用户昵称
+ ///
+ [Required]
+ [Column("nick_name")]
+ [StringLength(30)]
+ public string NickName { get; set; }
+
+ ///
+ /// 用户类型(admin系统用户,normal普通用户)
+ ///
+ [Column("user_type")]
+ [StringLength(2)]
+ public string UserType { get; set; }
+
+ ///
+ /// 用户邮箱
+ ///
+ [Column("email")]
+ [StringLength(50)]
+ public string Email { get; set; }
+
+ ///
+ /// 手机号码
+ ///
+ [Column("phonenumber")]
+ [StringLength(11)]
+ public string Phonenumber { get; set; }
+
+ ///
+ /// 用户性别(0男 1女 2未知)
+ ///
+ [Column("sex")]
+ [StringLength(1)]
+ public string Sex { get; set; }
+
+ ///
+ /// 头像地址
+ ///
+ [Column("avatar")]
+ [StringLength(100)]
+ public string Avatar { get; set; }
+
+ ///
+ /// 密码
+ ///
+ [Column("password")]
+ [StringLength(100)]
+ public string Password { get; set; }
+
+ ///
+ /// 帐号状态(1:启用,0:停用)
+ ///
+ [Column("activated")]
+ [StringLength(1)]
+ public bool Activated { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [Column("remark")]
+ [StringLength(500)]
+ public string Remark { get; set; }
+
+ ///
+ /// 最后登录IP
+ ///
+ [Column("login_ip")]
+ [StringLength(128)]
+ public string LoginIp { get; set; }
+
+ ///
+ /// 最后登录时间
+ ///
+ [Column("login_date", TypeName = "datetime")]
+ public DateTime? LoginDate { get; set; }
+}
\ No newline at end of file
diff --git a/CVDEMCS/Services/Repositories/IDeviceRepository.cs b/CVDEMCS/Services/Repositories/IDeviceRepository.cs
new file mode 100644
index 0000000..6d38d49
--- /dev/null
+++ b/CVDEMCS/Services/Repositories/IDeviceRepository.cs
@@ -0,0 +1,129 @@
+using Masuit.Tools.Models;
+using Masuit.Tools;
+using PVDEMCS.Common;
+using PVDEMCS.Common.DI;
+using PVDEMCS.Services.Repositories.Entities;
+using PVDEMCS.Services.Models;
+
+namespace PVDEMCS.Services.Repositories
+{
+ ///
+ /// PLC控制器 数据层 接口
+ ///
+ public interface IDeviceRepository : IDependency
+ {
+ #region PLC控制器
+
+ ///
+ /// 获取PLC控制器分页列表
+ ///
+ /// 控制器编号
+ /// 控制器名称
+ /// 是否启用
+ /// 当前页
+ /// 页大小
+ ///
+ Result> GetDevicePageList(string deviceCode, string deviceName, bool? activated, int page, int size);
+
+ ///
+ /// 获取PLC控制器列表
+ ///
+ /// 控制器编号
+ /// 控制器名称
+ /// 是否启用
+ ///
+ Result> GetDeviceInfoList(string deviceCode, string deviceName, bool? activated = false);
+
+ ///
+ /// 获取PLC控制器明细
+ ///
+ /// 主键Id
+ ///
+ Result GetDeviceDetail(string id);
+
+ ///
+ /// 添加PLC控制器
+ ///
+ ///
+ ///
+ Result AddDevice(DeviceInfoEntity entity);
+
+ ///