Merge branch 'dev-0829'

master
ccongli 1 year ago
commit d5a3a78819

4
.gitignore vendored

@ -15,6 +15,10 @@
/vol-net6/VOL.System/obj
/vol-net6/VOL.System/bin
/vol-net6/VOL.WebApi/obj
/vol-net6/VOL.WebApi/obj/*
/vol-net6/VOL.WebApi/bin
/vol-net6/VOL.WebApi/Properties/PublishProfiles
/vol-net6/VOL.WebApi/Properties
/vol-net6/VOL.WebApi/quartz/*
/vol-net6/VOL.Data/obj
/vol-net6/VOL.Data/bin

Binary file not shown.

@ -73,7 +73,7 @@ namespace VOL.Core.BaseProvider
protected virtual void Init(IRepository<T> repository)
{
IsMultiTenancy = true; // 开启租户隔离
}
protected virtual Type GetRealDetailType()

@ -62,7 +62,7 @@ namespace VOL.Core.Controllers.Basic
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Search)]
[HttpPost, Route("GetDetailPage")]
[ApiExplorerSettings(IgnoreApi = true)]
[ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口
public virtual ActionResult GetDetailPage([FromBody] PageDataOptions loadData)
{
return Content(InvokeService("GetDetailPage", new object[] { loadData }).Serialize());
@ -167,7 +167,7 @@ namespace VOL.Core.Controllers.Basic
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Delete)]
[HttpPost, Route("Del")]
[ApiExplorerSettings(IgnoreApi = true)]
[ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口
public virtual ActionResult Del([FromBody] object[] keys)
{
_baseWebResponseContent = InvokeService("Del", new object[] { keys, true }) as WebResponseContent;
@ -181,7 +181,7 @@ namespace VOL.Core.Controllers.Basic
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Audit)]
[HttpPost, Route("Audit")]
[ApiExplorerSettings(IgnoreApi = true)]
[ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口
public virtual ActionResult Audit([FromBody] object[] id, int? auditStatus, string auditReason)
{
_baseWebResponseContent = InvokeService("Audit", new object[] { id, auditStatus, auditReason }) as WebResponseContent;
@ -195,7 +195,7 @@ namespace VOL.Core.Controllers.Basic
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Add)]
[HttpPost, Route("Add")]
[ApiExplorerSettings(IgnoreApi = true)]
[ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口
public virtual ActionResult Add([FromBody] SaveModel saveModel)
{
_baseWebResponseContent = InvokeService("Add",
@ -213,7 +213,7 @@ namespace VOL.Core.Controllers.Basic
/// <returns></returns>
[ApiActionPermission(Enums.ActionPermissionOptions.Update)]
[HttpPost, Route("Update")]
[ApiExplorerSettings(IgnoreApi = true)]
[ApiExplorerSettings(IgnoreApi = false)] // 设置swagger文档不忽略改接口
public virtual ActionResult Update([FromBody] SaveModel saveModel)
{
_baseWebResponseContent = InvokeService("Update", new object[] { saveModel }) as WebResponseContent;

@ -26,7 +26,11 @@ namespace VOL.Core.EFDbContext
&& logLevel == LogLevel.Information)
{
var logContent = formatter(state, exception);
// TODO: 拿到日志内容想怎么玩就怎么玩吧
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green; // 字体绿色
Console.WriteLine(logContent);
Console.ResetColor();
}
}
public IDisposable BeginScope<TState>(TState state) => null;

@ -84,11 +84,14 @@ namespace VOL.Core.EFDbContext
{
optionsBuilder.UseSqlServer(connectionString);
}
//默认禁用实体跟踪
// 默认禁用实体跟踪(注释记录EFCore时)
optionsBuilder = optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
//var loggerFactory = new LoggerFactory();
//loggerFactory.AddProvider(new EFLoggerProvider());
// optionsBuilder.UseLoggerFactory(loggerFactory);
// 记录EFCore产生的SQL语句
var loggerFactory = new LoggerFactory();
loggerFactory.AddProvider(new EFLoggerProvider());
optionsBuilder.UseLoggerFactory(loggerFactory);
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)

@ -16,16 +16,16 @@ namespace VOL.Core.Tenancy
{
string multiTenancyString = $"select * from {tableName}";
//超级管理员不限制
//if (UserContext.Current.IsSuperAdmin)
//{
// return multiTenancyString;
//}
if (UserContext.Current.IsSuperAdmin)
{
return multiTenancyString;
}
switch (tableName)
{
//例如:指定用户表指定查询条件
//case "Sys_User":
// multiTenancyString += $" where UserId='{UserContext.Current.UserId}'";
// break;
case "Sys_User":
multiTenancyString += $" where UserId='{UserContext.Current.UserId}'";
break;
default:
//开启数租户数据隔离,用户只能看到自己的表数据(自己根据需要写条件做租户数据隔离)
multiTenancyString += $" where CreateID='{UserContext.Current.UserId}'";

@ -0,0 +1,41 @@
using System.Collections.Generic;
namespace VOL.Core.Utils
{
public class CommonUtil
{
// 实体对象转Dictionary
public static Dictionary<string, object> ConvertToDictionary<T>(T entity)
{
var dictionary = new Dictionary<string, object>();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
var key = property.Name;
var value = property.GetValue(entity);
dictionary.Add(key, value);
}
return dictionary;
}
// Dictionary转实体对象
public static T ConvertToObject<T>(Dictionary<string, object> dictionary) where T : new()
{
var obj = new T();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
if (dictionary.TryGetValue(property.Name, out var value))
{
property.SetValue(obj, value);
}
}
return obj;
}
}
}

@ -0,0 +1,306 @@
using System.Text;
using System;
namespace VOL.Core.Utils
{
public class DataConvertUtil
{
/// <summary>
/// 赋值string string => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void SetString(ushort[] src, int start, string value)
{
byte[] bytesTemp = Encoding.UTF8.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytesTemp);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取string ushort[] => string
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="len"></param>
/// <returns>string</returns>
public static string GetString(ushort[] src, int start, int len)
{
ushort[] temp = new ushort[len];
for (int i = 0; i < len; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp);
//string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' }); // 去除字符串左右端的指定内容
string res = Encoding.UTF8.GetString(bytesTemp).Trim();
return res;
}
/// <summary>
/// 赋值Real float => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetReal(ushort[] src, int start, float value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取float ushort[] => float
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>float</returns>
public static float GetReal(ushort[] src, int start)
{
try
{
ushort[] temp = new ushort[2];
for (int i = 0; i < 2; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp,false);
// BitConverter默认是小端转换如果是大端顺序数组接收需要先反序字节顺序
Array.Reverse(bytesTemp);
float res = BitConverter.ToSingle(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 赋值Short short => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetShort(ushort[] src, int start, short value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short ushort[] => short
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static short GetShort(ushort[] src, int start)
{
try
{
ushort[] temp = new ushort[1];
temp[0] = src[start];
byte[] bytesTemp = Ushorts2Bytes(temp);
short res = BitConverter.ToInt16(bytesTemp, 0);
return res;
}
catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 赋值Short short => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetInt(ushort[] src, int start, int value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short ushort[] => int
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static int GetInt(ushort[] src, int start)
{
try {
ushort[] temp = new ushort[2];
temp[0] = src[start];
temp[1] = src[start + 1]; // 0 100
Array.Reverse(temp);
byte[] bytesTemp = Ushorts2Bytes(temp);
int res = BitConverter.ToInt32(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 获取short ushort[] => long
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static long GetLong(ushort[] src, int start)
{
try {
ushort[] temp = new ushort[4];
temp[0] = src[start];
temp[1] = src[start + 1];
temp[2] = src[start + 2];
temp[3] = src[start + 3];
Array.Reverse(temp);
byte[] bytesTemp = Ushorts2Bytes(temp);
long res = BitConverter.ToInt64(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 获取bool数组 ushort[] => bool[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static bool[] GetBools(ushort[] src, int start, int num)
{
ushort[] temp = new ushort[num];
for (int i = start; i < start + num; i++)
{
temp[i] = src[i + start];
}
Array.Reverse(temp); // 反序,小端读取
byte[] bytes = Ushorts2Bytes(temp);
bool[] res = Bytes2Bools(bytes);
return res;
}
// byte[] => bool[]
private static bool[] Bytes2Bools(byte[] b)
{
bool[] array = new bool[8 * b.Length];
for (int i = 0; i < b.Length; i++)
{
for (int j = 0; j < 8; j++)
{
array[i * 8 + j] = (b[i] & 1) == 1;//判定byte的最后一位是否为1若为1则是true否则是false
b[i] = (byte)(b[i] >> 1);//将byte右移一位
}
}
return array;
}
// bool[] => byte
private static byte Bools2Byte(bool[] array)
{
if (array != null && array.Length > 0)
{
byte b = 0;
for (int i = 0; i < 8; i++)
{
if (array[i])
{
byte nn = (byte)(1 << i);//左移一位相当于×2
b += nn;
}
}
return b;
}
return 0;
}
// byte[] => ushort[]
private static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false)
{
int len = src.Length;
byte[] srcPlus = new byte[len + 1];
src.CopyTo(srcPlus, 0);
int count = len >> 1;
if (len % 2 != 0)
{
count += 1;
}
ushort[] dest = new ushort[count];
if (reverse)
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff);
}
}
else
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8);
}
}
return dest;
}
// ushort[] => byte[]
private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false)
{
int count = src.Length;
byte[] dest = new byte[count << 1];
if (reverse) // 大端
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 8);
dest[i * 2 + 1] = (byte)(src[i] >> 0);
}
}
else // 小端
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 0);
dest[i * 2 + 1] = (byte)(src[i] >> 8);
}
}
return dest;
}
}
}

@ -0,0 +1,7 @@
namespace VOL.Data
{
public class Class1
{
}
}

@ -0,0 +1,18 @@
/*
*,
*RepositoryPartialIData_ConfigRepository
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
using VOL.Core.Extensions.AutofacManager;
namespace VOL.Data.IRepositories
{
public partial interface IData_ConfigRepository : IDependency,IRepository<Data_Config>
{
}
}

@ -0,0 +1,18 @@
/*
*,
*RepositoryPartialIData_MachineRepository
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
using VOL.Core.Extensions.AutofacManager;
namespace VOL.Data.IRepositories
{
public partial interface IData_MachineRepository : IDependency,IRepository<Data_Machine>
{
}
}

@ -0,0 +1,18 @@
/*
*,
*RepositoryPartialIData_ProduceRepository
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
using VOL.Core.Extensions.AutofacManager;
namespace VOL.Data.IRepositories
{
public partial interface IData_ProduceRepository : IDependency,IRepository<Data_Produce>
{
}
}

@ -0,0 +1,12 @@
/*
*,
*/
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
namespace VOL.Data.IServices
{
public partial interface IData_ConfigService : IService<Data_Config>
{
}
}

@ -0,0 +1,19 @@
/*
*Data_Config
*/
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
using VOL.Core.Utilities;
using System.Linq.Expressions;
namespace VOL.Data.IServices
{
public partial interface IData_ConfigService
{
// 获取设备配置列表
List<Data_Config> getConfigList();
// 根据主键查询设备
Data_Config GetConfigById(int id);
}
}

@ -0,0 +1,12 @@
/*
*,
*/
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
namespace VOL.Data.IServices
{
public partial interface IData_MachineService : IService<Data_Machine>
{
}
}

@ -0,0 +1,15 @@
/*
*Data_Machine
*/
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
using VOL.Core.Utilities;
using System.Linq.Expressions;
namespace VOL.Data.IServices
{
public partial interface IData_MachineService
{
// 查询设备列表数据
Dictionary<int, Data_Machine> GetMachineData();
}
}

@ -0,0 +1,35 @@
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using VOL.Entity.DomainModels;
namespace VOL.Data.IServices.modbus
{
public interface IDataProcessing
{
// 读西门子数据
Dictionary<string, Dictionary<string, object>> readSiemensData(IModbusService modbus);
// 读广数数据
Dictionary<string, Dictionary<string, object>> readGSKData(IModbusService modbus);
// 获取设备配置信息
Data_Config GetDataConfig(int deviceId);
// 保存设备数据
bool saveMachineData(Data_Machine machine, out string message);
// 保存生产数据
bool saveProduceData(Data_Produce produce, out string message);
}
}

@ -0,0 +1,46 @@
using NModbus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VOL.Data.IServices.modbus
{
public interface IModbusService
{
/// <summary>
/// 创建主站客户端
/// </summary>
/// <returns></returns>
void createModbusClient();
/// <summary>
/// 关闭链接
/// </summary>
/// <returns></returns>
void disConnent();
/// <summary>
/// <param name="slaveAddress">从站地址</param>
/// <param name="startAddress">起始地址</param>
/// <param name="object">数据</param>
/// 写数据
/// </summary>
/// <returns></returns>
void writeData(byte slaveAddress, ushort startAddress, object data);
/// <summary>
/// <param name="slaveAddress">从站地址</param>
/// <param name="startAddress">起始地址</param>
/// <param name="units">寄存器单元地址数</param>
/// 读数据
/// </summary>
/// <returns>dynamic</returns>
dynamic readData(byte slaveAddress, ushort startAddress, string type, int units = 1);
}
}

@ -0,0 +1,12 @@
/*
*,
*/
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
namespace VOL.Data.IServices
{
public partial interface IData_ProduceService : IService<Data_Produce>
{
}
}

@ -0,0 +1,23 @@
/*
*Data_Produce
*/
using VOL.Entity.DomainModels;
namespace VOL.Data.IServices
{
public partial interface IData_ProduceService
{
// 根据查询对象获取最新的一条记录
Data_Produce getLastProduceData(Func<Data_Produce, bool> query);
// 最近一周生产加工数
Dictionary<string, object> produceDataGroupByWeekDays();
// 近一周工单走势数据
Dictionary<string, object> workDataGroupByWeekDays(int configId, string target);
}
}

@ -0,0 +1,24 @@
/*
*,
*RepositoryPartialData_ConfigRepository
*/
using VOL.Data.IRepositories;
using VOL.Core.BaseProvider;
using VOL.Core.EFDbContext;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
namespace VOL.Data.Repositories
{
public partial class Data_ConfigRepository : RepositoryBase<Data_Config> , IData_ConfigRepository
{
public Data_ConfigRepository(VOLContext dbContext)
: base(dbContext)
{
}
public static IData_ConfigRepository Instance
{
get { return AutofacContainerModule.GetService<IData_ConfigRepository>(); } }
}
}

@ -0,0 +1,24 @@
/*
*,
*RepositoryPartialData_MachineRepository
*/
using VOL.Data.IRepositories;
using VOL.Core.BaseProvider;
using VOL.Core.EFDbContext;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
namespace VOL.Data.Repositories
{
public partial class Data_MachineRepository : RepositoryBase<Data_Machine> , IData_MachineRepository
{
public Data_MachineRepository(VOLContext dbContext)
: base(dbContext)
{
}
public static IData_MachineRepository Instance
{
get { return AutofacContainerModule.GetService<IData_MachineRepository>(); } }
}
}

@ -0,0 +1,24 @@
/*
*,
*RepositoryPartialData_ProduceRepository
*/
using VOL.Data.IRepositories;
using VOL.Core.BaseProvider;
using VOL.Core.EFDbContext;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
namespace VOL.Data.Repositories
{
public partial class Data_ProduceRepository : RepositoryBase<Data_Produce> , IData_ProduceRepository
{
public Data_ProduceRepository(VOLContext dbContext)
: base(dbContext)
{
}
public static IData_ProduceRepository Instance
{
get { return AutofacContainerModule.GetService<IData_ProduceRepository>(); } }
}
}

@ -0,0 +1,27 @@
/*
*Authorjxx
*Contact283591387@qq.com
*,
*PartialData_ConfigServiceIData_ConfigService
*/
using VOL.Data.IRepositories;
using VOL.Data.IServices;
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
namespace VOL.Data.Services
{
public partial class Data_ConfigService : ServiceBase<Data_Config, IData_ConfigRepository>
, IData_ConfigService, IDependency
{
public Data_ConfigService(IData_ConfigRepository repository)
: base(repository)
{
Init(repository);
}
public static IData_ConfigService Instance
{
get { return AutofacContainerModule.GetService<IData_ConfigService>(); } }
}
}

@ -0,0 +1,52 @@
/*
*Data_Config
*使repository.EF/Dapper
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current
*Data_ConfigServiceServiceFunFilter
*/
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using System.Linq;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using VOL.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.Data.IRepositories;
namespace VOL.Data.Services
{
public partial class Data_ConfigService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IData_ConfigRepository _repository;//访问数据库
[ActivatorUtilitiesConstructor]
public Data_ConfigService(
IData_ConfigRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
base.Init(dbRepository);
}
public List<Data_Config> getConfigList() {
var list = _repository.DbContext.Set<Data_Config>().Select(x => new Data_Config() {
id = x.id, name = x.name, type = x.type, device_ip = x.device_ip, com_ip = x.com_ip
}).OrderBy(x => x.id).ToList();
return list;
}
public Data_Config GetConfigById(int id) {
return _repository.DbContext.Set<Data_Config>().FirstOrDefault(e => e.id == id);
}
}
}

@ -0,0 +1,29 @@
/*
*Authorjxx
*Contact283591387@qq.com
*,
*PartialData_MachineServiceIData_MachineService
*/
using VOL.Data.IRepositories;
using VOL.Data.IServices;
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
namespace VOL.Data.Services
{
public partial class Data_MachineService : ServiceBase<Data_Machine, IData_MachineRepository>
, IData_MachineService, IDependency
{
public Data_MachineService(IData_MachineRepository repository)
: base(repository)
{
Init(repository);
}
public static IData_MachineService Instance
{
get { return AutofacContainerModule.GetService<IData_MachineService>(); }
}
}
}

@ -0,0 +1,131 @@
/*
*Data_Machine
*使repository.EF/Dapper
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current
*Data_MachineServiceServiceFunFilter
*/
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using System.Linq;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using VOL.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.Data.IRepositories;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using SkiaSharp;
using StackExchange.Redis;
using System.Text.RegularExpressions;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using VOL.Core.Utilities;
namespace VOL.Data.Services
{
public partial class Data_MachineService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IData_MachineRepository _repository;//访问数据库
private WebResponseContent webResponse = new WebResponseContent();
[ActivatorUtilitiesConstructor]
public Data_MachineService(
IData_MachineRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
base.Init(dbRepository);
}
public Dictionary<int, Data_Machine> GetMachineData()
{
var db = _repository.DbContext.Set<Data_Machine>();
var machineList = new Dictionary<int, Data_Machine>();
List<Data_Config> configList = Data_ConfigService.Instance.getConfigList();
IQueryable<Data_Machine> query = db.Where(x => x.com_status == 5);
foreach ( Data_Config config in configList )
{
// 机床数据,各自取最新一条
Data_Machine? data_Machine = query.Where(x => x.config_id == config.id).
OrderByDescending(d => d.CreateDate).FirstOrDefault();
if ( data_Machine != null )
{
data_Machine.com_ip = config.com_ip;
data_Machine.name = config.name;
data_Machine.totalQuantity = data_Machine.quantity_total;
data_Machine.totalRuntime = data_Machine.run_time_total;
// 判断通讯是否断开
#pragma warning disable CS8600
Data_Machine lastdata_Machine = db.Where(x => x.config_id == config.id).
OrderByDescending(d => d.CreateDate).FirstOrDefault();
#pragma warning restore CS8600
data_Machine.com_status = lastdata_Machine.com_status;
// 生产数据, 各自取最新一条
Func<Data_Produce, bool> where = p => p.config_id == config.id && p.com_status == 5;
Data_Produce data_Produce = Data_ProduceService.Instance.getLastProduceData(where);
if (data_Produce != null)
{
data_Machine.currentTurnout = data_Produce.turnout_all;
data_Machine.OEE = data_Produce.oee;
}
machineList.Add(config.id, data_Machine);
}
}
return machineList;
}
// 重写Add方法
public override WebResponseContent Add(SaveModel saveDataModel) {
Dictionary<string, object> mapData = saveDataModel.MainData;
mapData.TryGetValue("CreateID", out var userId);
mapData.TryGetValue("CreateDate", out var CreateDate);
AddOnExecuting = (Data_Machine data_Machine, object list) =>
{
if (userId != null)
{
data_Machine.CreateID = (int?)userId;
}
if (CreateDate != null)
{
data_Machine.CreateDate = (DateTime?)CreateDate;
}
return webResponse.OK();
};
return base.Add(saveDataModel);
}
// 测试使用
public void testQuery() {
//List<Data_Machine> data_Machines = _repository.DbContext.Set<Data_Machine>().ToList();
//var list = db.Where(x => x.com_status == 5).GroupBy(e => e.config_id).Select(g => new {
// ConfigId = g.Key,
// Data_Machine = g.OrderByDescending(d => d.CreateDate).ToList()
//}).OrderBy(g => g.ConfigId).ToList();
// 1. 查设备ID分组
//var result1 = db.GroupBy(e => e.config_id).Select(g => new
//{
// ConfigId = g.Key
//}).OrderBy(g => g.ConfigId).ToList();
//List<int> configIds = result1.Select(c => c.ConfigId).ToList();
// 2. 查找设备名称并赋值
//var result2 = db.Where(p => configIds.Contains(p.config_id) && p.com_status == 5).OrderByDescending(o => o.CreateDate).ToList();
//Console.Write(JsonConvert.SerializeObject(result2));
//Console.Write(string.Join(",", data_Machines));
//var list = db.GroupBy(e => e.config_id).Count();
}
}
}

@ -0,0 +1,211 @@
using Microsoft.AspNetCore.Http;
using VOL.Data.IServices.modbus;
using VOL.Entity.DomainModels;
using VOL.Core.Services;
using Microsoft.AspNetCore.Mvc;
using Autofac.Core;
using VOL.Core.Extensions.AutofacManager;
using System.Reflection.PortableExecutable;
namespace VOL.Data.Services.modbus
{
public class DataProcessing : IDataProcessing, IDependency // 继承IDependency交给Ioc容器接管
{
private readonly IHttpContextAccessor _httpContextAccessor;
public DataProcessing(IHttpContextAccessor httpContextAccessor) {
_httpContextAccessor = httpContextAccessor;
}
// 读西门子数据
public Dictionary<string, Dictionary<string, object>> readSiemensData(IModbusService modbus)
{
// 生产数据
Dictionary<string, object> map1 = new Dictionary<string, object>
{
{ "com_status",modbus.readData(1, 6430, "int16") }, // 通讯状态 5通讯正常 15通讯断线
{ "run_time", (int)modbus.readData(1, 6435, "int16") }, // 运行时长 分钟
{ "turnout_1",(int)modbus.readData(1, 6436, "int16") }, // 工单1产量 件
{ "turnout_2", (int)modbus.readData(1, 6437, "int16") }, // 工单2产量 件
{ "turnout_3", (int)modbus.readData(1, 6438, "int16") }, // 工单3产量 件
{ "turnout_all", (int)modbus.readData(1, 6439, "int16") }, // 当班产量 件
{ "status", modbus.readData(1, 6440, "int16") }, // 运行状态 0:待机 1运行 2故障
{ "schedule_1", (decimal)modbus.readData(1, 1315, "single") }, // 工单1任务进度 %
{ "schedule_2",(decimal) modbus.readData(1, 1317, "single") }, // 工单2任务进度 %
{ "schedule_3", (decimal)modbus.readData(1, 1319, "single") }, // 工单3任务进度 %
{ "yield_1", (decimal)modbus.readData(1, 1321, "single") }, // 工单1良品率 % 真实值 *= 100
{ "yield_2", (decimal)modbus.readData(1, 1323, "single") }, // 工单2良品率 % 真实值 *= 100
{ "yield_3", (decimal)modbus.readData(1, 1325, "single") }, // 工单3良品率 % 真实值 *= 100
{ "oee", (decimal)modbus.readData(1, 1339, "single") }, // 设备综合效率 % 真实值 *= 100
};
// 机床数据
Dictionary<string, object> map2 = new Dictionary<string, object>
{
// 操作模式 0:JOG 1:AUTO 2:AUTO + TEACHIN 3:JOG + REPOIN 4:JOG + REPOS
// 5:MDA 6:MDA + REPOS 7:MDA + REPOS + TEAHIN8:MDA + TEACHIN
{ "com_status", modbus.readData(1, 6430, "int16") }, // 通讯状态 5通讯正常 15通讯断线
{ "smode", modbus.readData(1, 6099, "int16") },
{ "state", modbus.readData(1, 6429, "int16") }, // 运行状态 0:待机 1:故障 2:运行 3:暂停
{ "temperature", (decimal)modbus.readData(1, 1201, "single")}, // 电机温度 ℃
{ "potential", (decimal)modbus.readData(1, 1203, "single")}, // 母线电压 V
{ "current", (decimal)modbus.readData(1, 1205, "single")}, // 实际电流 A
{ "cut_rate", (decimal)modbus.readData(1, 1225, "single")}, // 切削倍率
{ "main_rate", (decimal)modbus.readData(1, 1231, "single")}, // 主轴倍率
{ "run_program_no", modbus.readData(1, 6689, "string", 26)}, // 加工程序号 length = 52
{ "run_time_total", (long)modbus.readData(1, 6435, "int16")}, // 累计运行时长 分钟
{ "quantity_total", (long)modbus.readData(1, 1215, "single")}, // 累计加工数 次
};
// 组装Map返回
Dictionary<string, Dictionary<string, object>> map = new();
map.Add("produce", map1);
map.Add("machine", map2);
return map;
}
// 读广数数据
public Dictionary<string, Dictionary<string, object>> readGSKData(IModbusService modbus)
{
// 生产数据
Dictionary<string, object> map1 = new Dictionary<string, object>
{
{ "program_no", (int)modbus.readData(1, 6429, "int16") }, // 程序编号
{ "com_status", modbus.readData(1, 6430, "int16") }, // 通讯状态 5通讯正常 15通讯断线
{ "run_time", (int)modbus.readData(1, 6435, "int16") }, // 运行时长 分钟
{ "turnout_1", (int)modbus.readData(1, 6436, "int16") }, // 工单1产量 件
{ "turnout_2", (int)modbus.readData(1, 6437, "int16") }, // 工单2产量 件
{ "turnout_3", (int)modbus.readData(1, 6438, "int16") }, // 工单3产量 件
{ "turnout_all",(int)modbus.readData(1, 6439, "int16") }, // 当班产量 件
{ "status", modbus.readData(1, 6440, "int16") }, // 运行状态 0:待机 1运行 2故障
{ "schedule_1", (decimal)modbus.readData(1, 1315, "single") }, // 工单1任务进度 %
{ "schedule_2", (decimal)modbus.readData(1, 1317, "single") }, // 工单2任务进度 %
{ "schedule_3", (decimal)modbus.readData(1, 1319, "single") }, // 工单3任务进度 %
{ "yield_1", (decimal)modbus.readData(1, 1321, "single") }, // 工单1良品率 % 真实值 *= 100
{ "yield_2", (decimal)modbus.readData(1, 1323, "single") }, // 工单2良品率 % 真实值 *= 100
{ "yield_3", (decimal)modbus.readData(1, 1325, "single") }, // 工单3良品率 % 真实值 *= 100
{ "oee", (decimal)modbus.readData(1, 1331, "single") }, // 设备综合效率 % 真实值 *= 100
};
// 机床数据
Dictionary<string, object> map2 = new Dictionary<string, object>
{
{ "com_status", modbus.readData(1, 6430, "int16") }, // 通讯状态 5通讯正常 15通讯断线
{ "gmode", modbus.readData(1, 6099, "int16") }, // 工作方式 0:编辑 1:自动 2:MDI 3:DNC 4:手动 5:手轮 6:回参考点
{ "state", modbus.readData(1, 6100, "int16") }, // 运行状态 0:复位 1:停止 2:运行 3:暂停
{ "quantity", (long)modbus.readData(1, 4117, "int32")}, // 当天加工数量 次
{ "on_time", (long)modbus.readData(1, 1201, "int32")}, // 开机时间 秒
{ "run_time", (long)modbus.readData(1, 1203, "int32")}, // 运行时间 秒
{ "feed_rate", (decimal)modbus.readData(1, 1241, "single")}, // 进给倍率
{ "main_rate", (decimal)modbus.readData(1, 1247, "single")}, // 主轴倍率
{ "run_program_no", modbus.readData(1, 6299, "string", 4)}, // 运行程序编号 length = 8
{ "run_time_total", (long)modbus.readData(1, 4115, "int32")}, // 累计运行时长 分钟
{ "quantity_total", (long)modbus.readData(1, 1199, "int32")} // 累计加工数 次
};
// 组装Map返回
Dictionary<string, Dictionary<string, object>> map = new();
map.Add("produce", map1);
map.Add("machine", map2);
return map;
}
// 查询设备信息
public Data_Config GetDataConfig(int deviceId) {
return Data_ConfigService.Instance.GetConfigById(deviceId);
}
// 保存机床数据
public bool saveMachineData(Data_Machine machine, out string message) {
SaveModel model = new SaveModel();
Dictionary<string, object> mapData = new()
{
{ "config_id", machine.config_id},
{ "com_status", machine.com_status ?? 15 },
{ "gmode", machine.gmode ?? 1 },
{ "smode", machine.smode ?? 1 },
{ "run_program_no", machine.run_program_no ?? "12345"},
{ "state", machine.state ?? 0 },
{ "temperature", machine.temperature ?? 0M },
{ "potential", machine.potential ?? 0M},
{ "current", machine.current ?? 0M},
{ "quantity", machine.quantity ?? 0},
{ "on_time", machine.on_time ?? 0},
{ "run_time", machine.run_time ?? 0},
{ "feed_rate",machine.feed_rate ?? 0M},
{ "cut_rate", machine.cut_rate ?? 0M},
{ "main_rate", machine.main_rate ?? 0M},
{ "run_time_total", machine.run_time_total ?? 0},
{ "quantity_total", machine.quantity_total ?? 0},
{ "CreateID", machine.CreateID},
{ "CreateDate", machine.CreateDate},
};
model.MainData = mapData;
try {
Core.Utilities.WebResponseContent result = Data_MachineService.Instance.Add(model);
if (!result.Status)
{
message = result.Message;
//Logger.Info(result.Message);
return false;
}
} catch (Exception ex)
{
//Logger.Error(ex.Message);
message = ex.Message;
return false;
}
message = "ok";
return true;
}
// 保存生产数据
public bool saveProduceData(Data_Produce produce, out string message)
{
SaveModel model = new SaveModel();
Dictionary<string, object> mapData = new()
{
{ "config_id", produce.config_id},
{ "program_no", produce.program_no ?? 12345 },
{ "com_status", produce.com_status ?? 15 },
{ "run_time", produce.run_time ?? 0 },
{ "status", produce.status ?? 0 },
{ "turnout_all", produce.turnout_all ?? 0 },
{ "turnout_1", produce.turnout_1 ?? 0 },
{ "turnout_2", produce.turnout_2 ?? 0 },
{ "turnout_3", produce.turnout_3 ?? 0 },
{ "schedule_1", produce.schedule_1 ?? 0M },
{ "schedule_2", produce.schedule_2 ?? 0M },
{ "schedule_3", produce.schedule_3 ?? 0M },
{ "yield_1", produce.yield_1 ?? 1M },
{ "yield_2", produce.yield_2 ?? 0M },
{ "yield_3", produce.yield_3 ?? 0M },
{ "oee", produce.oee ?? 0.95M }, // 默认95%
{ "CreateID", produce.CreateID},
{ "CreateDate", produce.CreateDate},
};
model.MainData = mapData;
try
{
Core.Utilities.WebResponseContent result = Data_ProduceService.Instance.Add(model);
if (!result.Status)
{
message = result.Message;
return false;
}
}
catch (Exception ex)
{
message = ex.Message;
return false;
}
message = "ok";
return true;
}
}
}

@ -0,0 +1,178 @@
using NModbus;
using System.Net.Sockets;
using VOL.Data.IServices.modbus;
using VOL.Core.Utils;
using VOL.Core.Extensions;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
namespace VOL.Data.Services.modbus
{
public class ModbusTcpService : IModbusService
{
// IP
private string ip { set; get; } = "127.0.0.1";
// 端口
private int port { set; get; } = 502;
// 从站地址
private int slaveNo { set; get; } = 1;
private TcpClient client;
private IModbusMaster modbusMaster;
public ModbusTcpService(string ip, int port) {
this.ip = ip;
this.port = port;
this.client = new TcpClient(ip, port);
this.createModbusClient();
}
public void createModbusClient()
{
ModbusFactory modbusFactory = new();
modbusMaster = modbusFactory.CreateMaster(client);
modbusMaster.Transport.ReadTimeout = 3000; //读超时
modbusMaster.Transport.WriteTimeout = 3000;//写超时
modbusMaster.Transport.Retries = 3;
modbusMaster.Transport.WaitToRetryMilliseconds = 500;//尝试重复连接间隔
}
// 是否已连接
public bool isConnected
{
get => client.Connected;
}
// 写寄存器数据
public void writeData(byte slaveAddress, ushort startAddress, object data)
{
var type = data.GetType().Name.ToLower();
dynamic val ;
ushort[]? units; // 单元数
switch (type) {
case "int16":
val = data.ToShort();
units = new ushort[1];
DataConvertUtil.SetShort(units, 0, val);
break;
case "int32":
val = data.ToInt();
units = new ushort[2];
DataConvertUtil.SetInt(units, 0, val);
break;
case "single":
val = data.ToFloat();
units = new ushort[2];
DataConvertUtil.SetReal(units, 0, val);
break;
case "string":
val = data.ToString();
int length = (int) Math.Ceiling((double) val.Length / 2);
units = new ushort[length]; // 先不考虑中文字符,一个寄存器地址存放两个字符
DataConvertUtil.SetString(units, 0, val); // units 25690 25690
break;
default:
throw new ArgumentException("暂未实现写入此类型:"+ type);
}
if (units != null) {
this.WriteMultipleRegisters(slaveAddress, startAddress, units);
}
}
// 读寄存器数据
public dynamic readData(byte slaveAddress, ushort startAddress, string type, int units = 1)
{
type = type.ToLower();
ushort[]? source;
dynamic? data = null;
switch (type)
{
case "int16":
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 1);
data = DataConvertUtil.GetShort(source, 0);
break;
case "int32":
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 2);
data = DataConvertUtil.GetInt(source, 0);
break;
case "single":
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 2);
data = DataConvertUtil.GetReal(source, 0);
break;
case "string":
//units = val.Length * 2; // 先不考虑中文字符
source = this.ReadHoldingRegisters(slaveAddress, startAddress, (ushort) units); // 25690 25690 0 0
data = DataConvertUtil.GetString(source, 0, units);
break;
default:
throw new ArgumentException("暂未实现读取此类型:" + type);
}
return data;
}
// 读线圈 0x01 0x
public bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort num)
{
return modbusMaster.ReadCoils(slaveAddress, startAddress, num);
}
// 读离散输入 0x02 1x
public bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort num)
{
return modbusMaster.ReadInputs(slaveAddress, startAddress, num);
}
// 读保持寄存器 0x03 4x
public ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort num)
{
return modbusMaster.ReadHoldingRegisters(slaveAddress, startAddress, num);
}
// 读输入寄存器 0x04 3x
public ushort[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort num)
{
return modbusMaster.ReadInputRegisters(slaveAddress, startAddress, num);
}
// 写单个线圈 0x05
public void WriteSingleCoil(byte slaveAddress, ushort startAddress, bool value)
{
modbusMaster.WriteSingleCoil(slaveAddress, startAddress, value);
}
// 写单个保持寄存器 0x06
public void WriteSingleRegister(byte slaveAddress, ushort startAddress, ushort value)
{
modbusMaster.WriteSingleRegister(slaveAddress, startAddress, value);
}
// 写多个线圈 0x0F
public void WriteMultipleCoils(byte slaveAddress, ushort startAddress, bool[] value)
{
modbusMaster.WriteMultipleCoils(slaveAddress, startAddress, value);
}
// 写多个保持寄存器 0x10
public void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] value)
{
modbusMaster.WriteMultipleRegisters(slaveAddress, startAddress, value);
}
// 关闭Socket
public void disConnent() {
client.Close();
modbusMaster.Dispose();
}
}
}

@ -0,0 +1,29 @@
/*
*Authorjxx
*Contact283591387@qq.com
*,
*PartialData_ProduceServiceIData_ProduceService
*/
using VOL.Data.IRepositories;
using VOL.Data.IServices;
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
namespace VOL.Data.Services
{
public partial class Data_ProduceService : ServiceBase<Data_Produce, IData_ProduceRepository>
, IData_ProduceService, IDependency
{
public Data_ProduceService(IData_ProduceRepository repository)
: base(repository)
{
Init(repository);
}
public static IData_ProduceService Instance
{
get { return AutofacContainerModule.GetService<IData_ProduceService>(); } }
}
}

@ -0,0 +1,195 @@
/*
*Data_Produce
*使repository.EF/Dapper
*使repository.DbContextBeginTransaction
*使DBServerProvider.
*使UserContext.Current
*Data_ProduceServiceServiceFunFilter
*/
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using System.Linq;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using VOL.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.Data.IRepositories;
using VOL.Core.DBManager;
using SkiaSharp;
namespace VOL.Data.Services
{
public partial class Data_ProduceService
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IData_ProduceRepository _repository;//访问数据库
private WebResponseContent webResponse = new WebResponseContent();
[ActivatorUtilitiesConstructor]
public Data_ProduceService(
IData_ProduceRepository dbRepository,
IHttpContextAccessor httpContextAccessor
)
: base(dbRepository)
{
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
base.Init(dbRepository);
}
public Data_Produce getLastProduceData(Func<Data_Produce, bool> query) {
//_repository.DbContext.Set<Data_Produce>().FirstOrDefault(query);
Data_Produce? data_Produce = _repository.DbContext.Set<Data_Produce>().Where(query)
.OrderByDescending(x => x.CreateDate).FirstOrDefault();
return data_Produce;
}
public Dictionary<string, object> produceDataGroupByWeekDays() {
List<Data_Config> configList = Data_ConfigService.Instance.getConfigList();
if (configList == null) {
return new();
}
var dapper = DBServerProvider.SqlDapper;
string sql = @"SELECT
c.datelist AS date,
d.config_id AS configId,
COALESCE ( MAX( turnout_all ), 0 ) AS currentTurnout
FROM
data_calendar c
LEFT JOIN data_produce d ON c.datelist = DATE( d.CreateDate )
AND d.com_status = @comStatus
WHERE
c.datelist BETWEEN CURDATE() - INTERVAL @Redays DAY
AND CURDATE()
GROUP BY
c.datelist,
d.config_id";
int comStatus = 5;
int Redays = 6;
// 原生sql动态查询
var result = dapper.QueryDynamicList(sql, new { comStatus, Redays });
var resultMap = new Dictionary<string, object>();
var datelist = result.Select(p => p.date.ToString("yyyy-MM-dd")).Distinct().ToList();
var configMap = new Dictionary<string, List<int>>();
foreach (var config in configList)
{
var data = new List<int>();
foreach (var item in result)
{
//Console.WriteLine(item.currentTurnout.GetType()); Int64
if (item.configId == null || item.configId == config.id) {
data.Add(Convert.ToInt32(item.currentTurnout));
}
}
configMap.Add(config.id.ToString(), data);
}
resultMap.Add("datelist", datelist);
resultMap.Add("dataMap", configMap);
return resultMap;
}
public Dictionary<string, object> workDataGroupByWeekDays(int configId, string target)
{
var dapper = DBServerProvider.SqlDapper;
string sql = @"SELECT
c.datelist AS date,
d.config_id AS configId,
COALESCE ( MAX( id ), 0 ) AS lastId
FROM
data_calendar c
LEFT JOIN data_produce d ON c.datelist = DATE( d.CreateDate )
AND d.com_status = @comStatus
AND d.config_id = @configId
WHERE
c.datelist BETWEEN CURDATE() - INTERVAL @Redays DAY
AND CURDATE()
GROUP BY
c.datelist,
d.config_id";
int comStatus = 5;
int Redays = 6;
var result = dapper.QueryDynamicList(sql, new { comStatus, configId, Redays });
var datelist = result.Select(p => p.date.ToString("yyyy-MM-dd")).Distinct().ToList();
var resultMap = new Dictionary<string, object>();
var dataMap = new Dictionary<string, List<List<int>>>();
var dataSize = datelist.Count;
// 初始化所有指标数据
var work1_Turnouts = new List<int>(dataSize);
var work2_Turnouts = new List<int>(dataSize);
var work3_Turnouts = new List<int>(dataSize);
var work1_Schedules = new List<int>(dataSize);
var work2_Schedules = new List<int>(dataSize);
var work3_Schedules = new List<int>(dataSize);
var work1_Yields = new List<int>(dataSize);
var work2_Yields = new List<int>(dataSize);
var work3_Yields = new List<int>(dataSize);
foreach (var item in result)
{
int a = 0, b = 0, c = 0, aa = 0, bb = 0, cc = 0, aaa = 0, bbb = 0, ccc = 0;
var data = new List<int>();
if (item.configId != null && item.lastId != 0)
{
sql = @"SELECT * from data_produce where id = @lastId";
var row = dapper.QueryDynamicFirst(sql, new { item.lastId });
if (row != null)
{
a = row.turnout_1 ?? 0;
b = row.turnout_2 ?? 0;
c = row.turnout_3 ?? 0;
aa = row.schedule_1 != null ? Convert.ToInt32(row.schedule_1 * 100) : 0;
bb = row.schedule_2 != null ? Convert.ToInt32(row.schedule_2 * 100) : 0;
cc = row.schedule_3 != null ? Convert.ToInt32(row.schedule_3 * 100) : 0;
aaa = row.yield_1 != null ? Convert.ToInt32(row.yield_1 * 100) : 0;
bbb = row.yield_2 != null ? Convert.ToInt32(row.yield_2 * 100) : 0;
ccc = row.yield_3 != null ? Convert.ToInt32(row.yield_3 * 100) : 0;
}
}
work1_Turnouts.Add(a);
work2_Turnouts.Add(b);
work3_Turnouts.Add(c);
work1_Schedules.Add(aa);
work2_Schedules.Add(bb);
work3_Schedules.Add(cc);
work1_Yields.Add(aaa);
work2_Yields.Add(bbb);
work3_Yields.Add(ccc);
}
dataMap.Add("turnout", new List<List<int>> { work1_Turnouts , work2_Turnouts, work3_Turnouts });
dataMap.Add("schedule", new List<List<int>> { work1_Schedules, work2_Schedules, work3_Schedules });
dataMap.Add("yield", new List<List<int>> { work1_Yields, work2_Yields, work3_Yields });
resultMap.Add("datelist", datelist);
resultMap.Add("dataMap", dataMap);
return resultMap;
}
// 重写Add方法
public override WebResponseContent Add(SaveModel saveDataModel)
{
Dictionary<string, object> mapData = saveDataModel.MainData;
mapData.TryGetValue("CreateID", out var userId);
mapData.TryGetValue("CreateDate", out var CreateDate);
AddOnExecuting = (Data_Produce data_Produce, object list) =>
{
if (userId != null)
{
data_Produce.CreateID = (int?)userId;
}
if (CreateDate != null)
{
data_Produce.CreateDate = (DateTime?)CreateDate;
}
return webResponse.OK();
};
return base.Add(saveDataModel);
}
}
}

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\VOL.Core\VOL.Core.csproj" />
<ProjectReference Include="..\VOL.Entity\VOL.Entity.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="IRepositories\" />
<Folder Include="Repositories\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NModbus" Version="3.0.80" />
</ItemGroup>
</Project>

@ -13,6 +13,9 @@ namespace VOL.Entity.DomainModels
public string msg { get; set; }
public int total { get; set; }
public List<T> rows { get; set; }
/// <summary>
/// 统计求和数据
/// </summary>
public object summary { get; set; }
/// <summary>
/// 可以在返回前,再返回一些额外的数据,比如返回其他表的信息,前台找到查询后的方法取出来

@ -0,0 +1,116 @@
/*
*,
*Model
*/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Entity.SystemModels;
namespace VOL.Entity.DomainModels
{
[Entity(TableCnName = "设备配置",TableName = "Data_Config")]
public partial class Data_Config:BaseEntity
{
/// <summary>
///
/// </summary>
[Key]
[Display(Name ="id")]
[Column(TypeName="int")]
[Editable(true)]
[Required(AllowEmptyStrings=false)]
public int id { get; set; }
/// <summary>
///设备名称
/// </summary>
[Display(Name ="设备名称")]
[MaxLength(255)]
[Column(TypeName="nvarchar(255)")]
[Editable(true)]
public string name { get; set; }
/// <summary>
///机床类型
/// </summary>
[Display(Name ="机床类型")]
[Column(TypeName="short")]
[Editable(true)]
public short? type { get; set; }
/// <summary>
///设备IP
/// </summary>
[Display(Name ="设备IP")]
[MaxLength(255)]
[Column(TypeName="nvarchar(255)")]
[Editable(true)]
public string device_ip { get; set; }
/// <summary>
///通讯IP
/// </summary>
[Display(Name ="通讯IP")]
[MaxLength(60)]
[Column(TypeName="nvarchar(60)")]
[Editable(true)]
public string com_ip { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="CreateID")]
[Column(TypeName="int")]
[Editable(true)]
public int? CreateID { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="Creator")]
[MaxLength(255)]
[Column(TypeName="nvarchar(255)")]
[Editable(true)]
public string Creator { get; set; }
/// <summary>
///创建时间
/// </summary>
[Display(Name ="创建时间")]
[Column(TypeName="datetime")]
[Editable(true)]
public DateTime? CreateDate { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="ModifyID")]
[Column(TypeName="int")]
[Editable(true)]
public int? ModifyID { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="Modifier")]
[MaxLength(255)]
[Column(TypeName="nvarchar(255)")]
[Editable(true)]
public string Modifier { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="ModifyDate")]
[Column(TypeName="datetime")]
[Editable(true)]
public DateTime? ModifyDate { get; set; }
}
}

@ -0,0 +1,37 @@
/*
*,
*Model
*/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Entity.SystemModels;
namespace VOL.Entity.DomainModels
{
public partial class Data_Config
{
//此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常
/// <summary>
///通讯状态
/// </summary>
[Display(Name = "通讯状态")]
[Column(TypeName = "short")]
[Editable(true), NotMapped]
public short? com_status { get; set; }
/// <summary>
///运行状态
/// </summary>
[Display(Name = "运行状态")]
[Column(TypeName = "short")]
[Editable(true), NotMapped]
public short? state { get; set; }
}
}

@ -0,0 +1,225 @@
/*
*,
*Model
*/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Entity.SystemModels;
namespace VOL.Entity.DomainModels
{
[Entity(TableCnName = "机床数据",TableName = "Data_Machine")]
public partial class Data_Machine:BaseEntity
{
/// <summary>
///
/// </summary>
[Key]
[Display(Name ="id")]
[Column(TypeName="int")]
[Editable(true)]
[Required(AllowEmptyStrings=false)]
public int id { get; set; }
/// <summary>
///设备信息
/// </summary>
[Display(Name ="设备信息")]
[Column(TypeName="int")]
[Editable(true)]
[Required(AllowEmptyStrings=false)]
public int config_id { get; set; }
/// <summary>
///通讯状态
/// </summary>
[Display(Name ="通讯状态")]
[Column(TypeName="short")]
[Editable(true)]
public short? com_status { get; set; }
/// <summary>
///运行模式(西门子)
/// </summary>
[Display(Name ="运行模式(西门子)")]
[Column(TypeName="short")]
[Editable(true)]
public short? smode { get; set; }
/// <summary>
///运行模式(广数)
/// </summary>
[Display(Name ="运行模式(广数)")]
[Column(TypeName="short")]
[Editable(true)]
public short? gmode { get; set; }
/// <summary>
///加工程序号
/// </summary>
[Display(Name ="加工程序号")]
[MaxLength(60)]
[Column(TypeName="nvarchar(60)")]
[Editable(true)]
public string run_program_no { get; set; }
/// <summary>
///运行状态
/// </summary>
[Display(Name ="运行状态")]
[Column(TypeName="short")]
[Editable(true)]
public short? state { get; set; }
/// <summary>
///电机温度
/// </summary>
[Display(Name ="电机温度")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? temperature { get; set; }
/// <summary>
///母线电压
/// </summary>
[Display(Name ="母线电压")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? potential { get; set; }
/// <summary>
///实际电流
/// </summary>
[Display(Name ="实际电流")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? current { get; set; }
/// <summary>
///加工数
/// </summary>
[Display(Name ="加工数")]
[Column(TypeName="bigint")]
[Editable(true)]
public long? quantity { get; set; }
/// <summary>
///主轴倍率
/// </summary>
[Display(Name ="主轴倍率")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? main_rate { get; set; }
/// <summary>
///进给倍率
/// </summary>
[Display(Name ="进给倍率")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? feed_rate { get; set; }
/// <summary>
///切削倍率
/// </summary>
[Display(Name ="切削倍率")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? cut_rate { get; set; }
/// <summary>
///开机时间
/// </summary>
[Display(Name ="开机时间")]
[Column(TypeName="bigint")]
[Editable(true)]
public long? on_time { get; set; }
/// <summary>
///运行时间
/// </summary>
[Display(Name ="运行时间")]
[Column(TypeName="bigint")]
[Editable(true)]
public long? run_time { get; set; }
/// <summary>
///累计运行时长
/// </summary>
[Display(Name ="累计运行时长")]
[Column(TypeName="bigint")]
[Editable(true)]
public long? run_time_total { get; set; }
/// <summary>
///累计加工数
/// </summary>
[Display(Name ="累计加工数")]
[Column(TypeName="bigint")]
[Editable(true)]
public long? quantity_total { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="CreateID")]
[Column(TypeName="int")]
[Editable(true)]
public int? CreateID { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="Creator")]
[MaxLength(255)]
[Column(TypeName="nvarchar(255)")]
[Editable(true)]
public string Creator { get; set; }
/// <summary>
///记录时间
/// </summary>
[Display(Name ="记录时间")]
[Column(TypeName="datetime")]
[Editable(true)]
public DateTime? CreateDate { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="ModifyID")]
[Column(TypeName="int")]
[Editable(true)]
public int? ModifyID { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="Modifier")]
[MaxLength(255)]
[Column(TypeName="nvarchar(255)")]
[Editable(true)]
public string Modifier { get; set; }
/// <summary>
///更新时间
/// </summary>
[Display(Name ="更新时间")]
[Column(TypeName="datetime")]
[Editable(true)]
public DateTime? ModifyDate { get; set; }
}
}

@ -0,0 +1,72 @@
/*
*,
*Model
*/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Entity.SystemModels;
namespace VOL.Entity.DomainModels
{
public partial class Data_Machine
{
//此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常
[Display(Name = "设备名称")]
[MaxLength(255)]
[Column(TypeName = "nvarchar(255)")]
[Editable(true), NotMapped]
public string name { get; set; }
/// <summary>
///通讯IP
/// </summary>
[Display(Name = "通讯IP")]
[MaxLength(60)]
[Column(TypeName = "nvarchar(60)")]
[Editable(true), NotMapped]
public string com_ip { get; set; }
/// <summary>
///累计运行时长
/// </summary>
[Display(Name = "当班产量")]
[Column(TypeName = "int")]
[Editable(true), NotMapped]
public int? currentTurnout { get; set; }
/// <summary>
///累计加工数
/// </summary>
[Display(Name = "累计加工数")]
[Column(TypeName = "bigint")]
[Editable(true), NotMapped]
public long? totalQuantity { get; set; }
/// <summary>
///累计运行时长
/// </summary>
[Display(Name = "累计运行时长")]
[Column(TypeName = "bigint")]
[Editable(true), NotMapped]
public long? totalRuntime { get; set; }
/// <summary>
///设备综合效率
/// </summary>
[Display(Name = "设备综合效率")]
[DisplayFormat(DataFormatString = "10,2")]
[Column(TypeName = "decimal")]
[Editable(true), NotMapped]
public decimal? OEE { get; set; }
}
}

@ -0,0 +1,217 @@
/*
*,
*Model
*/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Entity.SystemModels;
namespace VOL.Entity.DomainModels
{
[Entity(TableCnName = "生产数据",TableName = "Data_Produce")]
public partial class Data_Produce:BaseEntity
{
/// <summary>
///ID
/// </summary>
[Key]
[Display(Name ="ID")]
[Column(TypeName="int")]
[Editable(true)]
[Required(AllowEmptyStrings=false)]
public int id { get; set; }
/// <summary>
///设备信息
/// </summary>
[Display(Name ="设备信息")]
[Column(TypeName="int")]
[Editable(true)]
[Required(AllowEmptyStrings=false)]
public int config_id { get; set; }
/// <summary>
///程序编号
/// </summary>
[Display(Name ="程序编号")]
[Column(TypeName="int")]
[Editable(true)]
public int? program_no { get; set; }
/// <summary>
///通讯状态
/// </summary>
[Display(Name ="通讯状态")]
[Column(TypeName="short")]
[Editable(true)]
public short? com_status { get; set; }
/// <summary>
///运行时长
/// </summary>
[Display(Name ="运行时长")]
[Column(TypeName="int")]
[Editable(true)]
public int? run_time { get; set; }
/// <summary>
///运行状态
/// </summary>
[Display(Name ="运行状态")]
[Column(TypeName="short")]
[Editable(true)]
public short? status { get; set; }
/// <summary>
///当班产量
/// </summary>
[Display(Name ="当班产量")]
[Column(TypeName="int")]
[Editable(true)]
public int? turnout_all { get; set; }
/// <summary>
///工单 1 产量
/// </summary>
[Display(Name ="工单 1 产量")]
[Column(TypeName="int")]
[Editable(true)]
public int? turnout_1 { get; set; }
/// <summary>
///工单 2 产量
/// </summary>
[Display(Name ="工单 2 产量")]
[Column(TypeName="int")]
[Editable(true)]
public int? turnout_2 { get; set; }
/// <summary>
///工单 3 产量
/// </summary>
[Display(Name ="工单 3 产量")]
[Column(TypeName="int")]
[Editable(true)]
public int? turnout_3 { get; set; }
/// <summary>
///工单1任务进度
/// </summary>
[Display(Name ="工单1任务进度")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? schedule_1 { get; set; }
/// <summary>
///工单2任务进度
/// </summary>
[Display(Name ="工单2任务进度")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? schedule_2 { get; set; }
/// <summary>
///工单3任务进度
/// </summary>
[Display(Name ="工单3任务进度")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? schedule_3 { get; set; }
/// <summary>
///工单1良品率
/// </summary>
[Display(Name ="工单1良品率")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? yield_1 { get; set; }
/// <summary>
///工单2良品率
/// </summary>
[Display(Name ="工单2良品率")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? yield_2 { get; set; }
/// <summary>
///工单3良品率
/// </summary>
[Display(Name ="工单3良品率")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? yield_3 { get; set; }
/// <summary>
///设备综合效率
/// </summary>
[Display(Name ="设备综合效率")]
[DisplayFormat(DataFormatString="10,2")]
[Column(TypeName="decimal")]
[Editable(true)]
public decimal? oee { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="CreateID")]
[Column(TypeName="int")]
[Editable(true)]
public int? CreateID { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="Creator")]
[MaxLength(255)]
[Column(TypeName="nvarchar(255)")]
[Editable(true)]
public string Creator { get; set; }
/// <summary>
///记录时间
/// </summary>
[Display(Name ="记录时间")]
[Column(TypeName="datetime")]
[Editable(true)]
public DateTime? CreateDate { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="ModifyID")]
[Column(TypeName="int")]
[Editable(true)]
public int? ModifyID { get; set; }
/// <summary>
///
/// </summary>
[Display(Name ="Modifier")]
[MaxLength(255)]
[Column(TypeName="nvarchar(255)")]
[Editable(true)]
public string Modifier { get; set; }
/// <summary>
///更新时间
/// </summary>
[Display(Name ="更新时间")]
[Column(TypeName="datetime")]
[Editable(true)]
public DateTime? ModifyDate { get; set; }
}
}

@ -0,0 +1,28 @@
/*
*,
*Model
*/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Entity.SystemModels;
namespace VOL.Entity.DomainModels
{
public partial class Data_Produce
{
//此处配置字段(字段配置见此model的另一个partial),如果表中没有此字段请加上 [NotMapped]属性,否则会异常
/// <summary>
/// 日期
/// </summary>
[Display(Name = "日期")]
[Column(TypeName = "date")]
[Editable(true), NotMapped]
public DateOnly? datelist { get; set; }
}
}

@ -0,0 +1,16 @@
using VOL.Entity.MappingConfiguration;
using VOL.Entity.DomainModels;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace VOL.Entity.MappingConfiguration
{
public class Data_ConfigMapConfig : EntityMappingConfiguration<Data_Config>
{
public override void Map(EntityTypeBuilder<Data_Config>
builderTable)
{
//b.Property(x => x.StorageName).HasMaxLength(45);
}
}
}

@ -0,0 +1,16 @@
using VOL.Entity.MappingConfiguration;
using VOL.Entity.DomainModels;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace VOL.Entity.MappingConfiguration
{
public class Data_MachineMapConfig : EntityMappingConfiguration<Data_Machine>
{
public override void Map(EntityTypeBuilder<Data_Machine>
builderTable)
{
//b.Property(x => x.StorageName).HasMaxLength(45);
}
}
}

@ -0,0 +1,16 @@
using VOL.Entity.MappingConfiguration;
using VOL.Entity.DomainModels;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace VOL.Entity.MappingConfiguration
{
public class Data_ProduceMapConfig : EntityMappingConfiguration<Data_Produce>
{
public override void Map(EntityTypeBuilder<Data_Produce>
builderTable)
{
//b.Property(x => x.StorageName).HasMaxLength(45);
}
}
}

@ -5,9 +5,12 @@ using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace VOL.System.IServices
{
public partial interface ISys_DepartmentService
{
// 获取用户关联根部门
Task<Sys_Department> GetUserDepartment(int userId);
}
}

@ -20,6 +20,8 @@ using VOL.System.IRepositories;
using System.Collections.Generic;
using VOL.Core.ManageUser;
using VOL.Core.UserManager;
using VOL.Core.DBManager;
using System.Threading.Tasks;
namespace VOL.System.Services
{
@ -96,6 +98,22 @@ namespace VOL.System.Services
{
return base.Del(keys, delList).Reload();
}
public async Task<Sys_Department> GetUserDepartment(int userId) {
var dapper = DBServerProvider.SqlDapper;
string sql = @"SELECT
d.DepartmentId,
d.DepartmentCode,
d.DepartmentName
FROM
sys_department AS d
LEFT JOIN sys_userdepartment AS ud ON ud.DepartmentId = d.DepartmentId
WHERE
ud.UserId = @userId
AND d.ParentId IS NULL;";
return await dapper.QueryFirstAsync<Sys_Department>(sql, new { userId }); ;
}
}
}

@ -0,0 +1,81 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using System;
using VOL.Core.Filters;
using VOL.Data.IServices.modbus;
using VOL.Data.Services.modbus;
using Microsoft.Extensions.DependencyInjection;
using VOL.WebApi.Utils;
using VOL.Entity.DomainModels;
using System.Collections.Generic;
using Confluent.Kafka;
using VOL.Data.IServices;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using Newtonsoft.Json;
namespace VOL.WebApi.Controllers.Data
{
/// <summary>
/// 数据采集API类
/// </summary>
[Route("api/Data_Screen")]
[JWTAuthorize, ApiController, AllowAnonymous]
public class DataApiController : Controller
{
private IData_ConfigService _configService;
private IData_MachineService _machineService;
private IData_ProduceService _produceService;
private readonly IHttpContextAccessor _httpContextAccessor;
[ActivatorUtilitiesConstructor]
public DataApiController(
IData_ConfigService configService,
IData_MachineService machineService,
IData_ProduceService produceService,
IHttpContextAccessor httpContextAccessor
)
{
_configService = configService;
_machineService = machineService;
_produceService = produceService;
_httpContextAccessor = httpContextAccessor;
}
// 获取设备配置数据
[HttpPost, Route("GetDeviceConfig")]
public IActionResult getDeviceConfig([FromBody] PageDataOptions loadData)
{
return Json(_configService.GetPageData(loadData));
}
// 获取机床数据
[HttpPost, Route("GetMachineData")]
public IActionResult getMachineData([FromBody] Data_Config config) // application/json模式
{
//Console.WriteLine(JsonConvert.SerializeObject(config));
return Json(_machineService.GetMachineData());
}
// 获取近一周每日加工量数据
[HttpPost, Route("GetTurnOutByWeekDays")]
public IActionResult getTurnOutByWeekDays()
{
return Json(_produceService.produceDataGroupByWeekDays());
}
// 获取近一周工单指标数据
[HttpPost, Route("GetWorkDataByWeekDays")]
public IActionResult GetWorkDataByWeekDays(string target, int configId) // x-www-form表单模式
{
//return Json(new { target, configId });
return Json(_produceService.workDataGroupByWeekDays(configId, target));
}
}
}

@ -0,0 +1,350 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using System;
using VOL.Core.Filters;
using VOL.Data.IServices.modbus;
using VOL.Data.Services.modbus;
using Microsoft.Extensions.DependencyInjection;
using VOL.WebApi.Utils;
using VOL.Entity.DomainModels;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
namespace VOL.WebApi.Controllers.Data
{
/// <summary>
/// 数据采集API类
/// </summary>
[Route("api/Data_Test")]
[AllowAnonymous]
public class DataTestController : Controller
{
private static ModbusTcpService _service; // 静态字段
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IDataProcessing _dataService; // 业务处理
[ActivatorUtilitiesConstructor]
public DataTestController(
//ModbusTcpService service, // ModbusTcpService为有参构造暂时无法注入
IDataProcessing dataService,
IHttpContextAccessor httpContextAccessor
)
{
//_service = service;
_dataService = dataService;
_httpContextAccessor = httpContextAccessor;
}
// 静态构造器 类实例化前调用,且只调用一次
static DataTestController()
{
try
{
//_service = new ModbusTcpService("127.0.0.1", 502);
_service = new ModbusTcpService("192.168.0.99", 502);
Console.WriteLine("master modbus tcp created...");
}
catch (Exception)
{
Console.WriteLine("master modbus tcp connect failed");
}
}
/// <summary>
/// 测试定时接口
/// </summary>
/// <returns>IActionResult</returns>
[ApiTask]
[HttpGet, HttpPost, Route("test")]
public IActionResult Test()
{
//Logger.Info("log info test...");
//Logger.Error("log info error...");
//Data_Device data_Device = new Data_Device();
//bool result = _dataService.saveDeviceData(data_Device, out string message);
//Console.WriteLine(message);
//Data_Produce data_Produce = new Data_Produce();
//bool result2 = _dataService.saveProduceData(data_Produce, out string message1);
//Console.WriteLine(message1);
_service = new ModbusTcpService("192.168.0.99", 502);
_service.writeData(1,0,(short)1);
_service.writeData(1,0,1);
_service.writeData(1,0,1F);
_service.writeData(1,0,"1234");
return Content(DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"));
}
/// <summary>
/// 测试采集接口
/// </summary>
/// <returns>IActionResult</returns>
//[ApiTask]
[HttpGet, HttpPost, Route("getData")]
public IActionResult Collection()
{
Console.WriteLine(_service);
bool isConnected = _service == null ? false : _service.isConnected;
if (!isConnected)
{
try
{
_service.disConnent();
_service = new ModbusTcpService("127.0.0.1", 502);
Console.WriteLine("master modbus tcp reconnect...");
}
catch (Exception)
{
Console.WriteLine("master modbus tcp reconnect failed");
}
isConnected = _service == null ? false : _service.isConnected;
if (!isConnected)
{
return Content("master modbus connect failed!");
}
}
try {
// 读Int16
ushort[] us1 = _service.ReadHoldingRegisters(1, 9, 1);
short v = DataConvertUtil.GetShort(us1, 0);
Console.WriteLine("Short Data" + v);
// 读Float
ushort[] us2 = _service.ReadHoldingRegisters(1, 1, 2);
float f = DataConvertUtil.GetReal(us2, 0);
Console.WriteLine("Real Data" + f);
// 读Bool
ushort[] us3 = _service.ReadHoldingRegisters(1, 11, 1);
bool[] bs = DataConvertUtil.GetBools(us3,0,1);
Console.WriteLine("Bools Data" + String.Join(",",bs));
// 写String
ushort[] src = new ushort[6];
DataConvertUtil.SetString(src, 0, "你好世界"); // UTF8 1个中文字符 = 3Byte
_service.WriteMultipleRegisters(1, 30, src);
// 读String
ushort[] target = _service.ReadHoldingRegisters(1, 30, 6);
string str = DataConvertUtil.GetString(target,0,6);
Console.WriteLine("String Data" + str.ToString());
} catch (Exception ex) {
Console.WriteLine(ex.Message);
_service.disConnent();
return Content("read data error!");
}
return Content("ok!");
}
[HttpGet, HttpPost, Route("readTest")]
public IActionResult Test01()
{
_service = new ModbusTcpService("192.168.0.99", 502);
if (_service.isConnected)
{
//Console.WriteLine("=========read0x=========");
//bool[] data0x = _service.ReadCoils(1, 0, 5); // 0x
////bool[] bools = { true, false };
//Array.ForEach(data0x, Console.WriteLine);
//Console.WriteLine("=========read0x=========");
//Console.WriteLine("=========read1x=========");
//bool[] data1x = _service.ReadInputs(1, 0, 5);
//Array.ForEach(data1x, Console.WriteLine);
//Console.WriteLine("=========read1x=========");
// 读取从0开始文档上地址从1开始的地址需要减1
Console.WriteLine("=========read4x=========");
// int16
ushort[] src0 = new ushort[1];
DataConvertUtil.SetShort(src0, 0, 2);
_service.WriteMultipleRegisters(1, 6429, src0);
ushort[] data4xs_int16 = _service.ReadHoldingRegisters(1, 6429, 1); // 运行状态
short val = DataConvertUtil.GetShort(data4xs_int16, 0);
Console.WriteLine(val);
// 写 float
ushort[] src1 = new ushort[2];
DataConvertUtil.SetReal(src1, 0, 3.14F);
_service.WriteMultipleRegisters(1, 1215, src1);
// 读 float
ushort[] data4xs_float = _service.ReadHoldingRegisters(1, 1215, 2); // 加工数
float fval = DataConvertUtil.GetReal(data4xs_float, 0);
Console.WriteLine(fval);
//// string
//ushort[] data_strlen = _service.ReadHoldingRegisters(1, 6689, 1);
//short strlen = DataConvertUtil.GetShort(data_strlen, 0);
//Console.WriteLine(strlen);
//// 6690程序号不可写, 为双引号 asill码为34
//ushort[] src2 = new ushort[6];
//DataConvertUtil.SetString(src1, 0, "123456");
//_service.WriteMultipleRegisters(1, 6691, src2);
//ushort[] data4xs_str = _service.ReadHoldingRegisters(1, 6690, 52); // 程序号
//string str = DataConvertUtil.GetString(data4xs_str, 0, 52);
//Console.WriteLine(str);
Console.WriteLine("=========read4x=========");
//ushort[] data4xs_float = _service.ReadHoldingRegisters(1, 1200, 2); // 刀具长度补偿编号
//float fval = DataConvertUtil.GetReal(data4xs_float, 0);
//Console.WriteLine(fval);
//ushort[] data4xs_int32 = _service.ReadHoldingRegisters(1, 1, 2); // 电机温度
//int vval = DataConvertUtil.GetInt(data4xs_int32, 0);
//Console.WriteLine(vval);
//ushort[] data4xs_int64 = _service.ReadHoldingRegisters(1, 4, 4); // 运行模式
//long vvval = DataConvertUtil.GetLong(data4xs_int64, 0);
//Console.WriteLine(vvval);
//Console.WriteLine("=========read4x=========");
//Console.WriteLine("=========read3x=========");
//ushort[] data3xs = _service.ReadInputRegisters(1, 4, 2);
//uint[] data3x = data3xs.Select(x => (uint)x).ToArray();
//Array.ForEach(data3x, Console.WriteLine);
//Console.WriteLine("=========read3x=========");
_service.disConnent();
//List<Object> data = new();
//data.Add(data0x);
//data.Add(data1x);
//data.Add(data3x);
//data.Add(data4x);
return Content("read ok");
}
else
{
return Content("Modbus 从站连接失败!");
}
}
[HttpGet, HttpPost, Route("unitTestSem")]
public IActionResult Test02()
{
_service = new ModbusTcpService("192.168.1.99", 502);
if (_service.isConnected)
{
// 读取从0开始文档上地址从1开始的地址需要减1
Console.WriteLine("=========read4x=========");
// 写数据
//_service.writeData(1, 6429, 1);
//_service.writeData(1, 1173, 256);
//_service.writeData(1, 1215, 6.28F);
//_service.writeData(1, 6691, "Hello World!!");
// 读数据
//short s = _service.readData(1, 6429, "int16"); // 运行模式
//float f = _service.readData(1, 1215, "single"); // 加工数
//int i = _service.readData(1, 1173, "int32");
//string str = _service.readData(1, 6690, "string", 52);
//Console.WriteLine(s);
//Console.WriteLine(f);
//Console.WriteLine(i);
//Console.WriteLine(str);
//short s = _service.readData(1, 6429, "int16"); // 运行模式
//float f1 = _service.readData(1, 1231, "single"); // 主轴倍率
//float f2 = _service.readData(1, 1215, "single"); // 加工数
//Console.WriteLine(s);
//Console.WriteLine(f1);
//Console.WriteLine(f2);
//Console.WriteLine(str);
short s = _service.readData(1, 6430, "int16"); // 通讯状态
Console.WriteLine(s);
Console.WriteLine("=========read4x=========");
_service.disConnent();
return Content("read ok");
}
else
{
return Content("Modbus 从站连接失败!");
}
}
[HttpGet, HttpPost, Route("unitTestCnc")]
public IActionResult Test03()
{
_service = new ModbusTcpService("192.168.1.100", 502);
//_service = new ModbusTcpService("192.168.1.99", 502);
if (_service.isConnected)
{
// 读取从0开始文档上地址从1开始的地址需要减1
Console.WriteLine("=========read4x=========");
// 写数据
//_service.writeData(1, 6424, 2);
//_service.writeData(1, 1309, 65537);
//_service.writeData(1, 1307, 5.68F);
//_service.writeData(1, 6640, "hehe");
// 读数据
//short s = _service.readData(1, 6424, "int16");
//int i = _service.readData(1, 1309, "int32");
//float f = _service.readData(1, 1307, "single");
//string str = _service.readData(1, 6640, "string", 2); // 一个寄存器地址存放两个字符
//Console.WriteLine(s);
//Console.WriteLine(i);
//Console.WriteLine(f);
//Console.WriteLine(str);
//_service.writeData(1, 1307, 120F);
//_service.writeData(1, 1299, 19912F);
//_service.writeData(1, 6424, 2);
//_service.writeData(1, 6402, 25);
//Console.WriteLine(_service.readData(1, 1307, "single")); // 加工数量
//Console.WriteLine(_service.readData(1, 1299, "single")); // 切削时间
//Console.WriteLine(_service.readData(1, 6424, "int16")); // 运行模式
//Console.WriteLine(_service.readData(1, 6402, "int16")); // 快速倍率
//Console.WriteLine(_service.readData(1, 6425, "int16")); // 轴状态
Console.WriteLine(_service.readData(1, 6429, "int16"));
Console.WriteLine(_service.readData(1, 6430, "int16"));
Console.WriteLine(_service.readData(1, 6431, "int16"));
Console.WriteLine("=========read4x=========");
_service.disConnent();
return Content("read ok");
}
else
{
return Content("Modbus 从站连接失败!");
}
}
}
}

@ -0,0 +1,21 @@
/*
*,
*PartialData_ConfigController
*/
using Microsoft.AspNetCore.Mvc;
using VOL.Core.Controllers.Basic;
using VOL.Entity.AttributeManager;
using VOL.Data.IServices;
namespace VOL.Data.Controllers
{
[Route("api/Data_Config")]
[PermissionTable(Name = "Data_Config")]
public partial class Data_ConfigController : ApiBaseController<IData_ConfigService>
{
public Data_ConfigController(IData_ConfigService service)
: base(service)
{
}
}
}

@ -0,0 +1,21 @@
/*
*,
*PartialData_MachineController
*/
using Microsoft.AspNetCore.Mvc;
using VOL.Core.Controllers.Basic;
using VOL.Entity.AttributeManager;
using VOL.Data.IServices;
namespace VOL.Data.Controllers
{
[Route("api/Data_Machine")]
[PermissionTable(Name = "Data_Machine")]
public partial class Data_MachineController : ApiBaseController<IData_MachineService>
{
public Data_MachineController(IData_MachineService service)
: base(service)
{
}
}
}

@ -0,0 +1,21 @@
/*
*,
*PartialData_ProduceController
*/
using Microsoft.AspNetCore.Mvc;
using VOL.Core.Controllers.Basic;
using VOL.Entity.AttributeManager;
using VOL.Data.IServices;
namespace VOL.Data.Controllers
{
[Route("api/Data_Produce")]
[PermissionTable(Name = "Data_Produce")]
public partial class Data_ProduceController : ApiBaseController<IData_ProduceService>
{
public Data_ProduceController(IData_ProduceService service)
: base(service)
{
}
}
}

@ -0,0 +1,273 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using System;
using VOL.Core.Filters;
using VOL.Data.IServices.modbus;
using VOL.Data.Services.modbus;
using Microsoft.Extensions.DependencyInjection;
using VOL.WebApi.Utils;
using VOL.Entity.DomainModels;
using System.Collections.Generic;
using Microsoft.Extensions.Primitives;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
/// <summary>
// 尼可尼数据采集
/// <summary>
namespace VOL.WebApi.Controllers.Data
{
/// <summary>
/// 数据采集API类
/// </summary>
[Route("api/NKNCapture")]
[AllowAnonymous]
public class NKNCaptureController : Controller
{
private ModbusTcpService _service; // 静态字段
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IDataProcessing _dataService; // 业务处理
[ActivatorUtilitiesConstructor]
public NKNCaptureController(
IDataProcessing dataService,
IHttpContextAccessor httpContextAccessor
)
{
_dataService = dataService;
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// 采集西门子设备
/// </summary>
/// <returns>IActionResult</returns>
[ApiTask]
[HttpGet, HttpPost, Route("gatherSiemens")]
public IActionResult gatherSiemens()
{
var headers = _httpContextAccessor.HttpContext.Request.Headers;
headers.TryGetValue("USER-DEVICE-ID", out StringValues deviceIdStr);
if (1 == 1) {
try
{
_service = new ModbusTcpService("192.168.1.99", 502);
Console.WriteLine("siemens modbus tcp connected...");
}
catch (Exception)
{
Console.WriteLine("siemens modbus tcp connect failed");
return Content("siemens modbus tcp connect failed!");
}
if (!_service.isConnected)
{
Console.WriteLine("siemens modbus tcp disconnect!");
return Content("siemens modbus tcp disconnect!");
}
}
// 切削倍率 17136 1
//_service.readData(1, 6435, "int16"); // 运行时长 分钟
//_service.readData(1, 6436, "int16"); // 工单1产量 件
//_service.readData(1, 6437, "int16"); // 工单2产量 件
//_service.readData(1, 6438, "int16"); // 工单3产量 件
//_service.readData(1, 6439, "int16"); // 当班产量 件
//_service.readData(1, 6440, "int16"); // 运行状态 0:待机 1运行 2故障
//_service.readData(1, 1315, "single"); // 工单1任务进度 %
//_service.readData(1, 1317, "single"); // 工单2任务进度 %
//_service.readData(1, 1319, "single"); // 工单3任务进度 %
//_service.readData(1, 1321, "single"); // 工单1良品率 % 真实值 *= 100
//_service.readData(1, 1323, "single"); // 工单2良品率 % 真实值 *= 100
//_service.readData(1, 1325, "single"); // 工单3良品率 % 真实值 *= 100
//_service.readData(1, 1339, "single"); // 设备综合效率 % 真实值 *= 100
//dynamic d1 = _service.readData(1, 1201, "single"); // 电机温度 ℃
//dynamic d2 = _service.readData(1, 1203, "single"); // 母线电压 V
//dynamic d3 = _service.readData(1, 1205, "single"); // 实际电流 A
//dynamic d4 = _service.readData(1, 1215, "single"); // 累计加工次数
//dynamic d5 = _service.readData(1, 1225, "single"); // 切削倍率
//dynamic d6 = _service.readData(1, 1231, "single"); // 主轴倍率
//dynamic d7 = _service.readData(1, 6689, "string", 50); // 运行程序编号 length = 8
//dynamic d8 = _service.readData(1, 6435, "int16"); // 累计运行时长 分钟
string message = "";
bool success = int.TryParse(deviceIdStr, out int deviceId);
try
{
if (success)
{
Dictionary<string, Dictionary<string, object>> dataMap = new();
if (1 == 1)
{
dataMap = _dataService.readSiemensData(_service);
}
else {
dataMap.Add("produce", new Dictionary<string, object>());
dataMap.Add("machine", new Dictionary<string, object>());
}
message = saveSourceData(dataMap, deviceId);
}
else
{
message = "设备非法或已下线";
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
message = "read data error: " + ex.Message;
}
finally
{
if (_service != null)
{
_service.disConnent();
}
}
return Content(message);
}
/// <summary>
/// 采集广数设备
/// </summary>
/// <returns>IActionResult</returns>
[ApiTask]
[HttpGet, HttpPost, Route("gatherGSK")]
public IActionResult gatherGSK()
{
var headers = _httpContextAccessor.HttpContext.Request.Headers;
headers.TryGetValue("USER-DEVICE-ID", out StringValues deviceIdStr);
if (1 == 1)
{
try
{
_service = new ModbusTcpService("192.168.1.100", 502);
Console.WriteLine("GSK modbus tcp connected...");
}
catch (Exception)
{
Console.WriteLine("GSK modbus tcp connect failed");
return Content("GSK modbus tcp connect failed!");
}
if (!_service.isConnected)
{
Console.WriteLine("GSK modbus tcp disconnect!");
return Content("GSK modbus tcp disconnect!");
}
}
//_service.readData(1, 6429, "int16"); // 程序编号
//_service.readData(1, 6435, "int16"); // 通讯状态 5通讯正常 15通讯断线
//_service.readData(1, 6430, "int16");
//_service.readData(1, 6435, "int16"); // 运行时长 分钟
//_service.readData(1, 6436, "int16"); // 工单1产量 件
//_service.readData(1, 6437, "int16"); // 工单2产量 件
//_service.readData(1, 6438, "int16"); // 工单3产量 件
//_service.readData(1, 6439, "int16"); // 当班产量 件
//_service.readData(1, 6440, "int16"); // 运行状态 0:待机 1运行 2故障
//_service.readData(1, 1315, "single"); // 工单1任务进度 %
//_service.readData(1, 1317, "single"); // 工单2任务进度 %
//_service.readData(1, 1319, "single"); // 工单3任务进度 %
//_service.readData(1, 1321, "single"); // 工单1良品率 % 真实值 *= 100
//_service.readData(1, 1323, "single"); // 工单2良品率 % 真实值 *= 100
//_service.readData(1, 1325, "single"); // 工单3良品率 % 真实值 *= 100
//_service.readData(1, 1331, "single"); // 设备综合效率 % 真实值 *= 100
//_service.readData(1, 6430, "int16"); // 通讯状态 5通讯正常 15通讯断线
//_service.readData(1, 6099, "int16"); // 工作方式 0:编辑 1:自动 2:MDI 3:DNC 4:手动 5:手轮 6:回参考点
//_service.readData(1, 6100, "int16"); // 运行状态 0:复位 1:停止 2:运行 3:暂停
//dynamic d1 = _service.readData(1, 4117, "int32"); // 当天加工数量 次
//dynamic d2 = _service.readData(1, 1201, "int32"); // 开机时间 秒
//dynamic d3 = _service.readData(1, 1203, "int32"); // 运行时间 秒
//dynamic d4 = _service.readData(1, 1241, "single"); // 进给倍率
//dynamic d5 = _service.readData(1, 1247, "single"); // 主轴倍率
//dynamic d6 = _service.readData(1, 6299, "string", 8); // 运行程序编号 length = 8
//dynamic d7 = _service.readData(1, 4115, "int32"); // 累计运行时长 分钟
//dynamic d8 = _service.readData(1, 1199, "int32"); // 累计加工数 次
string message = "";
bool success = int.TryParse(deviceIdStr, out int deviceId);
try
{
if (success)
{
Dictionary<string, Dictionary<string, object>> dataMap = new();
if (1 == 1)
{
dataMap = _dataService.readGSKData(_service);
}
else
{
dataMap.Add("produce", new Dictionary<string, object>());
dataMap.Add("machine", new Dictionary<string, object>());
}
message = saveSourceData(dataMap, deviceId);
}
else
{
message = "设备非法或已下线";
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
message = "read data error: " + ex.Message;
}
finally
{
if (_service != null)
{
_service.disConnent();
}
}
return Content(message);
}
[HttpGet, HttpPost, Route("testSave")]
public IActionResult testSave()
{
Dictionary<string, Dictionary<string, object>> dataMap = new();
dataMap.Add("machine", new Dictionary<string, object>() { { "config_id", 666 } });
dataMap.Add("produce", new Dictionary<string, object>() { { "config_id", 666 } });
string message = saveSourceData(dataMap, 1);
return Content(message);
}
/// <summary>
/// 保存采集数据
/// </summary>
/// <returns>IActionResult</returns>
private string saveSourceData(Dictionary<string, Dictionary<string, object>> dataMap, int deviceId)
{
// 获取当前系统时间, 保证插入时间一致
DateTime now = DateTime.Now;
// 设备关联的用户信息
Data_Config dataConfig = _dataService.GetDataConfig(deviceId);
if (dataConfig == null) {
return "设备不存在!";
}
int userId = dataConfig.CreateID ?? 1; // 默认超管
Dictionary<string, object> machineData = dataMap["machine"];
Data_Machine data_Machine = CommonUtil.ConvertToObject<Data_Machine>(machineData);
data_Machine.config_id = deviceId;
data_Machine.CreateDate = now;
data_Machine.CreateID = userId;
bool result1 = _dataService.saveMachineData(data_Machine, out string message1);
Dictionary<string, object> produceData = dataMap["produce"];
Data_Produce data_Produce = CommonUtil.ConvertToObject<Data_Produce>(produceData);
data_Produce.config_id = deviceId;
data_Produce.CreateDate = now;
data_Produce.CreateID = userId;
bool result2 = _dataService.saveProduceData(data_Produce, out string message2);
return (result1 && result2) ? "OK" : "save machine: " + message1 + "; save produce: " + message2 + ";";
}
}
}

@ -0,0 +1,33 @@
/*
*...
*ActionAction使
*: [ApiActionPermission("Data_Config",Enums.ActionPermissionOptions.Search)]
*/
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.Entity.DomainModels;
using VOL.Data.IServices;
namespace VOL.Data.Controllers
{
public partial class Data_ConfigController
{
private readonly IData_ConfigService _service;//访问业务代码
private readonly IHttpContextAccessor _httpContextAccessor;
[ActivatorUtilitiesConstructor]
public Data_ConfigController(
IData_ConfigService service,
IHttpContextAccessor httpContextAccessor
)
: base(service)
{
_service = service;
_httpContextAccessor = httpContextAccessor;
}
}
}

@ -0,0 +1,33 @@
/*
*...
*ActionAction使
*: [ApiActionPermission("Data_Machine",Enums.ActionPermissionOptions.Search)]
*/
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.Entity.DomainModels;
using VOL.Data.IServices;
namespace VOL.Data.Controllers
{
public partial class Data_MachineController
{
private readonly IData_MachineService _service;//访问业务代码
private readonly IHttpContextAccessor _httpContextAccessor;
[ActivatorUtilitiesConstructor]
public Data_MachineController(
IData_MachineService service,
IHttpContextAccessor httpContextAccessor
)
: base(service)
{
_service = service;
_httpContextAccessor = httpContextAccessor;
}
}
}

@ -0,0 +1,33 @@
/*
*...
*ActionAction使
*: [ApiActionPermission("Data_Produce",Enums.ActionPermissionOptions.Search)]
*/
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.Entity.DomainModels;
using VOL.Data.IServices;
namespace VOL.Data.Controllers
{
public partial class Data_ProduceController
{
private readonly IData_ProduceService _service;//访问业务代码
private readonly IHttpContextAccessor _httpContextAccessor;
[ActivatorUtilitiesConstructor]
public Data_ProduceController(
IData_ProduceService service,
IHttpContextAccessor httpContextAccessor
)
: base(service)
{
_service = service;
_httpContextAccessor = httpContextAccessor;
}
}
}

@ -44,7 +44,7 @@ namespace VOL.Order.Controllers
[HttpPost]
[ApiActionPermission("SellOrder", Core.Enums.ActionPermissionOptions.Search)]
[Route("getServiceDate"), FixedToken]//FixedToken请求此接口只要token合法就能能过//AllowAnonymous
[Route("getServiceDate"), FixedToken]//FixedToken 接口token永不过期 //AllowAnonymous 无需验证即可访问
public IActionResult GetServiceDate()
{
return Content(Service.GetServiceDate());

@ -125,6 +125,20 @@ namespace VOL.System.Controllers
}).ToListAsync();
return JsonNormal(new { rows });
}
/// <summary>
/// 获取用户根部门
/// </summary>
/// <returns></returns>
[HttpGet, Route("getUserDepartment")]
[ApiActionPermission()]
public async Task<ActionResult> GetUserDepartment()
{
int useId = UserContext.Current.UserId;
var sysDepartment = await _service.GetUserDepartment(useId);
return JsonNormal(new { sysDepartment.DepartmentName, sysDepartment.DepartmentId });
}
}
}

@ -13,6 +13,7 @@ using VOL.Entity.DomainModels;
using VOL.System.IServices;
using VOL.Core.Filters;
using VOL.Core.Enums;
using Microsoft.Extensions.Primitives;
namespace VOL.System.Controllers
{
@ -40,6 +41,8 @@ namespace VOL.System.Controllers
[HttpGet, HttpPost, Route("test")]
public IActionResult Test()
{
//var headers = _httpContextAccessor.HttpContext.Request.Headers;
//headers.TryGetValue("USER-DEVICE-ID", out StringValues val); //AuthKey
return Content(DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"));
}

@ -17,6 +17,7 @@ namespace VOL.System.Controllers
public Sys_LogController(ISys_LogService service)
: base("System", "System", "Sys_Log", service)
{
// 没有多个构造函数时,执行默认构造
}
}
}

@ -22,7 +22,7 @@ namespace VOL.WebApi
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
//CreateHostBuilder(args).Build().Run();
var host = CreateHostBuilder(args).Build();
#region kafka订阅消息
#region kafka订阅消息111
//if (AppSetting.Kafka.UseConsumer)
//{
// using var scope = host.Services.CreateScope();
@ -30,16 +30,24 @@ namespace VOL.WebApi
// testConsumer.Consume(res =>
// {
// Console.WriteLine($"recieve:{DateTime.Now.ToLongTimeString()} value:{res.Message.Value}");
// //静态方法 数据处理 入库等操作
// //静态方法 数据处理 入库等操作
// bool bl = DataHandle.AlarmData(res.Message.Value);
// //回调函数需返回便于执行Commit
// //回调函数需返回便于执行Commit
// return bl;
// }, AppSetting.Kafka.Topics.TestTopic);
//}
#endregion
// 打印测试
if (1 == 1) {
DateTime dateTime = DateTime.Now;
String dateOnly = dateTime.ToString("yyyy-MM-dd");
Console.WriteLine(dateTime); // 输出完整的日期和时间
Console.WriteLine(dateOnly); // 输出日期部分(不包含时间)
}
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
@ -53,5 +61,26 @@ namespace VOL.WebApi
webBuilder.UseIIS();
webBuilder.UseStartup<Startup>();
}).UseServiceProviderFactory(new AutofacServiceProviderFactory());
//public static async Task Main(string[] args)
//{
// // 创建一个定时器每隔1秒触发一次
// var timer = new Timer(async state =>
// {
// // 在这里编写您的异步任务逻辑
// await Task.Delay(1000);
// Console.WriteLine("异步定时任务执行");
// }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
// TimeSpan.Zero 表示定时器立即开始执行TimeSpan.FromSeconds(1) 表示每隔1秒触发一次定时任务。
// // 等待一段时间,观察异步定时任务的执行
// await Task.Delay(5000);
// // 停止定时器
// timer.Dispose();
// Console.WriteLine("定时器已停止");
//}
}
}

@ -0,0 +1,41 @@
using System.Collections.Generic;
namespace VOL.WebApi.Utils
{
public class CommonUtil
{
// 实体对象转Dictionary
public static Dictionary<string, object> ConvertToDictionary<T>(T entity)
{
var dictionary = new Dictionary<string, object>();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
var key = property.Name;
var value = property.GetValue(entity);
dictionary.Add(key, value);
}
return dictionary;
}
// Dictionary转实体对象
public static T ConvertToObject<T>(Dictionary<string, object> dictionary) where T : new()
{
var obj = new T();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
if (dictionary.TryGetValue(property.Name, out var value))
{
property.SetValue(obj, value);
}
}
return obj;
}
}
}

@ -0,0 +1,307 @@
using System.Text;
using System;
namespace VOL.WebApi.Utils
{
public class DataConvertUtil
{
/// <summary>
/// 赋值string string => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void SetString(ushort[] src, int start, string value)
{
byte[] bytesTemp = Encoding.UTF8.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytesTemp);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取string ushort[] => string
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="len"></param>
/// <returns>string</returns>
public static string GetString(ushort[] src, int start, int len)
{
ushort[] temp = new ushort[len];
for (int i = 0; i < len; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp);
//string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' }); // 去除字符串左右端的指定内容
string res = Encoding.UTF8.GetString(bytesTemp).Trim();
return res;
}
/// <summary>
/// 赋值Real float => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetReal(ushort[] src, int start, float value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取float ushort[] => float
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>float</returns>
public static float GetReal(ushort[] src, int start)
{
try
{
ushort[] temp = new ushort[2];
for (int i = 0; i < 2; i++)
{
temp[i] = src[i + start];
}
Array.Reverse(temp);
// BitConverter默认是小端转换如果是大端字节顺序数组接收需要先反序字节顺序
byte[] bytesTemp = Ushorts2Bytes(temp,false);
float f = BitConverter.ToSingle(bytesTemp, 0);
return float.Parse(f.ToString("F2")); // 保留两位小数
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 赋值Short short => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetShort(ushort[] src, int start, short value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short ushort[] => short
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static short GetShort(ushort[] src, int start)
{
try
{
ushort[] temp = new ushort[1];
temp[0] = src[start];
byte[] bytesTemp = Ushorts2Bytes(temp);
short res = BitConverter.ToInt16(bytesTemp, 0);
return res;
}
catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 赋值Short short => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetInt(ushort[] src, int start, int value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short ushort[] => int
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static int GetInt(ushort[] src, int start)
{
try {
ushort[] temp = new ushort[2];
temp[0] = src[start];
temp[1] = src[start + 1]; // 0 100
Array.Reverse(temp); // 100 0 地址低位存储低字节数据(小端)
byte[] bytesTemp = Ushorts2Bytes(temp,false);
int res = BitConverter.ToInt32(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 获取short ushort[] => long
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static long GetLong(ushort[] src, int start)
{
try {
ushort[] temp = new ushort[4];
temp[0] = src[start];
temp[1] = src[start + 1];
temp[2] = src[start + 2];
temp[3] = src[start + 3]; // 0 0 0 100
Array.Reverse(temp); // 100 0 0 0
byte[] bytesTemp = Ushorts2Bytes(temp);
long res = BitConverter.ToInt64(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 获取bool数组 ushort[] => bool[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static bool[] GetBools(ushort[] src, int start, int num)
{
ushort[] temp = new ushort[num];
for (int i = start; i < start + num; i++)
{
temp[i] = src[i + start];
} // 0 1 0 1 0 0 0 0 默认小端模式
//Array.Reverse(temp); // 0 0 0 0 1 0 1 0
byte[] bytes = Ushorts2Bytes(temp);
bool[] res = Bytes2Bools(bytes);
return res;
}
// byte[] => bool[]
private static bool[] Bytes2Bools(byte[] b)
{
bool[] array = new bool[8 * b.Length];
for (int i = 0; i < b.Length; i++)
{
for (int j = 0; j < 8; j++)
{
array[i * 8 + j] = (b[i] & 1) == 1;//判定byte的最后一位是否为1若为1则是true否则是false
b[i] = (byte)(b[i] >> 1);//将byte右移一位
}
}
return array;
}
// bool[] => byte
private static byte Bools2Byte(bool[] array)
{
if (array != null && array.Length > 0)
{
byte b = 0;
for (int i = 0; i < 8; i++)
{
if (array[i])
{
byte nn = (byte)(1 << i);//左移一位相当于×2
b += nn;
}
}
return b;
}
return 0;
}
// byte[] => ushort[]
private static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false)
{
int len = src.Length;
byte[] srcPlus = new byte[len + 1];
src.CopyTo(srcPlus, 0);
int count = len >> 1;
if (len % 2 != 0)
{
count += 1;
}
ushort[] dest = new ushort[count];
if (reverse)
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff);
}
}
else
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8);
}
}
return dest;
}
// ushort[] => byte[]
private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false)
{
int count = src.Length;
byte[] dest = new byte[count << 1];
if (reverse)
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 8);
dest[i * 2 + 1] = (byte)(src[i] >> 0);
}
}
else
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 0);
dest[i * 2 + 1] = (byte)(src[i] >> 8);
}
}
return dest;
}
}
}

@ -31,6 +31,7 @@
<ProjectReference Include="..\VOL.AppManager\VOL.AppManager.csproj" />
<ProjectReference Include="..\VOL.Builder\VOL.Builder.csproj" />
<ProjectReference Include="..\VOL.Core\VOL.Core.csproj" />
<ProjectReference Include="..\VOL.Data\VOL.Data.csproj" />
<ProjectReference Include="..\VOL.Entity\VOL.Entity.csproj" />
<ProjectReference Include="..\VOL.Order\VOL.Order.csproj" />
<ProjectReference Include="..\VOL.System\VOL.System.csproj" />

@ -6,8 +6,8 @@
<PropertyGroup>
<ActiveDebugProfile>VOL.WebApi</ActiveDebugProfile>
<NameOfLastUsedPublishProfile>E:\jxx\Vue.NetCore\.Net6版本\VOL.WebApi\Properties\PublishProfiles\FolderProfile1.pubxml</NameOfLastUsedPublishProfile>
<Controller_SelectedScaffolderID>MvcControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Common/MVC/Controller</Controller_SelectedScaffolderCategoryPath>
<Controller_SelectedScaffolderID>ApiControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Common/Api</Controller_SelectedScaffolderCategoryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>

@ -0,0 +1 @@
作业启动:西门子设备采集(5s一次)

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VOL.Order", "VOL.Order\VOL.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VOL.WebApi", "VOL.WebApi\VOL.WebApi.csproj", "{4DB3C91B-93FE-4937-8B58-DDD3F57D4607}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VOL.Data", "VOL.Data\VOL.Data.csproj", "{FA76EAA8-C355-4E13-B15C-FF925919F861}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -51,6 +53,10 @@ Global
{4DB3C91B-93FE-4937-8B58-DDD3F57D4607}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4DB3C91B-93FE-4937-8B58-DDD3F57D4607}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4DB3C91B-93FE-4937-8B58-DDD3F57D4607}.Release|Any CPU.Build.0 = Release|Any CPU
{FA76EAA8-C355-4E13-B15C-FF925919F861}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA76EAA8-C355-4E13-B15C-FF925919F861}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA76EAA8-C355-4E13-B15C-FF925919F861}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA76EAA8-C355-4E13-B15C-FF925919F861}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -8,6 +8,7 @@
"name": "vol.vue3",
"version": "0.1.0",
"dependencies": {
"@dataview/datav-vue3": "^0.0.0-test.1672506674342",
"@element-plus/icons-vue": "^2.1.0",
"@microsoft/signalr": "^6.0.4",
"ali-oss": "^6.17.1",
@ -1680,6 +1681,27 @@
"node": ">=10"
}
},
"node_modules/@dataview/datav-vue3": {
"version": "0.0.0-test.1672506674342",
"resolved": "https://registry.npmmirror.com/@dataview/datav-vue3/-/datav-vue3-0.0.0-test.1672506674342.tgz",
"integrity": "sha512-d0oT/msAi592CTvWmQl0umkLpHgMwtTN2+peyo0L2GHNG7b4cKeO9meEF5o28DgFzRwOLeNQW73vKCF4JC+ihw==",
"dependencies": {
"@jiaminghi/color": "^0.1.1",
"classnames": "^2.3.2",
"lodash-es": "^4.17.21"
},
"peerDependencies": {
"vue": ">=3.2.0"
}
},
"node_modules/@dataview/datav-vue3/node_modules/@jiaminghi/color": {
"version": "0.1.1",
"resolved": "https://registry.npmmirror.com/@jiaminghi/color/-/color-0.1.1.tgz",
"integrity": "sha512-M09+Sb5HGqVim0zo+nG5gU1v+6gXT8ptr0BZR6dMGt83XmCJgnZtO8s7llTW4hLFFFM5co6geZvTekqLpSPAAQ==",
"dependencies": {
"@babel/runtime": "^7.5.5"
}
},
"node_modules/@element-plus/icons-vue": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz",
@ -4654,6 +4676,11 @@
"node": ">=0.10.0"
}
},
"node_modules/classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"node_modules/clean-css": {
"version": "4.2.3",
"resolved": "https://registry.nlark.com/clean-css/download/clean-css-4.2.3.tgz?cache=0&sync_timestamp=1624616709466&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fclean-css%2Fdownload%2Fclean-css-4.2.3.tgz",
@ -18556,6 +18583,26 @@
"resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz",
"integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw=="
},
"@dataview/datav-vue3": {
"version": "0.0.0-test.1672506674342",
"resolved": "https://registry.npmmirror.com/@dataview/datav-vue3/-/datav-vue3-0.0.0-test.1672506674342.tgz",
"integrity": "sha512-d0oT/msAi592CTvWmQl0umkLpHgMwtTN2+peyo0L2GHNG7b4cKeO9meEF5o28DgFzRwOLeNQW73vKCF4JC+ihw==",
"requires": {
"@jiaminghi/color": "^0.1.1",
"classnames": "^2.3.2",
"lodash-es": "^4.17.21"
},
"dependencies": {
"@jiaminghi/color": {
"version": "0.1.1",
"resolved": "https://registry.npmmirror.com/@jiaminghi/color/-/color-0.1.1.tgz",
"integrity": "sha512-M09+Sb5HGqVim0zo+nG5gU1v+6gXT8ptr0BZR6dMGt83XmCJgnZtO8s7llTW4hLFFFM5co6geZvTekqLpSPAAQ==",
"requires": {
"@babel/runtime": "^7.5.5"
}
}
}
},
"@element-plus/icons-vue": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz",
@ -21099,6 +21146,11 @@
}
}
},
"classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"clean-css": {
"version": "4.2.3",
"resolved": "https://registry.nlark.com/clean-css/download/clean-css-4.2.3.tgz?cache=0&sync_timestamp=1624616709466&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fclean-css%2Fdownload%2Fclean-css-4.2.3.tgz",

@ -1,5 +1,5 @@
{
"name": "vol.vue3",
"name": "yxsc",
"version": "0.1.0",
"private": true,
"scripts": {
@ -10,11 +10,12 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"@jiaminghi/data-view": "^2.10.0",
"@microsoft/signalr": "^6.0.4",
"ali-oss": "^6.17.1",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"echarts": "^5.0.2",
"echarts": "^5.3.0",
"element-plus": "^2.2.14",
"less": "^4.1.1",
"vue": "^3.2.37",

@ -5,8 +5,8 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="keywords" content=".netccore,dotnet core,vue,element,element plus,vue3" />
<meta name="description" content=".NetCore+Vue前后端分离提供Vue2、Vue3版本不一样的快速开发框架" />
<meta name="keywords" content=".netccore,dotnet core,vue,element,element plus,vue3,yxsz.cc" />
<meta name="description" content="云息数采,为工厂数字化赋能" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>

@ -12,7 +12,7 @@ import { ElLoading as Loading, ElMessage as Message } from 'element-plus';
let loadingInstance;
let loadingStatus = false;
if (process.env.NODE_ENV == 'development') {
axios.defaults.baseURL = 'http://127.0.0.1:9991/';
axios.defaults.baseURL = 'http://192.168.0.187:9991/';
}
else if (process.env.NODE_ENV == 'debug') {
axios.defaults.baseURL = 'http://127.0.0.1:9991/';
@ -205,6 +205,7 @@ function createXHR () {
}
function redirect (responseText, message) {
console.log(typeof responseText);
try {
let responseData = typeof responseText == 'string' ? JSON.parse(responseText) : responseText;
if ((responseData.hasOwnProperty('code') && responseData.code == 401)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@ -1511,7 +1511,6 @@ export default defineComponent({
if (!column.bind || !column.bind.data) {
return row[column.field];
}
if (column.edit && (column.edit.type == 'selectList'||column.edit.type=='treeSelect')) {
if (!Array.isArray(val)) {
row[column.field] = val.split(',');

@ -0,0 +1,196 @@
<template>
<div class="bar" ref="vbar"></div>
</template>
<script>
import * as echarts from 'echarts';
import { markRaw } from 'vue'
export default {
name: "Bar",
props: {
option: {
type: Object,
required: false,
default: () => {
return null;
}
}
},
data() {
return {
// chartBar: null,
chartBar: {
chart: null
},
defaultOption: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
toolbox: {
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
// saveAsImage: { show: true, name: "" }
}
},
legend: {
top: 0,
data: ['广数980DI-1', '西门子828D-1'],
itemGap: 20, //
textStyle: {
fontSize: 14,
color: '#fff'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '2%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { //
lineStyle: {
color: '#fff',
}
},
axisTick: { // 线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '广数980DI-1',
alignTicks: true,
min: 0,
axisLabel: {
formatter: '{value} 件'
},
axisLine: { //
show: false, // 线
lineStyle: {
color: '#fff',
},
onZero: true
},
splitLine: { // 线
show: true,
lineStyle: {
// 使
color: ['#fff', '#ff9f7f'],
width: 1
}
}
},
{
type: 'value',
name: '西门子828D-1',
min: 0,
// interval: 50,
alignTicks: true,
axisLabel: {
formatter: '{value} 件'
},
axisLine: { //
lineStyle: {
color: '#fff',
}
},
}
],
series: [
{
name: '广数980DI-1',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' 件';
}
},
data: [
100, 99, 91, 107, 121, 137, 101
]
},
{
name: '西门子828D-1',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' 件';
}
},
data: [
120, 117, 99, 100, 111, 127, 101
]
}
]
}
}
},
created() {
console.log("bar loaded...");
this.defaultOption = this.option || this.defaultOption;
},
mounted() {
this.initBar(this.defaultOption);
},
methods: {
initBar(option) {
console.log(option);
// reactive Proxytooltip
// this.chartBar = echarts.init(this.$refs.vbar);
// Proxy
if (!this.chartBar.chart) {
let chart = markRaw(echarts.init(this.$refs.vbar));
chart.setOption(option, true);
this.chartBar.chart = chart;
} else {
this.$nextTick(() => {
this.chartBar.chart.setOption(option, true);
});
}
// echarts
// if(this.chartBar.chart){
// this.chartBar.chart.dispose();
// }
// this.$nextTick(() => {
// let chart = echarts.init(this.$refs.vbar);
// chart.setOption(option, true);
// this.chartBar.chart = chart;
// });
}
},
destroyed() {
this.chartBar.chart = null;
},
};
</script>
<style lang="less" scoped>
.bar {
width: 100%;
height: 100%;
// padding: 20px;
}
</style>

@ -0,0 +1,159 @@
<template>
<div class="gauge" ref="vgauge"></div>
</template>
<script>
var echarts = require("echarts");
export default {
name: "Gauge",
props: {
option: {
type: Object,
required: false,
default: () => {
return null;
}
}
},
data() {
return {
chartGauge: null,
defaultOption: {
series: [{
radius: '130%',
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 1,
splitNumber: 10,
center: ["50%", "80%"], //
axisLine: {
lineStyle: {
width: 3,
color: [
[0.2, '#FF6E76'],
[0.4, '#FF9F7F'],
[0.6, '#FDDD60'],
[0.8, '#58D9F9'],
[1.0, '#7CFFB2']
]
}
},
pointer: {
icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
length: '12%',
width: 20,
offsetCenter: [0, '-60%'],
itemStyle: {
color: 'auto'
}
},
axisTick: {
length: 12,
lineStyle: {
color: 'auto',
width: 2
}
},
splitLine: {
length: 20,
lineStyle: {
color: 'auto',
width: 5
}
},
axisLabel: {
color: '#fff',
fontSize: 20,
// distance: -60,
rotate: 'tangential',
formatter: function (value) {
switch(value) {
case 0.20:
return "差";
case 0.50:
return "中";
case 0.80:
return "良";
default:
return '';
}
}
},
title: {
offsetCenter: [0, '-20%'],
fontSize: 20,
color: '#fff'
},
detail: {
fontSize: 30,
offsetCenter: [0, '0%'],
valueAnimation: true,
formatter: function (value) {
return Math.round(value * 100) + '%';
},
color: 'auto'
},
data: [
{
name: '西门子828D-1',
value: 0.99,
}
]
}]
}
}
},
created() {
console.log("gauge loaded...");
this.defaultOption = (this.option || this.defaultOption);
},
mounted() {
this.initGauge(this.defaultOption);
},
methods: {
initGauge(option) {
if (!this.chartGauge) {
this.chartGauge = echarts.init(this.$refs.vgauge);
}
this.$nextTick(() => {
// this.chartGauge.clear(); // ,使
this.chartGauge.setOption(option, true);
});
}
},
// watch:{
// 'option.series.0.data': {
// handler: function(newVal, oldVal) {
// console.log(newVal, oldVal);
// this.defaultOption.series[0].data = newVal;
// // console.log(this.defaultOption);
// this.initGauge(this.defaultOption);
// },
// deep: true
// },
// option: { //
// handler: function(newVal, oldVal) {
// console.log(newVal, oldVal);
// },
// deep: true
// }
// },
destroyed() {
this.chartGauge = null;
}
};
</script>
<style lang="less" scoped>
.gauge {
width: 100%;
height: 100%;
// padding: 20px;
}
</style>

@ -0,0 +1,181 @@
<template>
<div class="line" ref="vline"></div>
</template>
<script>
var echarts = require("echarts");
import { markRaw } from 'vue'
export default {
name: "Line",
props: {
option: {
type: Object,
required: false,
default: () => {
return null;
}
}
},
data() {
return {
chartLine: {
chart: null
},
defaultOption: {
title: {
text: '产量折线图',
textStyle: {
fontSize: 20,
color: "#fff"
},
left: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['工单1', '工单2', '工单3'],
itemGap: 20, //
textStyle: {
fontSize: 14,
color: '#fff'
}
},
toolbox: {
feature: {
// , my
mySwitch: {
show: true,
title: '更多',
icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
onclick: function () {
alert('暂未实现!')
}
},
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] }
}
},
grid: {
left: '3%',
right: '4%',
bottom: '2%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false, //
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { //
lineStyle: {
color: '#fff',
}
},
axisTick: { // 线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '产量',
position: 'left',
alignTicks: true,
axisLine: {
show: true,
lineStyle: {
color: '#fff',
},
},
axisLabel: {
formatter: '{value} 次'
}
}
],
series: [
{
name: '工单1',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '工单2',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '工单3',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [150, 232, 201, 154, 190, 330, 410]
},
]
}
}
},
created() {
console.log("line loaded...");
this.defaultOption = this.option || this.defaultOption;
},
mounted() {
this.initLine(this.defaultOption);
},
methods: {
initLine(option) {
// console.log(option);
if (!this.chartLine.chart) {
let chart = markRaw(echarts.init(this.$refs.vline));
chart.setOption(option, true);
this.chartLine.chart = chart;
} else {
this.$nextTick(() => {
this.chartLine.chart.setOption(option, true);
});
}
}
},
destroyed() {
this.chartLine.chart = null;
// console.log("========line destroyed========");
},
};
</script>
<style lang="less" scoped>
.line {
width: 100%;
height: 100%;
// padding: 20px;
}
</style>

@ -0,0 +1,80 @@
<template>
<div class="number">
<dv-digital-flop :config="config" />
</div>
</template>
<script>
var echarts = require("echarts");
let $chartBar;
export default {
name: "Number",
props: {
number: {
type: Number,
required: false,
default: 10000
},
unity: {
type: String,
required: false,
default: ''
},
toFixed: {
type: Number,
required: false,
default: 0
},
toFormat: {
type: Boolean,
required: false,
default: true
}
},
data() {
return {
config: {
number: [this.number],
content: '{nt} ',
toFixed: this.toFixed
}
}
},
created() {
this.config.content += this.unity;
if (this.toFormat) {
this.config.formatter = this.formatter;
}
},
methods: {
//
formatter(number) {
const numbers = number.toString().split('').reverse();
const segs = [];
while (numbers.length) segs.push(numbers.splice(0, 3).join(''));
return segs.join(',').split('').reverse().join('');
}
},
watch: {
number: {
handler(newVal, oldVal) {
this.config.number = [newVal];
this.config = {...this.config}; // dataV
},
deep: true
}
}
};
</script>
<style lang="less" scoped>
.number {
width: 100%;
height: 100%;
// padding: 20px;
}
</style>

@ -0,0 +1,75 @@
/*****************************************************************************************
** Author:jxx 2022
** QQ:283591387
**http://v2.volcore.xyz/document/api 【代码生成页面ViewGrid】
**http://v2.volcore.xyz/document/vueDev
**http://v2.volcore.xyz/document/netCoreDev
*****************************************************************************************/
//此js文件是用来自定义扩展业务代码可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
components: {
//查询界面扩展组件
gridHeader: '',
gridBody: '',
gridFooter: '',
//新建、编辑弹出框扩展组件
modelHeader: '',
modelBody: '',
modelFooter: ''
},
tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
buttons: { view: [], box: [], detail: [] }, //扩展的按钮
methods: {
//下面这些方法可以保留也可以删除
onInit() { //框架初始化配置前,
//示例:在按钮的最前面添加一个按钮
// this.buttons.unshift({ //也可以用push或者splice方法来修改buttons数组
// name: '按钮', //按钮名称
// icon: 'el-icon-document', //按钮图标vue2版本见iview文档iconvue3版本见element ui文档icon(注意不是element puls文档)
// type: 'primary', //按钮样式vue2版本见iview文档buttonvue3版本见element ui文档button
// onClick: function () {
// this.$Message.success('点击了按钮');
// }
// });
//示例:设置修改新建、编辑弹出框字段标签的长度
// this.boxOptions.labelWidth = 150;
},
onInited() {
//框架初始化配置后
//如果要配置明细表,在此方法操作
//this.detailOptions.columns.forEach(column=>{ });
},
searchBefore(param) {
//界面查询前,可以给param.wheres添加查询参数
//返回false则不会执行查询
return true;
},
searchAfter(result) {
//查询后result返回的查询数据,可以在显示到表格前处理表格的值
return true;
},
addBefore(formData) {
//新建保存前formData为对象包括明细表可以给给表单设置值自己输出看formData的值
return true;
},
updateBefore(formData) {
//编辑保存前formData为对象包括明细表、删除行的Id
return true;
},
rowClick({ row, column, event }) {
//查询界面点击行事件
// this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
},
modelOpenAfter(row) {
//点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
//(1)判断是编辑还是新建操作: this.currentAction=='Add';
//(2)给弹出框设置默认值
//(3)this.editFormFields.字段='xxx';
//如果需要给下拉框设置默认值请遍历this.editFormOptions找到字段配置对应data属性的key值
//看不懂就把输出看console.log(this.editFormOptions)
}
}
};
export default extension;

@ -0,0 +1,164 @@
/*****************************************************************************************
** Author:jxx 2022
** QQ:283591387
**http://v2.volcore.xyz/document/api 【代码生成页面ViewGrid】
**http://v2.volcore.xyz/document/vueDev
**http://v2.volcore.xyz/document/netCoreDev
*****************************************************************************************/
//此js文件是用来自定义扩展业务代码可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
components: {
//查询界面扩展组件
gridHeader: '',
gridBody: '',
gridFooter: '',
//新建、编辑弹出框扩展组件
modelHeader: '',
modelBody: '',
modelFooter: ''
},
tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
buttons: { view: [], box: [], detail: [] }, //扩展的按钮
methods: {
onInit() { //框架初始化配置前,
//设置排序字段
this.pagination.sortName = "id";
this.pagination.order = "desc";
//设置页面上显示的按钮个数
this.maxBtnLength = 3;
// 格式化数据
this.dataFormatter();
},
onInited() {
//框架初始化配置后
let fixeds = ['id','com_status','config_id'];
this.columns.forEach(x=>{
//设置title列固定
if (fixeds.includes(x.field)) {
x.fixed=true//也可以设置为right,固定到最右边
}
})
//如果要配置明细表,在此方法操作
//this.detailOptions.columns.forEach(column=>{ });
},
searchBefore(param) {
//界面查询前,可以给param.wheres添加查询参数
//返回false则不会执行查询
return true;
},
searchAfter(result) {
//查询后result返回的查询数据,可以在显示到表格前处理表格的值
return true;
},
addBefore(formData) {
//新建保存前formData为对象包括明细表可以给给表单设置值自己输出看formData的值
return true;
},
updateBefore(formData) {
//编辑保存前formData为对象包括明细表、删除行的Id
return true;
},
rowClick({ row, column, event }) {
//查询界面点击行事件
this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
},
modelOpenAfter(row) {
//点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
//(1)判断是编辑还是新建操作: this.currentAction=='Add';
//(2)给弹出框设置默认值
//(3)this.editFormFields.字段='xxx';
//如果需要给下拉框设置默认值请遍历this.editFormOptions找到字段配置对应data属性的key值
//看不懂就把输出看console.log(this.editFormOptions)
},
dataFormatter() {
this.columns.forEach(column => {
if (column.field == 'temperature') {
column.formatter = (row) => {
return row.temperature && '<span style="color: #2d8cf0;">' + row.temperature + ' </span>'
}
}
if (column.field == 'potential') {
column.formatter = (row) => {
return row.potential && '<span style="color: #2d8cf0;">' + row.potential + ' V </span>'
}
}
if (column.field == 'current') {
column.formatter = (row) => {
return row.current && '<span style="color: #2d8cf0;">' + row.current + ' A </span>'
}
}
if (column.field == 'quantity') {
column.formatter = (row) => {
return row.quantity && '<span style="color: #2d8cf0;">' + row.quantity + ' </span>'
}
}
if (column.field == 'cut_rate') {
column.formatter = (row) => {
return row.cut_rate && '<span style="color: #2d8cf0;">' + row.cut_rate + ' % </span>'
}
}
if (column.field == 'main_rate') {
column.formatter = (row) => {
return row.main_rate && '<span style="color: #2d8cf0;">' + row.main_rate + ' % </span>'
}
}
if (column.field == 'feed_rate') {
column.formatter = (row) => {
return row.feed_rate && '<span style="color: #2d8cf0;">' + row.feed_rate + ' % </span>'
}
}
if (column.field == 'on_time') {
column.formatter = (row) => {
return row.on_time && '<span style="color: #2d8cf0;">' + row.on_time + ' </span>'
}
}
if (column.field == 'run_time') {
column.formatter = (row) => {
return row.run_time && '<span style="color: #2d8cf0;">' + row.run_time + ' </span>'
}
}
if (column.field == 'run_time_total') {
column.formatter = (row) => {
return row.run_time_total && '<span style="color: #2d8cf0;">' + row.run_time_total + ' </span>'
}
}
if (column.field == 'quantity_total') {
column.formatter = (row) => {
return row.quantity_total && '<span style="color: #2d8cf0;">' + row.quantity_total + ' </span>'
}
}
// 标签改色
if (column.field == 'com_status') {
column.getColor = (row, column) => {
if (row.com_status == 15) {
return 'danger';
} else if (row.com_status == 5){
return 'success';
} else {
return '';
}
}
}
if (column.field == 'state') {
column.getColor = (row, column) => {
if (row.state == 1) {
return 'danger';
} else if (row.state == 2){
return 'success';
} else if (row.state == 3){
return 'warning';
} else {
return '';
}
}
}
})
}
}
};
export default extension;

@ -0,0 +1,153 @@
/*****************************************************************************************
** Author:jxx 2022
** QQ:283591387
**http://v2.volcore.xyz/document/api 【代码生成页面ViewGrid】
**http://v2.volcore.xyz/document/vueDev
**http://v2.volcore.xyz/document/netCoreDev
*****************************************************************************************/
//此js文件是用来自定义扩展业务代码可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
components: {
//查询界面扩展组件
gridHeader: '',
gridBody: '',
gridFooter: '',
//新建、编辑弹出框扩展组件
modelHeader: '',
modelBody: '',
modelFooter: ''
},
tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
buttons: { view: [], box: [], detail: [] }, //扩展的按钮
methods: {
//下面这些方法可以保留也可以删除
onInit() { //框架初始化配置前,
//设置排序字段
this.pagination.sortName = "id";
this.pagination.order = "desc";
//设置页面上显示的按钮个数
this.maxBtnLength = 3;
// 格式化数据
this.dataFormatter();
},
onInited() {
let fixeds = ['id','com_status','config_id'];
this.columns.forEach(x=>{
//设置title列固定
if (fixeds.includes(x.field)) {
x.fixed=true//也可以设置为right,固定到最右边
}
})
},
searchBefore(param) {
//界面查询前,可以给param.wheres添加查询参数
//返回false则不会执行查询
return true;
},
searchAfter(result) {
//查询后result返回的查询数据,可以在显示到表格前处理表格的值
return true;
},
addBefore(formData) {
//新建保存前formData为对象包括明细表可以给给表单设置值自己输出看formData的值
return true;
},
updateBefore(formData) {
//编辑保存前formData为对象包括明细表、删除行的Id
return true;
},
rowClick({ row, column, event }) {
//单击行时选中当前行
this.$refs.table.$refs.table.toggleRowSelection(row);
},
modelOpenAfter(row) {
//点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
//(1)判断是编辑还是新建操作: this.currentAction=='Add';
//(2)给弹出框设置默认值
//(3)this.editFormFields.字段='xxx';
//如果需要给下拉框设置默认值请遍历this.editFormOptions找到字段配置对应data属性的key值
//看不懂就把输出看console.log(this.editFormOptions)
},
dataFormatter() {
this.columns.forEach(column => {
if (column.field == 'run_time') {
column.formatter = (row) => {
return row.run_time && '<span style="color: #2d8cf0;">' + row.run_time + ' </span>'
}
}
if (column.field == 'turnout_1') {
column.formatter = (row) => {
return row.turnout_1 && '<span style="color: #2d8cf0;">' + row.turnout_1 + ' </span>'
}
}
if (column.field == 'turnout_2') {
column.formatter = (row) => {
return row.turnout_2 && '<span style="color: #2d8cf0;">' + row.turnout_2 + ' </span>'
}
}
if (column.field == 'turnout_3') {
column.formatter = (row) => {
return row.turnout_3 && '<span style="color: #2d8cf0;">' + row.turnout_3 + ' </span>'
}
}
if (column.field == 'turnout_all') {
column.formatter = (row) => {
return row.turnout_all && '<span style="color: #2d8cf0;">' + row.turnout_all + ' </span>'
}
}
if (column.field == 'schedule_1') {
column.formatter = (row) => {
return row.schedule_1 && '<span style="color: #2d8cf0;">' + row.schedule_1 + ' % </span>'
}
}
if (column.field == 'schedule_2') {
column.formatter = (row) => {
return row.schedule_2 && '<span style="color: #2d8cf0;">' + row.schedule_2 + ' % </span>'
}
}
if (column.field == 'schedule_3') {
column.formatter = (row) => {
return row.schedule_3 && '<span style="color: #2d8cf0;">' + row.schedule_3 + ' % </span>'
}
}
if (column.field == 'yield_1') {
column.formatter = (row) => {
return row.yield_1 && '<span style="color: #2d8cf0;">' + row.yield_1 * 100 + ' % </span>'
}
}
if (column.field == 'yield_2') {
column.formatter = (row) => {
return row.yield_2 && '<span style="color: #2d8cf0;">' + row.yield_2 * 100 + ' % </span>'
}
}
if (column.field == 'yield_3') {
column.formatter = (row) => {
return row.yield_3 && '<span style="color: #2d8cf0;">' + row.yield_3 * 100 + ' % </span>'
}
}
if (column.field == 'oee') {
column.formatter = (row) => {
return row.oee && '<span style="color: #2d8cf0;">' + row.oee * 100 + ' % </span>'
}
}
// 标签改色
if (column.field == 'com_status') {
column.getColor = (row, column) => {
if (row.com_status == 15) {
return 'danger';
} else if (row.com_status == 5){
return 'success';
} else {
return '';
}
}
}
})
}
}
};
export default extension;

@ -188,6 +188,7 @@ let extension = {
//你可以指定param查询的参数处如果返回false则不会执行查询
// this.$message.success(this.table.cnName + ',查询前' });
// console.log("扩展的"this.detailOptions.cnName + '触发loadDetailTableBefore');
console.log(param);
return true;
},
searchAfter(result) { //查询ViewGird表数据后param查询参数,result回返查询的结果

@ -12,7 +12,8 @@ import http from './api/http'
// import locale from 'element-plus/lib/locale/lang/zh-cn'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
// vue3 引入dataV全局组件
import dataV from '@jiaminghi/data-view'
import permission from './api/permission'
import viewgird from './components/basic/ViewGrid';
@ -59,6 +60,7 @@ app.use(store)
.use(ElementPlus, { size: 'default' })
.use(router)
.use(viewgird)
.use(dataV)
.mount('#app');
app.config.globalProperties.$Message = app.config.globalProperties.$message;

@ -0,0 +1,62 @@
// 屏幕适配 mixin 函数
// * 默认缩放值
const scale = {
width: '1',
height: '1',
}
// * 设计稿尺寸px
const baseWidth = 1920
const baseHeight = 1080
// * 需保持的比例默认1.77778
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
export default {
data() {
return {
// * 定时函数
drawTiming: null
}
},
mounted () {
this.calcRate()
window.addEventListener('resize', this.resize)
},
beforeDestroy () {
window.removeEventListener('resize', this.resize)
},
methods: {
calcRate () {
const appRef = this.$refs["appRef"] // 需要在指定节点上添加 ref="appRef"
console.log(this);
console.log(appRef);
if (!appRef) return
// 当前宽高比
const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))
if (appRef) {
if (currentRate > baseProportion) {
// 表示更宽
scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
scale.height = (window.innerHeight / baseHeight).toFixed(5)
appRef.style.transform = `scale(${scale.width}, ${scale.height})`
// appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
} else {
// 表示更高
scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5)
scale.width = (window.innerWidth / baseWidth).toFixed(5)
appRef.style.transform = `scale(${scale.width}, ${scale.height})`
}
}
},
resize () {
clearTimeout(this.drawTiming)
this.drawTiming = setTimeout(() => {
this.calcRate()
console.log(scale)
}, 200)
},
},
}

@ -84,20 +84,38 @@ const routes = [
anonymous:true
}
},
// {
// path: '/app/guide',
// name: 'apphome',
// meta: {
// anonymous: true
// },
// component: () => import('@/views/h5/Guide.vue'),
// },
// {
// path: '/bigdata',
// name: 'bigdata',
// component: () => import('@/views/charts/bigdata.vue'),
// meta: {
// keepAlive: false
// }
// },
{
path: '/app/guide',
name: 'apphome',
path: '/dataview',
name: 'dataview',
component: () => import('@/views/data/bigscreen/index.vue'),
meta: {
anonymous: true
},
component: () => import('@/views/h5/Guide.vue'),
keepAlive: false,
anonymous: true // 路由无需登录访问
}
},
{
path: '/bigdata',
name: 'bigdata',
component: () => import('@/views/charts/bigdata.vue'),
path: '/datatest',
name: 'datatest',
component: () => import('@/views/data/bigscreen/test.vue'),
meta: {
keepAlive: false
keepAlive: false,
anonymous: true // 路由无需登录访问
}
}
]

@ -25,29 +25,33 @@ let viewgird = [
path: '/Sys_Role',
name: 'Sys_Role',
component: () => import('@/views/system/Sys_Role.vue')
}, {
},
{
path: '/Sys_Role1',
name: 'Sys_Role1',
component: () => import('@/views/system/Sys_Role1.vue')
}
, {
},
{
path: '/Sys_DictionaryList',
name: 'Sys_DictionaryList',
component: () => import('@/views/system/Sys_DictionaryList.vue')
}
, {
},
{
path: '/SellOrder',
name: 'SellOrder',
component: () => import('@/views/order/SellOrder.vue')
}, {
},
{
path: '/SellOrder2',
name: 'SellOrder2',
component: () => import('@/views/order/SellOrder2.vue')
}, {
},
{
path: '/SellOrder3',
name: 'SellOrder3',
component: () => import('@/views/order/SellOrder3.vue')
}, {
},
{
path: '/vSellOrderImg',
name: 'vSellOrderImg',
component: () => import('@/views/order/vSellOrderImg.vue')
@ -69,66 +73,92 @@ let viewgird = [
meta: {
keepAlive: false
}
}
, {
},
{
path: '/App_Expert',
name: 'App_Expert',
component: () => import('@/views/appmanager/App_Expert.vue')
}
, {
},
{
path: '/App_Expert2',
name: 'App_Expert2',
component: () => import('@/views/appmanager/App_Expert2.vue')
}
, {
},
{
path: '/App_Transaction',
name: 'App_Transaction',
component: () => import('@/views/appmanager/App_Transaction.vue')
}
, {
},
{
path: '/App_Transaction2',
name: 'App_Transaction2',
component: () => import('@/views/appmanager/App_Transaction2.vue')
}, {
},
{
path: '/App_ReportPrice',
name: 'App_ReportPrice',
component: () => import('@/views/appmanager/App_ReportPrice.vue')
}, {
},
{
path: '/App_News',
name: 'App_News',
component: () => import('@/views/appmanager/App_News.vue')
}, {
},
{
path: '/App_NewsEditor',
name: 'App_NewsEditor',
component: () => import('@/views/appmanager/App_NewsEditor.vue')
} ,{
},
{
path: '/FormDesignOptions',
name: 'FormDesignOptions',
component: () => import('@/views/system/form/FormDesignOptions.vue')
} ,{
},
{
path: '/FormCollectionObject',
name: 'FormCollectionObject',
component: () => import('@/views/system/form/FormCollectionObject.vue')
} ,{
},
{
path: '/Sys_WorkFlow',
name: 'Sys_WorkFlow',
component: () => import('@/views/system/flow/Sys_WorkFlow.vue')
} ,{
},
{
path: '/Sys_WorkFlowTable',
name: 'Sys_WorkFlowTable',
component: () => import('@/views/system/flow/Sys_WorkFlowTable.vue')
} ,{
},
{
path: '/Sys_QuartzOptions',
name: 'Sys_QuartzOptions',
component: () => import('@/views/system/quartz/Sys_QuartzOptions.vue')
} ,{
},
{
path: '/Sys_QuartzLog',
name: 'Sys_QuartzLog',
component: () => import('@/views/system/quartz/Sys_QuartzLog.vue')
} ,{
},
{
path: '/Sys_Department',
name: 'Sys_Department',
component: () => import('@/views/system/system/Sys_Department.vue')
}]
},
{
path: '/Data_Produce',
name: 'Data_Produce',
component: () => import('@/views/data/produce/Data_Produce.vue')
},
{
path: '/Data_Config',
name: 'Data_Config',
component: () => import('@/views/data/config/Data_Config.vue')
},
{
path: '/Data_Machine',
name: 'Data_Machine',
component: () => import('@/views/data/machine/Data_Machine.vue')
}
]
export default viewgird

@ -324,6 +324,24 @@ let base = {
return this.getTreeAllChildren(id, data).map((c) => {
return c.id;
});
},
//使用递归的方式实现数组、对象的深拷贝
deepClone(obj) {
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
var objClone = Array.isArray(obj) ? [] : {};
//进行深拷贝的不能为空,并且是对象或者是
if (obj && typeof obj === "object") {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = this.deepClone(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
};
export default base;

@ -1,382 +1,20 @@
<template>
<div class="home-contianer">
<div class="h-top">
<div class="h-top-left" id="h-chart1">left</div>
<div class="h-top-center">
<div class="n-item">
<div
@click="open(item)"
class="item"
:class="'item' + (index + 1)"
v-for="(item, index) in center"
:key="index"
>
<i
style="font-size: 30px; padding-bottom: 10px"
:class="item.icon"
:size="20"
></i>
<br />
{{ item.title }}
</div>
</div>
</div>
<div class="h-top-right task-table">
<h3 class="h3">#框架Vue3.x版本变更说明</h3>
<table border="0" cellspacing="0" cellpadding="0">
<tr v-for="(row, index) in list" :key="index">
<td>{{ index + 1 }}</td>
<td>{{ row.desc }}</td>
</tr>
</table>
</div>
</div>
<div class="h-chart">
<div class="h-left-grid">
<div class="item" v-for="(item, index) in grid" :key="index">
<div class="icon-text">
<i :class="item.icon"></i>
<span class="name">{{ item.name }}</span>
</div>
<div class="desc">{{ item.desc }}</div>
</div>
</div>
<div id="h-chart2"></div>
<div id="h-chart3"></div>
</div>
<div style="display: flex;">
<div
id="h-chart4"
style="height: 350px; background: white; flex: 1;padding-top:15px;"
></div>
<div
id="h-chart5"
style="height: 350px; background: white; flex: 1;padding-top:15px;"
></div>
</div>
<div class="title">欢迎登录云息数采平台</div>
</div>
</template>
<script>
import * as echarts from 'echarts';
import { chart1, chart2, chart3, chart4 } from './home/home-chart-options';
import { ref, onMounted, onUnmounted } from 'vue';
var $chart2;
export default {
components: {},
data() {
return {
center: [
{
title: 'GitHub',
icon: 'el-icon-set-up',
url: 'https://github.com/cq-panda/Vue.NetCore'
},
{
title: 'Gitee',
icon: 'el-icon-turn-off',
url: 'https://gitee.com/x_discoverer/Vue.NetCore'
},
{
title: '框架Vue2版本',
icon: 'el-icon-reading',
url: 'http://v2.volcore.xyz'
},
{
title: '框架视频',
icon: 'el-icon-document',
url: 'https://www.cctalk.com/m/group/90268531'
},
{
title: '小程序/app/h5',
icon: 'el-icon-chat-line-round',
url: 'http://v2.volcore.xyz/app/guide'
},
{
title: 'QQ3群743852316',
icon: 'el-icon-chat-dot-round',
url: 'https://jq.qq.com/?_wv=1027&k=Sqstuy0M'
}
],
n: 90,
value1: '1',
applicants: {
//
day: 20, //
week: 150, //
month: 1200, //
totalBoy: 800,
totalGirl: 890,
taotal: 1690
}, //
list: [
{ desc: '框架2.x版本不支持直接升级Vue3版本(代码生成器已修改)' },
{ desc: '框架使用的Element Plus组件移除了Iview组件的依赖' },
{ desc: '框架内部组件全部重新优化,相比2.x版本首屏大小减少60%' },
{ desc: '框架Vue2版本会继续维护,并与Vue3版本同步更新,请放心使用' },
{ desc: '框架Vue2、Vue3版本开发文档一致(差异部分文档会备注说明)' },
//{ desc: "使Vue2使;使Vue3" },
{
desc: 'vue2、vue3文档相同,开文档大部分文档仍然使用的vue2语法'
},
{
desc: '自定义部分既可以使用vue3语法与可以使用vue3语法'
}
//(vue2/3使),使vue3
],
grid: [
{
name: '用户管理',
desc: '系统用户管理,注册用户3000000人。',
icon: 'el-icon-user'
},
{
name: '站内消息',
desc: '您有一条新的消息,请及时处理。',
icon: 'el-icon-chat-dot-round'
},
{
name: '系统管理',
desc: '这里放点什么,还没想好。',
icon: 'el-icon-setting'
},
{
name: '还没想好',
desc: '这里不知道应该放点什么或者写点什么。',
icon: 'el-icon-document'
},
{
name: '语音导航',
desc: '高德地图林志玲为您语音导航。',
icon: 'el-icon-microphone'
},
{
name: '垃圾回收',
desc: '删除过的数据在此处找回。。。。',
icon: 'el-icon-delete'
}
]
};
},
setup() {
let open = (item) => {
window.open(item.url, '_blank');
};
let interval;
onMounted(() => {
$chart = echarts.init(document.getElementById('h-chart1'));
$chart.setOption(chart1);
$chart2 = echarts.init(document.getElementById('h-chart2'));
$chart2.setOption(chart2);
// interval = setInterval(() => {
// chart2.xAxis[0].data.splice(0, 1);
// let lastYear =
// chart2.xAxis[0].data[chart2.xAxis[0].data.length - 1] * 1 + 1;
// chart2.xAxis[0].data.push(lastYear);
// chart2.series[0].data.splice(0, 1);
// chart2.series[0].data.push(~~(Math.random() * 1000));
// chart2.series[1].data.splice(0, 1);
// chart2.series[1].data.push(~~(Math.random() * 1000));
// $chart2.setOption(chart2);
// }, 2000);
$chart3 = echarts.init(document.getElementById('h-chart3'));
$chart3.setOption(chart3);
let $chart4 = echarts.init(document.getElementById('h-chart4'));
$chart4.setOption(chart4);
let $chart5 = echarts.init(document.getElementById('h-chart5'));
$chart5.setOption(chart2);
});
onUnmounted(() => {
interval && clearInterval(interval);
if ($chart) {
$chart.dispose();
$chart2.dispose();
$chart3.dispose();
}
});
return { open };
},
destroyed() {
$chart2 = null;
}
};
var $chart, $chart2, $chart3;
// window.addEventListener("resize", function () {
// $chart2.setOption(chart2);
// });
</script>
<style lang="less" scoped>
.home-contianer {
padding: 6px;
background: #eee;
width: 100%;
height: 100%;
// max-width: 800px;
// position: absolute;
top: 0;
right: 0;
left: 0;
margin: 0 auto;
.h-top {
display: flex;
.h-top-left {
height: 100%;
width: 300px;
background: white;
}
height: 300px;
}
.h-top > div {
border: 1px solid #e8e7e7;
border-radius: 5px;
// margin: 6px;
}
.h-top-center {
height: 100%;
background: white;
margin: 0 6px;
display: flex;
flex-direction: column;
flex: 1;
.item1 .num {
padding-top: 28px;
}
.item2 .num {
padding-bottom: 20px;
}
.n-item {
width: 100%;
height: 100%;
text-align: center;
cursor: pointer;
// display: flex;
.item {
border-right: 1px solid #e5e5e5;
width: 33.3333333%;
float: left;
height: 50%;
border-bottom: 1px solid #e5e5e5;
padding: 47px 0;
font-size: 13px;
}
.item:hover {
background: #f9f9f9;
cursor: pointer;
}
.item:last-child {
border-right: 0;
}
.item3,
.item6 {
border-right: 0;
}
.num {
word-break: break-all;
color: #282727;
font-size: 30px;
transition: transform 0.8s;
}
.num:hover {
color: #55ce80;
transform: scale(1.2);
}
.text {
font-size: 13px;
color: #777;
}
}
}
.h-top-right {
// flex: 1;
width: 400px;
height: 100%;
background: white;
}
.h3 {
padding: 7px 15px;
font-weight: 500;
background: #fff;
border-bottom: 1px dotted #d4d4d4;
}
}
.task-table {
table {
width: 100%;
.thead {
font-weight: bold;
}
tr {
cursor: pointer;
td {
border-bottom: 1px solid #f3f3f3;
padding: 9px 8px;
font-size: 12px;
}
}
tr:hover {
background: #eee;
}
}
}
.h-chart {
height: 340px;
margin: 6px 0px;
display: flex;
.h-left-grid {
width: 300px;
height: 100%;
background: white;
display: inline-block;
.name {
margin-left: 7px;
}
.item:hover {
background: #f9f9f9;
cursor: pointer;
}
.item {
padding: 22px 14px;
float: left;
width: 50%;
height: 33.33333%;
border-bottom: 1px solid #eee;
border-right: 1px solid #eee;
i {
font-size: 30px;
}
.desc {
font-size: 12px;
color: #c3c3c3;
padding: 5px 0 0 4px;
line-height: 1.5;
}
}
}
}
#h-chart2 {
border-radius: 3px;
background: white;
padding-top: 10px;
height: 100%;
width: 0;
flex: 1;
margin: 0 7px;
}
#h-chart3 {
border-radius: 3px;
padding: 10px 10px 0 10px;
background: white;
// padding-top: 10px;
height: 100%;
width: 400px;
.title {
margin: 10px;
}
</style>

@ -0,0 +1,382 @@
<template>
<div class="home-contianer">
<div class="h-top">
<div class="h-top-left" id="h-chart1">left</div>
<div class="h-top-center">
<div class="n-item">
<div
@click="open(item)"
class="item"
:class="'item' + (index + 1)"
v-for="(item, index) in center"
:key="index"
>
<i
style="font-size: 30px; padding-bottom: 10px"
:class="item.icon"
:size="20"
></i>
<br />
{{ item.title }}
</div>
</div>
</div>
<div class="h-top-right task-table">
<h3 class="h3">#框架Vue3.x版本变更说明</h3>
<table border="0" cellspacing="0" cellpadding="0">
<tr v-for="(row, index) in list" :key="index">
<td>{{ index + 1 }}</td>
<td>{{ row.desc }}</td>
</tr>
</table>
</div>
</div>
<div class="h-chart">
<div class="h-left-grid">
<div class="item" v-for="(item, index) in grid" :key="index">
<div class="icon-text">
<i :class="item.icon"></i>
<span class="name">{{ item.name }}</span>
</div>
<div class="desc">{{ item.desc }}</div>
</div>
</div>
<div id="h-chart2"></div>
<div id="h-chart3"></div>
</div>
<div style="display: flex;">
<div
id="h-chart4"
style="height: 350px; background: white; flex: 1;padding-top:15px;"
></div>
<div
id="h-chart5"
style="height: 350px; background: white; flex: 1;padding-top:15px;"
></div>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts';
import { chart1, chart2, chart3, chart4 } from './home/home-chart-options';
import { ref, onMounted, onUnmounted } from 'vue';
var $chart2;
export default {
components: {},
data() {
return {
center: [
{
title: 'GitHub',
icon: 'el-icon-set-up',
url: 'https://github.com/cq-panda/Vue.NetCore'
},
{
title: 'Gitee',
icon: 'el-icon-turn-off',
url: 'https://gitee.com/x_discoverer/Vue.NetCore'
},
{
title: '框架Vue2版本',
icon: 'el-icon-reading',
url: 'http://v2.volcore.xyz'
},
{
title: '框架视频',
icon: 'el-icon-document',
url: 'https://www.cctalk.com/m/group/90268531'
},
{
title: '小程序/app/h5',
icon: 'el-icon-chat-line-round',
url: 'http://v2.volcore.xyz/app/guide'
},
{
title: 'QQ3群743852316',
icon: 'el-icon-chat-dot-round',
url: 'https://jq.qq.com/?_wv=1027&k=Sqstuy0M'
}
],
n: 90,
value1: '1',
applicants: {
//
day: 20, //
week: 150, //
month: 1200, //
totalBoy: 800,
totalGirl: 890,
taotal: 1690
}, //
list: [
{ desc: '框架2.x版本不支持直接升级Vue3版本(代码生成器已修改)' },
{ desc: '框架使用的Element Plus组件移除了Iview组件的依赖' },
{ desc: '框架内部组件全部重新优化,相比2.x版本首屏大小减少60%' },
{ desc: '框架Vue2版本会继续维护,并与Vue3版本同步更新,请放心使用' },
{ desc: '框架Vue2、Vue3版本开发文档一致(差异部分文档会备注说明)' },
//{ desc: "使Vue2使;使Vue3" },
{
desc: 'vue2、vue3文档相同,开文档大部分文档仍然使用的vue2语法'
},
{
desc: '自定义部分既可以使用vue3语法与可以使用vue3语法'
}
//(vue2/3使),使vue3
],
grid: [
{
name: '用户管理',
desc: '系统用户管理,注册用户3000000人。',
icon: 'el-icon-user'
},
{
name: '站内消息',
desc: '您有一条新的消息,请及时处理。',
icon: 'el-icon-chat-dot-round'
},
{
name: '系统管理',
desc: '这里放点什么,还没想好。',
icon: 'el-icon-setting'
},
{
name: '还没想好',
desc: '这里不知道应该放点什么或者写点什么。',
icon: 'el-icon-document'
},
{
name: '语音导航',
desc: '高德地图林志玲为您语音导航。',
icon: 'el-icon-microphone'
},
{
name: '垃圾回收',
desc: '删除过的数据在此处找回。。。。',
icon: 'el-icon-delete'
}
]
};
},
setup() {
let open = (item) => {
window.open(item.url, '_blank');
};
let interval;
onMounted(() => {
$chart = echarts.init(document.getElementById('h-chart1'));
$chart.setOption(chart1);
$chart2 = echarts.init(document.getElementById('h-chart2'));
$chart2.setOption(chart2);
// interval = setInterval(() => {
// chart2.xAxis[0].data.splice(0, 1);
// let lastYear =
// chart2.xAxis[0].data[chart2.xAxis[0].data.length - 1] * 1 + 1;
// chart2.xAxis[0].data.push(lastYear);
// chart2.series[0].data.splice(0, 1);
// chart2.series[0].data.push(~~(Math.random() * 1000));
// chart2.series[1].data.splice(0, 1);
// chart2.series[1].data.push(~~(Math.random() * 1000));
// $chart2.setOption(chart2);
// }, 2000);
$chart3 = echarts.init(document.getElementById('h-chart3'));
$chart3.setOption(chart3);
let $chart4 = echarts.init(document.getElementById('h-chart4'));
$chart4.setOption(chart4);
let $chart5 = echarts.init(document.getElementById('h-chart5'));
$chart5.setOption(chart2);
});
onUnmounted(() => {
interval && clearInterval(interval);
if ($chart) {
$chart.dispose();
$chart2.dispose();
$chart3.dispose();
}
});
return { open };
},
destroyed() {
$chart2 = null;
}
};
var $chart, $chart2, $chart3;
// window.addEventListener("resize", function () {
// $chart2.setOption(chart2);
// });
</script>
<style lang="less" scoped>
.home-contianer {
padding: 6px;
background: #eee;
width: 100%;
height: 100%;
// max-width: 800px;
// position: absolute;
top: 0;
right: 0;
left: 0;
margin: 0 auto;
.h-top {
display: flex;
.h-top-left {
height: 100%;
width: 300px;
background: white;
}
height: 300px;
}
.h-top > div {
border: 1px solid #e8e7e7;
border-radius: 5px;
// margin: 6px;
}
.h-top-center {
height: 100%;
background: white;
margin: 0 6px;
display: flex;
flex-direction: column;
flex: 1;
.item1 .num {
padding-top: 28px;
}
.item2 .num {
padding-bottom: 20px;
}
.n-item {
width: 100%;
height: 100%;
text-align: center;
cursor: pointer;
// display: flex;
.item {
border-right: 1px solid #e5e5e5;
width: 33.3333333%;
float: left;
height: 50%;
border-bottom: 1px solid #e5e5e5;
padding: 47px 0;
font-size: 13px;
}
.item:hover {
background: #f9f9f9;
cursor: pointer;
}
.item:last-child {
border-right: 0;
}
.item3,
.item6 {
border-right: 0;
}
.num {
word-break: break-all;
color: #282727;
font-size: 30px;
transition: transform 0.8s;
}
.num:hover {
color: #55ce80;
transform: scale(1.2);
}
.text {
font-size: 13px;
color: #777;
}
}
}
.h-top-right {
// flex: 1;
width: 400px;
height: 100%;
background: white;
}
.h3 {
padding: 7px 15px;
font-weight: 500;
background: #fff;
border-bottom: 1px dotted #d4d4d4;
}
}
.task-table {
table {
width: 100%;
.thead {
font-weight: bold;
}
tr {
cursor: pointer;
td {
border-bottom: 1px solid #f3f3f3;
padding: 9px 8px;
font-size: 12px;
}
}
tr:hover {
background: #eee;
}
}
}
.h-chart {
height: 340px;
margin: 6px 0px;
display: flex;
.h-left-grid {
width: 300px;
height: 100%;
background: white;
display: inline-block;
.name {
margin-left: 7px;
}
.item:hover {
background: #f9f9f9;
cursor: pointer;
}
.item {
padding: 22px 14px;
float: left;
width: 50%;
height: 33.33333%;
border-bottom: 1px solid #eee;
border-right: 1px solid #eee;
i {
font-size: 30px;
}
.desc {
font-size: 12px;
color: #c3c3c3;
padding: 5px 0 0 4px;
line-height: 1.5;
}
}
}
}
#h-chart2 {
border-radius: 3px;
background: white;
padding-top: 10px;
height: 100%;
width: 0;
flex: 1;
margin: 0 7px;
}
#h-chart3 {
border-radius: 3px;
padding: 10px 10px 0 10px;
background: white;
// padding-top: 10px;
height: 100%;
width: 400px;
}
</style>

@ -20,9 +20,9 @@
</div>
<div class="vol-container" :style="{ left: menuWidth - 1 + 'px' }">
<div class="vol-header">
<div class="project-name">Vol开发框架Vue3版本</div>
<div class="project-name">{{departName}}</div>
<div class="header-text">
<div class="h-link">
<!-- <div class="h-link">
<a
href="javascript:void(0)"
@click="to(item)"
@ -34,7 +34,7 @@
<span v-if="!item.icon"> {{ item.text }}</span>
<i v-else :class="item.icon"></i>
</a>
</div>
</div> -->
</div>
<div class="header-info">
<div class="h-link">
@ -226,6 +226,9 @@ export default defineComponent({
//
const { proxy } = getCurrentInstance();
//
const departName = ref("上海长江云息数字科技");
//
const menuWidth = ref(200);
const contextMenuVisible = ref(false);
@ -615,6 +618,14 @@ export default defineComponent({
});
};
created();
const getDepartName = () => {
// departName.value = "";
http.get("api/Sys_Department/getUserDepartment", {}, true).then((data) => {
departName.value = data.DepartmentName;
});
}
return {
menuWidth,
isCollapse,
@ -647,6 +658,8 @@ export default defineComponent({
closeTabsMenu,
closeTabs,
currentMenuId,
departName,
getDepartName,
};
},
/**
@ -661,6 +674,8 @@ export default defineComponent({
}, 1000);
this.bindRightClickMenu(true);
this.getDepartName();
},
methods: {

@ -1,6 +1,6 @@
<template>
<div class="login-container">
<div class="project-name">VOL开发框架,Vue3版本</div>
<div class="project-name">云息数采系统</div>
<div class="login-form">
<div class="form-user" @keypress="loginPress">
<div class="login-text">
@ -36,7 +36,7 @@
</div>
<!-- 账号信息 -->
<div class="account-info">
<!-- <div class="account-info">
<p>演示账号admin666 &nbsp; &nbsp;密码:123456</p>
<p>本地账号admin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;密码:123456</p>
<p><a href="https://jq.qq.com/?_wv=1027&k=Sqstuy0M" style="text-decoration: none"
@ -44,9 +44,9 @@
&nbsp; &nbsp;&nbsp; &nbsp;
<a href="http://v2.volcore.xyz/document/guide" style="text-decoration: none" target="_blank">框架文档</a>
</p>
</div>
</div> -->
<!-- 链接位置 -->
<div class="app-link" >
<!-- <div class="app-link" >
<a href="#" style="text-decoration: none">移动端扫码</a>
<a>
<i class="el-icon-chat-dot-round"></i> 小程序
@ -59,11 +59,11 @@
<i class="el-icon-document"></i>
H5
<img src="https://app-1256993465.cos.ap-nanjing.myqcloud.com/H5.png" /></a>
</div>
</div> -->
</div>
<!-- 页面底部 -->
<div class="login-footer">
<!-- <div class="login-footer">
<a style="text-decoration: none" href="https://beian.miit.gov.cn/" target="_blank">京ICP备19056538号-1</a>
@ -71,8 +71,7 @@
<a href="https://space.bilibili.com/525836469" style="text-decoration: none" target="blank">NET视频教程(微软MVP-ACE录制)</a>
<a href="https://www.cctalk.com/m/group/90268531" style="text-decoration: none" target="blank">VOL框架视频</a>
<a href="http://120.48.115.252:9990" style="text-decoration: none" target="blank">视频演示地址</a>
</div>
</div> -->
<img class="login-bg" src="/static/login_bg.png" />
</div>
</template>

@ -120,7 +120,7 @@ import {
chartRight1,
gauge,
} from "./bigdata/chart-options";
// import IviewCircle from "./bigdata/IviewCircle";
// import IviewCircle from "./bigdata/IviewCircle"; // vue2使IView
import "./bigdata/layout.less";
export default {
components: {

@ -0,0 +1,574 @@
let MachineInfo = {
series: [{
radius: '130%',
type: 'gauge',
startAngle: 180,
endAngle: 0,
min: 0,
max: 1,
splitNumber: 10,
center: ["50%", "80%"], // 圆心坐标
axisLine: {
lineStyle: {
width: 3,
color: [
[0.2, '#FF6E76'],
[0.4, '#FF9F7F'],
[0.6, '#FDDD60'],
[0.8, '#58D9F9'],
[1.0, '#7CFFB2']
]
}
},
pointer: {
icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
length: '12%',
width: 20,
offsetCenter: [0, '-60%'],
itemStyle: {
color: 'auto'
}
},
axisTick: {
length: 12,
lineStyle: {
color: 'auto',
width: 2
}
},
splitLine: {
length: 20,
lineStyle: {
color: 'auto',
width: 5
}
},
axisLabel: {
color: '#fff',
fontSize: 20,
// distance: -60,
rotate: 'tangential',
formatter: function (value) {
switch (value) {
case 0.20:
return "差";
case 0.50:
return "中";
case 0.80:
return "良";
default:
return '';
}
}
},
title: {
offsetCenter: [0, '-20%'],
fontSize: 20,
color: '#fff'
},
detail: {
fontSize: 30,
offsetCenter: [0, '0%'],
valueAnimation: true,
formatter: function (value) {
return Math.round(value * 100) + '%';
},
color: 'auto'
},
data: [
{
value: 0.70,
name: ''
}
]
}]
};
let WorkData = {
turnout: {
title: {
text: '线',
textStyle: {
fontSize: 20,
color: "#fff"
},
left: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['1', '2', '3'],
itemGap: 20, // 标签间距
textStyle: {
fontSize: 14,
color: '#fff'
}
},
toolbox: {
feature: {
// 自定义切换按钮,只能以 my 开头
mySwitch: {
show: true,
title: '',
icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
onclick: function () {
alert('')
}
},
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] }
}
},
grid: {
left: '2%',
right: '5%',
bottom: '2%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false, // 坐标轴两边不留白
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { // 坐标轴
lineStyle: {
color: '#fff',
}
},
axisTick: { // 坐标轴刻度线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '',
position: 'left',
alignTicks: true,
axisLine: {
show: true,
lineStyle: {
color: '#fff',
},
},
axisLabel: {
formatter: '{value} '
},
splitLine: { // 坐标轴分隔线
show: true,
lineStyle: {
// 使用深浅的间隔色
color: ['#4fd2dd','#235fa7'],
width: 1
}
}
}
],
series: [
{
name: '1',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '2',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '3',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [150, 232, 201, 154, 190, 330, 410]
},
]
},
schedule: {
title: {
text: '线',
textStyle: {
fontSize: 20,
color: "#fff"
},
left: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
grid: {
left: '2%',
right: '5%',
bottom: '2%',
containLabel: true
},
legend: {
data: ['1', '2', '3'],
itemGap: 20, // 标签间距
textStyle: {
fontSize: 14,
color: '#fff'
}
},
xAxis: [
{
type: 'category',
boundaryGap: false, // 坐标轴两边不留白
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { // 坐标轴
lineStyle: {
color: '#fff',
}
},
axisTick: { // 坐标轴刻度线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '',
// position: 'right',
// min: 0,
// max: 100,
// interval: 20,
alignTicks: true,
axisLine: {
show: true,
lineStyle: {
color: '#fff',
},
},
axisLabel: {
formatter: '{value} %'
},
splitLine: { // 坐标轴分隔线
show: true,
lineStyle: {
// 使用深浅的间隔色
color: ['#4fd2dd','#235fa7'],
width: 1
}
}
}
],
series: [
{
name: '1',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [91, 92, 88, 94, 87, 85, 95]
},
{
name: '2',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [81, 92, 98, 93, 97, 95, 85]
},
{
name: '3',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [81, 97, 83, 91, 89, 95, 92]
},
]
},
yield: {
title: {
text: '线',
textStyle: {
fontSize: 20,
color: "#fff"
},
left: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
grid: {
left: '2%',
right: '5%',
bottom: '2%',
containLabel: true
},
legend: {
data: ['1', '2', '3'],
itemGap: 20, // 标签间距
textStyle: {
fontSize: 14,
color: '#fff'
}
},
xAxis: [
{
type: 'category',
boundaryGap: false, // 坐标轴两边不留白
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { // 坐标轴
lineStyle: {
color: '#fff',
}
},
axisTick: { // 坐标轴刻度线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '',
// offset: 80,
// position: 'right',
alignTicks: true,
axisLine: {
show: true,
lineStyle: {
color: '#fff',
},
},
axisLabel: {
formatter: '{value} %'
},
splitLine: { // 坐标轴分隔线
show: true,
lineStyle: {
// 使用深浅的间隔色
color: ['#4fd2dd','#235fa7'],
width: 1
}
}
}
],
series: [
{
name: '1',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [81, 82, 88, 94, 89, 85, 85]
},
{
name: '2',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [81, 93, 83, 84, 87, 85, 95]
},
{
name: '3',
type: 'line',
// stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [91, 82, 88, 84, 87, 85, 94]
},
]
}
}
let WeekProcess = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
},
},
// formatter: function (params) {
// console.log(params);
// }
},
toolbox: {
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
saveAsImage: { show: true, name: "近一周加工数" }
}
},
legend: {
top: 0,
data: ['广980DI-1', '西828D-1'],
itemGap: 20, // 标签间距
textStyle: {
fontSize: 14,
color: '#fff'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '2%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisPointer: {
type: 'shadow'
},
axisLine: { // 坐标轴
lineStyle: {
color: '#fff',
}
},
axisTick: { // 坐标轴刻度线
lineStyle: {
color: '#fff',
}
}
}
],
yAxis: [
{
type: 'value',
name: '广980DI-1',
alignTicks: true,
min: 0,
axisLabel: {
formatter: '{value} '
},
axisLine: { // 坐标轴
show: false, // 不显示坐标轴轴线。
lineStyle: {
color: '#fff',
},
onZero: true
},
splitLine: { // 坐标轴分隔线
show: true,
lineStyle: {
// 使用深浅的间隔色
color: ['#fff', '#ff9f7f'],
width: 1
}
}
},
{
type: 'value',
name: '西828D-1',
min: 0,
// interval: 50,
alignTicks: true,
axisLabel: {
formatter: '{value} '
},
axisLine: { // 坐标轴
lineStyle: {
color: '#fff',
}
},
splitLine: { // 坐标轴分隔线
show: true,
lineStyle: {
// 使用深浅的间隔色
color: ['#fff', '#ff9f7f'],
width: 1
}
}
}
],
series: [
{
name: '广980DI-1',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' ';
}
},
data: [
100, 99, 91, 107, 121, 137, 101
]
},
{
name: '西828D-1',
type: 'bar',
tooltip: {
valueFormatter: function (value) {
return value + ' ';
}
},
data: [
120, 117, 99, 100, 111, 127, 101
]
}
]
}
export { MachineInfo, WorkData, WeekProcess }

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

@ -0,0 +1,297 @@
.big-data-container {
position: absolute;
overflow: hidden;
height: 100%;
width: 100%;
background-color: #1400a8;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25' viewBox='0 0 1200 800'%3E%3Cdefs%3E%3CradialGradient id='a' cx='0' cy='800' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%230e0077'/%3E%3Cstop offset='1' stop-color='%230e0077' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='b' cx='1200' cy='800' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%2314057c'/%3E%3Cstop offset='1' stop-color='%2314057c' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='c' cx='600' cy='0' r='600' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%230d0524'/%3E%3Cstop offset='1' stop-color='%230d0524' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='d' cx='600' cy='800' r='600' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%231400a8'/%3E%3Cstop offset='1' stop-color='%231400a8' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='e' cx='0' cy='0' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23000000'/%3E%3Cstop offset='1' stop-color='%23000000' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='f' cx='1200' cy='0' r='800' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23130733'/%3E%3Cstop offset='1' stop-color='%23130733' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect fill='url(%23a)' width='1200' height='800'/%3E%3Crect fill='url(%23b)' width='1200' height='800'/%3E%3Crect fill='url(%23c)' width='1200' height='800'/%3E%3Crect fill='url(%23d)' width='1200' height='800'/%3E%3Crect fill='url(%23e)' width='1200' height='800'/%3E%3Crect fill='url(%23f)' width='1200' height='800'/%3E%3C/svg%3E");
background-attachment: fixed;
background-size: cover;
.header {
height: 80px;
// background: url(./head_bg.png) no-repeat center center;
// background-size: 100% 100%;
position: relative;
z-index: 100;
display: flex;
justify-content: space-between;
.header-item {
flex: 1;
position: relative;
text-align: center;
color: #fff;
.version {
position: absolute;
top: 40px;
left: 40%;
right: 0;
}
.topic {
position: relative;
top: 15px;
}
.datetime {
position: absolute;
top: 40px;
left: 0;
right: 40%;
}
.dv-decoration-8 {
width: 100%;
height: 60px;
}
.dv-decoration-5 {
width: 85%;
height: 60px;
margin: 0 auto;
}
}
}
.data-container {
height: 1000px;
margin: 0px 15px;
position: absolute;
left: 0;
right: 0;
top: 80px;
bottom: 0;
.border-box-content {
width: 100%;
padding: 20px;
display: flex;
}
.data-left,
.data-right {
flex: 1;
margin-right: 10px;
display: flex;
flex-direction: column;
.data-left-item,
.data-right-item {
flex: 1;
border: 1px solid rgba(25, 186, 139, 0.17);
padding: 2px 4px;
background: rgba(255, 255, 255, 0.04);
background-size: 100% auto;
position: relative;
margin-bottom: 10px;
z-index: 10;
.title {
height: 50px;
text-align: center;
color: #fff;
line-height: 50px;
font-size: 24px;
}
.content {
height: 400px;
width: 100%;
.chart {
flex: 1;
height: 100%;
}
}
&::before {
border-left: 2px solid #02a6b5;
left: 0;
position: absolute;
width: 10px;
height: 10px;
content: "";
border-top: 2px solid #02a6b5;
top: 0;
}
&::after {
border-right: 2px solid #02a6b5;
right: 0;
position: absolute;
width: 10px;
height: 10px;
content: "";
border-top: 2px solid #02a6b5;
top: 0;
}
}
.data-foot-line {
position: absolute;
bottom: 0;
width: 100%;
left: 0;
&::before,
&::after {
position: absolute;
width: 10px;
height: 10px;
content: "";
border-bottom: 2px solid #02a6b5;
bottom: 0;
}
&::before {
border-left: 2px solid #02a6b5;
left: 0;
}
&::after {
border-right: 2px solid #02a6b5;
right: 0;
}
}
}
.oee {
height: 250px;
display: flex;
flex-direction: row;
justify-content: center;
}
.machine {
height: 150px;
display: flex;
flex-direction: row;
justify-content: space-around;
.status-item {
flex: 1;
.tagbox {
width: 100%;
padding: 0 10px;
display: flex;
justify-content: space-around;
align-items: center;
color: #fff;
.taglist {
flex: 1;
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
.tag {
width: 50%;
display: flex;
align-items: center;
margin: 5px 0;
.text {
font-size: 16px;
}
}
}
.status {
flex: 1;
.item {
margin: 5px;
font-size: 18px;
display: flex;
align-items: center;
.name {
margin-left: 5px;
}
}
}
}
}
}
.target {
position: absolute;
top: 20px;
right: 10px;
width: 200px;
}
.devicebox {
position: absolute;
top: 20px;
left: 10px;
width: 200px;
}
.output {
margin-top: 10px;
padding: 10px 0;
height: 400px;
}
.statbox {
height: 400px;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #fff;
padding: 10px;
.stat-item {
flex: 1;
width: 100%;
display: flex;
align-items: center;
.device {
font-size: 20px;
flex: 1;
display: flex;
align-items: center;
.name {
margin-left: 5px;
text-align: center;
}
}
.stat-info {
flex: 3;
display: flex;
flex-direction: row;
.digital {
flex: 1;
.head {
margin-top: 30px;
font-size: 20px;
text-align: center;
height: 20px;
line-height: 20px;
}
}
}
}
}
}
}

@ -0,0 +1,434 @@
<template>
<div id="big-data-container" class="big-data-container">
<dv-loading v-if="loading">Loading...</dv-loading>
<dv-full-screen-container v-else>
<div class="header">
<div class="header-item">
<h3 class="version">CHANKO V1.0.0</h3>
<dv-decoration-8 />
</div>
<div class="header-item">
<h2 class="topic">大屏数据看板</h2>
<dv-decoration-5 />
</div>
<div class="header-item">
<h3 class="datetime">{{ datetime }}</h3>
<dv-decoration-8 :reverse="true" />
</div>
</div>
<!-- 四方格样式 -->
<div class="data-container">
<dv-border-box-13>
<div class="data-left">
<div class="data-left-item">
<div class="title">设备综合利用率</div>
<div class="content">
<div class="oee">
<div class="chart" v-for="(machine, index) in machineList" :key="index">
<!-- {{machine.name + "--" + machine.oee}} -->
<Gauge :option="machineOption(machine,index)" ref="vgauge"></Gauge>
</div>
</div>
<div class="machine">
<div class="status-item">
<div class="title">运行状态</div>
<div class="tagbox">
<div class="taglist">
<div class="tag" v-for="(item, index) in dicts.state" :key="index">
<el-icon :color="item.color" :size="30">
<TakeawayBox />
</el-icon>
<span class="text">{{ item.name }}</span>
</div>
</div>
<div class="status">
<div class="item" v-for="(machine, index) in machineList" :key="index">
<template v-if="machine.com_status == 5">
<template v-for="item in dicts.state" :key="item.value">
<el-icon :color="item.color" :size="40" v-if="item.value == machine.state">
<TakeawayBox />
</el-icon>
</template>
</template>
<!-- 通讯断开时运行状态为灰色 -->
<template v-else>
<el-icon color="#e4e4e4" :size="40">
<TakeawayBox />
</el-icon>
</template>
<span class="name">{{ machine.name }}</span>
</div>
</div>
</div>
</div>
<div class="status-item">
<div class="title">通讯状态</div>
<div class="tagbox">
<div class="taglist">
<div class="tag" v-for="(item, index) in dicts.com_status" :key="index">
<el-icon :color="item.color" :size="30">
<Link />
</el-icon>
<span class="text">{{ item.name }}</span>
</div>
</div>
<div class="status">
<!-- <div class="item">
<el-icon color="#FF6E76" :size="40">
<Link />
</el-icon>
<span class="name">西门子828D-1</span>
</div> -->
<!-- <div class="item">
<el-icon color="#7CFFB2" :size="40">
<Link />
</el-icon>
<span class="name">广数980DI-1</span>
</div> -->
<div class="item" v-for="(machine, index) in machineList" :key="index">
<template v-for="item in dicts.com_status" :key="item.value">
<el-icon :color="item.color" :size="40" v-if="item.value == machine.com_status">
<Link />
</el-icon>
</template>
<span class="name">{{ machine.name }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="data-foot-line"></div>
</div>
<div class="data-left-item">
<div class="title">工单近一周走势图</div>
<div class="target">
<el-select v-model="gdfrom.target" @change="changeQuota">
<el-option label="产量" value="turnout" />
<el-option label="进度" value="schedule" />
<el-option label="良品率" value="yield" />
</el-select>
</div>
<div class="devicebox">
<el-select v-model="gdfrom.configId" @change="changeDevice">
<el-option v-for="(machine, index) in machineList" :label="machine.name" :value="machine.config_id"
:key="index" />
</el-select>
</div>
<div class="output">
<Line :option="workdata[gdfrom.target]" ref="vline"></Line>
</div>
<div class="data-foot-line"></div>
</div>
</div>
<div class="data-right">
<div class="data-right-item">
<div class="title">统计数据</div>
<div class="statbox">
<div class="stat-item" v-for="(machine, index) in machineList" :key="index">
<!-- {{ machine.totalQuantity }} -->
<div class="device">
<el-icon color="#8378ea" :size="40">
<TakeawayBox />
</el-icon>
<div class="name">
<div style="margin-bottom: 5px;">{{ machine.name }}</div>
<div>{{ machine.com_ip }}</div>
</div>
</div>
<div class="stat-info">
<div class="digital">
<div class="head">当班产量</div>
<Number :number="machine.currentTurnout || 0" unity="件"></Number>
</div>
<div class="digital">
<div class="head">累计加工数</div>
<Number :number="machine.totalQuantity || 0" unity="次" :toFixed="1" :toFormat="false"></Number>
</div>
<div class="digital">
<div class="head">累计运行时长</div>
<Number :number="machine.totalRuntime || 0" unity="分"></Number>
</div>
</div>
</div>
</div>
<div class="data-foot-line"></div>
</div>
<div class="data-right-item">
<div class="title">最近一周加工数</div>
<div class="output">
<Bar :option="weekprocess" ref="vbar"></Bar>
</div>
<div class="data-foot-line"></div>
</div>
</div>
</dv-border-box-13>
</div>
</dv-full-screen-container>
</div>
</template>
<script>
import Gauge from "@/components/echarts/Gauge.vue";
import Bar from "@/components/echarts/Bar.vue";
import Line from "@/components/echarts/Line.vue";
import Number from "@/components/echarts/Number.vue";
import { MachineInfo, WorkData, WeekProcess } from "./chart-options";
import "./index.less";
export default {
components: {
Bar,
Gauge,
Line,
Number
},
data() {
return {
loading: true,
datetime: '',
dicts: {
state: [
{ color: "#FDDD60", name: "待机", value: 0 },
{ color: "#FF6E76", name: "故障", value: 1 },
{ color: "#7CFFB2", name: "运行", value: 2 },
{ color: "#58D9F9", name: "暂停", value: 3 }
],
com_status: [
{ color: "#FF6E76", name: "通讯断开", value: 15 },
{ color: "#7CFFB2", name: "通讯正常", value: 5 },
]
},
machineList: [
{
id: 1,
config_id: 1,
name: "西门子828D-11",
com_ip: "192.168.1.99",
com_status: 5,
state: 3,
oee: 0.88,
currentTurnout: 1009,
totalQuantity: 19876.5,
totalRuntime: 10086
},
{
id: 2,
config_id: 2,
name: "GSK980DI-12",
com_ip: "192.168.1.100",
com_status: 5,
state: 2,
oee: 0.92,
currentTurnout: 1009,
totalQuantity: 19876.5,
totalRuntime: 10086
}
],
machineinfo: MachineInfo,
workdata: WorkData,
weekprocess: WeekProcess,
gdfrom: {
target: "turnout",
configId: 1
},
timer: null
}
},
mounted() {
console.log(this.$refs.vline); // undefine
console.log("数据加载中...");
this.onLoading();
this.datetime = this.base.getDate(true);
setInterval(() => {
this.datetime = this.base.getDate(true);
});
window.addEventListener('beforeunload', this.clearTimer); //
},
methods: {
onLoading() {
this.getMachineData();
this.getWeekProcessData();
this.getWeekWorkData();
setTimeout(() => {
this.loading = false;
}, 3000);
// 10
this.timer = setInterval(() => {
this.getMachineData(true);
this.getWeekProcessData(true);
this.getWeekWorkData(true);
}, 10000);
},
changeDevice(value) {
this.gdfrom.configId = value;
this.getWeekWorkData(true);
},
//
changeQuota(value) {
// console.log(this.$refs);
// console.log(this.$refs.vline);
let option = this.workdata[value];
this.$refs.vline.initLine(option);
},
//
machineOption(machine) {
let machineOption = this.base.deepClone(this.machineinfo); // copy
let oeeObj = {
name: machine.name,
value: machine.oee
}
machineOption.series[0].data[0] = oeeObj;
return machineOption;
},
getMachineData(rerender) { //
this.http.post("/api/Data_Screen/GetMachineData", {}, true)
.then(result => {
let machineList = [];
for (let key in result) {
let {
id, config_id, name, com_ip, com_status, state, oee,
currentTurnout, totalQuantity, totalRuntime
} = { ...result[key] };
machineList.push({
id, config_id, name, com_ip, com_status, state, oee,
currentTurnout, totalQuantity, totalRuntime
});
}
this.machineList = machineList;
// console.log(this.machineList);
if(rerender) {
for(let index in this.machineList) {
let machineOption = this.machineOption(this.machineList[index]);
this.$refs.vgauge[index].initGauge(machineOption);
}
}
});
},
getWeekProcessData(rerender) { //
this.http.post("/api/Data_Screen/GetTurnOutByWeekDays", {}, true)
.then(result => {
// console.log(result);
// console.log(this.machineNameMap);
let dataMap = result.dataMap;
this.weekprocess.legend.data = Object.values(this.machineNameMap);
this.weekprocess.xAxis[0].data = result.datelist;
let modelY = this.weekprocess.yAxis[0];
let modelS = this.weekprocess.series[0];
let yAxis = [];
let series = [];
for (let config_id in this.machineNameMap) {
let name = this.machineNameMap[config_id];
let itemYObj = this.base.deepClone(modelY);
itemYObj.name = name;
yAxis.push(itemYObj);
let itemSObj = this.base.deepClone(modelS);
itemSObj.name = name;
itemSObj.data = dataMap[config_id];
series.push(itemSObj);
}
this.weekprocess.yAxis = yAxis;
this.weekprocess.series = series;
// console.log(this.weekprocess);
if (rerender) { //
this.$refs.vbar.initBar(this.weekprocess);
}
});
},
getWeekWorkData(rerender) { //
// formData
let params = this.gdfrom;
const formData = new FormData();
for (let key in params) {
if (params.hasOwnProperty(key)) {
formData.append(key, params[key]);
}
}
this.http.post("/api/Data_Screen/GetWorkDataByWeekDays", formData, true, {
timeout: 10000,//10
headers: { "Content-Type": 'application/x-www-form-urlencoded' } //
}).then(result => {
let dataMap = result.dataMap;
for (let target in dataMap) {
let dataList = dataMap[target];
let targetData = this.workdata[target];
targetData.xAxis[0].data = result.datelist;
for (let index in dataList) {
targetData.series[index].data = dataList[index];
}
}
// console.log(this.workdata);
if (rerender) {
this.changeQuota(this.gdfrom.target);
}
});
},
getDeviceConfig() { //
// let wheres = [
// {
// name: "name",
// value: "西",
// displayType: "like"
// }
// ];
let wheres = []; //
let params = {
sort: "CreateDate",
order: "desc",
page: 1,
rows: 999,
wheres: JSON.stringify(wheres)
};
console.log(JSON.stringify(params));
this.http.post("/api/Data_Screen/GetDeviceConfig", {}, true)
.then(result => {
console.log(result);
});
},
getDictData() { //
let dicNos = ["machine_state", "produce_com_status"];
this.http.post('/api/Sys_Dictionary/GetVueDictionary', dicNos).then((res) => {
console.log(res);
});
},
clearTimer() { //
clearInterval(this.timer);
this.timer = null;
}
},
computed: {
machineNameMap() {
return this.machineList.reduce(function (obj, item) {
obj[item.config_id] = item.name;
return obj;
}, {});
}
// params(){
// // Proxy
// return JSON.parse(JSON.stringify(this.pagination));
// }
},
beforeDestroy() {
this.timer && this.clearTimer();
},
destroyed() {
window.removeEventListener('beforeunload', this.clearTimer) //
}
}
</script>
<style lang="less" scoped>
// vue3 dv-loading
:deep(.dv-loading) {
justify-content: start;
margin-top: 100px;
color: #fff;
.loading-tip {
font-size: 16px;
}
}
</style>

@ -0,0 +1,62 @@
<template>
<div class="test">
<Gauge :option="machineinfo" ref="vgauge"></Gauge>
</div>
</template>
<script>
import Gauge from "@/components/echarts/Gauge.vue";
import { MachineInfo, WorkData, WeekProcess } from "./chart-options";
export default {
components: {
Gauge,
// Bar,
// Line,
},
data() {
return {
machineinfo: MachineInfo
}
},
mounted() {
console.log(this.$refs.vgauge);
console.log("数据测试...");
this.onLoading();
window.addEventListener('beforeunload', this.clearTimer); //
},
methods: {
getMachineInfo(){
this.machineinfo = this.base.deepClone(MachineInfo);
},
onLoading() {
this.timer = setInterval(() => {
// this.machineinfo.series[0].data[0].value += 0.01;
this.getMachineInfo();
console.log(123456);
}, 10000);
},
clearTimer() { //
clearInterval(this.timer);
this.timer = null;
}
},
beforeDestroy() {
this.timer && this.clearTimer();
},
destroyed() {
window.removeEventListener('beforeunload', this.clearTimer) //
}
}
</script>
<style lang="less" scoped>
// vue3 dv-loading
.test {
width: 500px;
height: 500px;
}
</style>

@ -0,0 +1,69 @@
<!--
*Authorjxx
*Contact283591387@qq.com
*代码由框架生成,任何更改都可能导致被代码生成器覆盖
*业务请在@/extension/data/config/Data_Config.js此处编写
-->
<template>
<view-grid ref="grid"
:columns="columns"
:detail="detail"
:editFormFields="editFormFields"
:editFormOptions="editFormOptions"
:searchFormFields="searchFormFields"
:searchFormOptions="searchFormOptions"
:table="table"
:extend="extend">
</view-grid>
</template>
<script>
import extend from "@/extension/data/config/Data_Config.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
setup() {
const table = ref({
key: 'id',
footer: "Foots",
cnName: '设备配置',
name: 'config/Data_Config',
url: "/Data_Config/",
sortName: "id"
});
const editFormFields = ref({"name":"","device_ip":"","com_ip":"","type":""});
const editFormOptions = ref([[{"title":"设备名称","field":"name"}],
[{"title":"设备IP","field":"device_ip"}],
[{"title":"通讯IP","field":"com_ip","type":"text"}],
[{"dataKey":"device_type","data":[],"title":"机床类型","field":"type","type":"select"}]]);
const searchFormFields = ref({"type":"","com_ip":""});
const searchFormOptions = ref([[{"dataKey":"device_type","data":[],"title":"机床类型","field":"type","type":"select"},{"title":"通讯IP","field":"com_ip","type":"text"}]]);
const columns = ref([{field:'id',title:'id',type:'int',width:110,hidden:true,readonly:true,require:true,align:'left'},
{field:'name',title:'设备名称',type:'string',width:220,align:'left',sort:true},
{field:'type',title:'机床类型',type:'short',bind:{ key:'device_type',data:[]},width:120,align:'left'},
{field:'device_ip',title:'设备IP',type:'string',width:220,align:'left'},
{field:'com_ip',title:'通讯IP',type:'string',width:110,align:'left'},
{field:'CreateID',title:'CreateID',type:'int',width:100,hidden:true,align:'left'},
{field:'Creator',title:'Creator',type:'string',width:100,hidden:true,align:'left'},
{field:'CreateDate',title:'创建时间',type:'datetime',width:150,align:'left',sort:true},
{field:'ModifyID',title:'ModifyID',type:'int',width:100,hidden:true,align:'left'},
{field:'Modifier',title:'Modifier',type:'string',width:100,hidden:true,align:'left'},
{field:'ModifyDate',title:'更新时间',type:'datetime',width:150,align:'left',sort:true}]);
const detail = ref({
cnName: "#detailCnName",
table: "#detailTable",
columns: [],
sortName: "",
key: ""
});
return {
table,
extend,
editFormFields,
editFormOptions,
searchFormFields,
searchFormOptions,
columns,
detail,
};
},
});
</script>

@ -0,0 +1,95 @@
<!--
*Authorjxx
*Contact283591387@qq.com
*代码由框架生成,任何更改都可能导致被代码生成器覆盖
*业务请在@/extension/data/machine/Data_Machine.js此处编写
-->
<template>
<view-grid ref="grid"
:columns="columns"
:detail="detail"
:editFormFields="editFormFields"
:editFormOptions="editFormOptions"
:searchFormFields="searchFormFields"
:searchFormOptions="searchFormOptions"
:table="table"
:extend="extend">
</view-grid>
</template>
<script>
import extend from "@/extension/data/machine/Data_Machine.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
setup() {
const table = ref({
key: 'id',
footer: "Foots",
cnName: '机床数据',
name: 'machine/Data_Machine',
url: "/Data_Machine/",
sortName: "id"
});
const editFormFields = ref({"config_id":"","com_status":"","run_program_no":"","smode":"","gmode":"","temperature":"","potential":"","current":"","main_rate":"","feed_rate":"","cut_rate":"","state":"","quantity":"","on_time":"","run_time":"","run_time_total":"","quantity_total":""});
const editFormOptions = ref([[{"dataKey":"device_name","data":[],"title":"设备信息","required":true,"field":"config_id","disabled":true,"type":"select"},
{"dataKey":"produce_com_status","data":[],"title":"通讯状态","field":"com_status","type":"select"},
{"title":"加工程序号","field":"run_program_no"}],
[{"dataKey":"machine_smode","data":[],"title":"运行模式(西门子)","field":"smode","colSize":6,"type":"select"},
{"dataKey":"machine_gmode","data":[],"title":"运行模式(广数)","field":"gmode","colSize":6,"type":"select"}],
[{"title":"电机温度","field":"temperature","type":"decimal"},
{"title":"母线电压","field":"potential","type":"decimal"},
{"title":"实际电流","field":"current","type":"decimal"}],
[{"title":"主轴倍率","field":"main_rate","type":"decimal"},
{"title":"进给倍率","field":"feed_rate","type":"decimal"},
{"title":"切削倍率","field":"cut_rate","type":"decimal"}],
[{"title":"加工数","field":"quantity","type":"number"},
{"dataKey":"machine_state","data":[],"title":"运行状态","field":"state","type":"select"},
{"title":"开机时间","field":"on_time","type":"number"},
{"title":"运行时间","field":"run_time","type":"number"}],
[{"title":"累计运行时长","field":"run_time_total","type":"number"},
{"title":"累计加工数","field":"quantity_total","type":"number"}]]);
const searchFormFields = ref({"config_id":"","com_status":"","smode":"","gmode":"","run_program_no":"","state":"","quantity":[null,null],"CreateDate":[null,null]});
const searchFormOptions = ref([[{"dataKey":"device_name","data":[],"title":"设备信息","field":"config_id","type":"select"},{"title":"加工程序号","field":"run_program_no"},{"dataKey":"produce_com_status","data":[],"title":"通讯状态","field":"com_status","type":"select"}],[{"dataKey":"machine_smode","data":[],"title":"运行模式(西门子)","field":"smode","type":"select"},{"dataKey":"machine_gmode","data":[],"title":"运行模式(广数)","field":"gmode","type":"select"},{"dataKey":"machine_state","data":[],"title":"运行状态","field":"state","type":"select"}],[{"title":"加工数","field":"quantity","type":"range"},{"title":"记录时间","field":"CreateDate","type":"range"}]]);
const columns = ref([{field:'id',title:'id',type:'int',width:80,readonly:true,require:true,align:'left',sort:true},
{field:'config_id',title:'设备信息',type:'int',bind:{ key:'device_name',data:[]},width:110,readonly:true,require:true,align:'left'},
{field:'com_status',title:'通讯状态',type:'short',bind:{ key:'produce_com_status',data:[]},width:110,align:'left'},
{field:'smode',title:'运行模式(西门子)',type:'short',bind:{ key:'machine_smode',data:[]},width:140,align:'left'},
{field:'gmode',title:'运行模式(广数)',type:'short',bind:{ key:'machine_gmode',data:[]},width:140,align:'left'},
{field:'run_program_no',title:'加工程序号',type:'string',width:180,align:'left'},
{field:'state',title:'运行状态',type:'short',bind:{ key:'machine_state',data:[]},width:110,align:'left'},
{field:'temperature',title:'电机温度',type:'decimal',width:100,align:'left'},
{field:'potential',title:'母线电压',type:'decimal',width:100,align:'left'},
{field:'current',title:'实际电流',type:'decimal',width:100,align:'left'},
{field:'quantity',title:'加工数',type:'bigint',width:100,align:'left'},
{field:'main_rate',title:'主轴倍率',type:'decimal',width:100,align:'left'},
{field:'feed_rate',title:'进给倍率',type:'decimal',width:100,align:'left'},
{field:'cut_rate',title:'切削倍率',type:'decimal',width:100,align:'left'},
{field:'on_time',title:'开机时间',type:'bigint',width:150,align:'left'},
{field:'run_time',title:'运行时间',type:'bigint',width:150,align:'left'},
{field:'run_time_total',title:'累计运行时长',type:'bigint',width:150,align:'left'},
{field:'quantity_total',title:'累计加工数',type:'bigint',width:150,align:'left'},
{field:'CreateID',title:'CreateID',type:'int',width:100,hidden:true,align:'left'},
{field:'Creator',title:'Creator',type:'string',width:100,hidden:true,align:'left'},
{field:'CreateDate',title:'记录时间',type:'datetime',width:180,align:'left',sort:true},
{field:'ModifyID',title:'ModifyID',type:'int',width:100,hidden:true,align:'left'},
{field:'Modifier',title:'Modifier',type:'string',width:100,hidden:true,align:'left'},
{field:'ModifyDate',title:'更新时间',type:'datetime',width:180,align:'left',sort:true}]);
const detail = ref({
cnName: "#detailCnName",
table: "#detailTable",
columns: [],
sortName: "",
key: ""
});
return {
table,
extend,
editFormFields,
editFormOptions,
searchFormFields,
searchFormOptions,
columns,
detail,
};
},
});
</script>

@ -0,0 +1,93 @@
<!--
*Authorjxx
*Contact283591387@qq.com
*代码由框架生成,任何更改都可能导致被代码生成器覆盖
*业务请在@/extension/data/produce/Data_Produce.js此处编写
-->
<template>
<view-grid ref="grid"
:columns="columns"
:detail="detail"
:editFormFields="editFormFields"
:editFormOptions="editFormOptions"
:searchFormFields="searchFormFields"
:searchFormOptions="searchFormOptions"
:table="table"
:extend="extend">
</view-grid>
</template>
<script>
import extend from "@/extension/data/produce/Data_Produce.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
setup() {
const table = ref({
key: 'id',
footer: "Foots",
cnName: '生产数据',
name: 'produce/Data_Produce',
url: "/Data_Produce/",
sortName: "id"
});
const editFormFields = ref({"config_id":"","program_no":"","com_status":"","run_time":"","status":"","turnout_all":"","turnout_1":"","turnout_2":"","turnout_3":"","schedule_1":"","schedule_2":"","schedule_3":"","yield_1":"","yield_2":"","yield_3":"","oee":""});
const editFormOptions = ref([[{"dataKey":"device_name","data":[],"title":"设备信息","required":true,"field":"config_id","disabled":true,"type":"select"},
{"title":"程序编号","field":"program_no","type":"number"}],
[{"dataKey":"produce_com_status","data":[],"title":"通讯状态","field":"com_status","type":"select"},
{"title":"运行时长","field":"run_time","type":"number"}],
[{"dataKey":"produce_status","data":[],"title":"运行状态","field":"status","type":"select"},
{"title":"当班产量","field":"turnout_all","type":"number"}],
[{"title":"工单 1 产量","field":"turnout_1","type":"number"},
{"title":"工单 2 产量","field":"turnout_2","type":"number"},
{"title":"工单 3 产量","field":"turnout_3","type":"number"}],
[{"title":"工单1任务进度","field":"schedule_1","type":"decimal"},
{"title":"工单2任务进度","field":"schedule_2","type":"decimal"},
{"title":"工单3任务进度","field":"schedule_3","type":"decimal"}],
[{"title":"工单1良品率","field":"yield_1","type":"decimal"},
{"title":"工单2良品率","field":"yield_2","type":"decimal"},
{"title":"工单3良品率","field":"yield_3","type":"decimal"}],
[{"title":"设备综合效率","field":"oee","type":"decimal"}]]);
const searchFormFields = ref({"config_id":"","program_no":"","com_status":"","status":"","turnout_all":[null,null],"CreateDate":""});
const searchFormOptions = ref([[{"dataKey":"produce_status","data":[],"title":"运行状态","field":"status","type":"select"},{"title":"程序编号","field":"program_no","type":"number"},{"dataKey":"produce_com_status","data":[],"title":"通讯状态","field":"com_status"}],[{"title":"记录时间","field":"CreateDate","type":"datetime"},{"dataKey":"device_name","data":[],"title":"设备信息","field":"config_id","type":"select"},{"title":"当班产量","field":"turnout_all","type":"range"}]]);
const columns = ref([{field:'id',title:'ID',type:'int',width:110,readonly:true,require:true,align:'left',sort:true},
{field:'config_id',title:'设备信息',type:'int',bind:{ key:'device_name',data:[]},width:120,readonly:true,require:true,align:'left'},
{field:'program_no',title:'程序编号',type:'int',width:150,align:'left'},
{field:'com_status',title:'通讯状态',type:'short',bind:{ key:'produce_com_status',data:[]},width:120,align:'left'},
{field:'run_time',title:'运行时长',type:'int',width:110,align:'left'},
{field:'status',title:'运行状态',type:'short',bind:{ key:'produce_status',data:[]},width:110,align:'left'},
{field:'turnout_all',title:'当班产量',type:'int',sort:true,width:120,align:'left'},
{field:'turnout_1',title:'工单 1 产量',type:'int',width:120,align:'left'},
{field:'turnout_2',title:'工单 2 产量',type:'int',width:120,align:'left'},
{field:'turnout_3',title:'工单 3 产量',type:'int',width:120,align:'left'},
{field:'schedule_1',title:'工单1任务进度',type:'decimal',width:120,align:'left'},
{field:'schedule_2',title:'工单2任务进度',type:'decimal',width:120,align:'left'},
{field:'schedule_3',title:'工单3任务进度',type:'decimal',width:120,align:'left'},
{field:'yield_1',title:'工单1良品率',type:'decimal',width:120,align:'left'},
{field:'yield_2',title:'工单2良品率',type:'decimal',width:120,align:'left'},
{field:'yield_3',title:'工单3良品率',type:'decimal',width:120,align:'left'},
{field:'oee',title:'设备综合效率',type:'decimal',sort:true,width:120,align:'left'},
{field:'CreateID',title:'CreateID',type:'int',width:100,hidden:true,readonly:true,align:'left'},
{field:'Creator',title:'Creator',type:'string',width:100,hidden:true,readonly:true,align:'left'},
{field:'CreateDate',title:'记录时间',type:'datetime',width:180,readonly:true,align:'left',sort:true},
{field:'ModifyID',title:'ModifyID',type:'int',width:100,hidden:true,readonly:true,align:'left'},
{field:'Modifier',title:'Modifier',type:'string',width:100,hidden:true,readonly:true,align:'left'},
{field:'ModifyDate',title:'更新时间',type:'datetime',width:180,readonly:true,align:'left',sort:true}]);
const detail = ref({
cnName: "#detailCnName",
table: "#detailTable",
columns: [],
sortName: "",
key: ""
});
return {
table,
extend,
editFormFields,
editFormOptions,
searchFormFields,
searchFormOptions,
columns,
detail,
};
},
});
</script>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save