diff --git a/DOAN.Admin.WebApi/Controllers/PBL/Logging/InventorylogController.cs b/DOAN.Admin.WebApi/Controllers/PBL/Logging/InventorylogController.cs
index cae5506..379fa3d 100644
--- a/DOAN.Admin.WebApi/Controllers/PBL/Logging/InventorylogController.cs
+++ b/DOAN.Admin.WebApi/Controllers/PBL/Logging/InventorylogController.cs
@@ -3,6 +3,7 @@ using DOAN.Model.PBL.Dto;
using DOAN.Model.PBL;
using DOAN.Service.PBL.IService;
using DOAN.Admin.WebApi.Filters;
+using System.Collections.Generic;
//创建时间:2024-09-23
namespace DOAN.Admin.WebApi.Controllers.PBL
@@ -98,5 +99,21 @@ namespace DOAN.Admin.WebApi.Controllers.PBL
return ToResponse(_InventorylogService.Delete(idArr));
}
+ ///
+ /// 导出库存日志
+ ///
+ ///
+ [HttpGet("export")]
+ [AllowAnonymous]
+ [Log(Title = "库存日志", BusinessType = BusinessType.EXPORT)]
+ public IActionResult AddInventorylog([FromQuery] InventorylogExportDto parm)
+ {
+ var list = _InventorylogService.ExportInventorylog(parm);
+ // 添加调试日志
+ Console.WriteLine($"导出的库存日志数量: {list.Count}");
+ var result = ExportExcelMini(list, "Inventorylog", "库存日志");
+ return ExportExcel(result.Item2, result.Item1);
+ }
+
}
}
\ No newline at end of file
diff --git a/DOAN.Admin.WebApi/Controllers/PBL/StoragelocationController.cs b/DOAN.Admin.WebApi/Controllers/PBL/StoragelocationController.cs
index 4aa7ae7..77193e0 100644
--- a/DOAN.Admin.WebApi/Controllers/PBL/StoragelocationController.cs
+++ b/DOAN.Admin.WebApi/Controllers/PBL/StoragelocationController.cs
@@ -37,6 +37,19 @@ namespace DOAN.Admin.WebApi.Controllers.PBL
return SUCCESS(response);
}
+ ///
+ /// 查询料架表列表(零件号聚合)
+ ///
+ ///
+ ///
+ [HttpGet("listByPartnumber")]
+ [ActionPermissionFilter(Permission = "storagelocation:list")]
+ public IActionResult QueryListByPartnumber()
+ {
+ var response = _StoragelocationService.GetPartNumberList();
+ return SUCCESS(response);
+ }
+
///
/// 查询料架表详情
diff --git a/DOAN.Admin.WebApi/appsettings.Development.json b/DOAN.Admin.WebApi/appsettings.Development.json
index f32e150..1ae1546 100644
--- a/DOAN.Admin.WebApi/appsettings.Development.json
+++ b/DOAN.Admin.WebApi/appsettings.Development.json
@@ -10,8 +10,8 @@
"dbConfigs": [
{
-
- "Conn": "Data Source=10.72.80.161;User ID=root;Password=doantech123;Initial Catalog=pbl_huaxiang_v2;Port=3306",
+ "Conn": "Data Source=192.168.0.58;User ID=root;Password=123456;Initial Catalog=pbl_huaxiang;Port=3306",
+ //"Conn": "Data Source=10.72.80.161;User ID=root;Password=doantech123;Initial Catalog=pbl_huaxiang_v2;Port=3306",
"DbType": 0, //数据库类型 MySql = 0, SqlServer = 1, Oracle = 3,PgSql = 4
"ConfigId": "0", //多租户唯一标识
"IsAutoCloseConnection": true
diff --git a/DOAN.Model/PBL/Dto/InventorylogDto.cs b/DOAN.Model/PBL/Dto/InventorylogDto.cs
index ecdb8f1..855bd5c 100644
--- a/DOAN.Model/PBL/Dto/InventorylogDto.cs
+++ b/DOAN.Model/PBL/Dto/InventorylogDto.cs
@@ -7,7 +7,7 @@ namespace DOAN.Model.PBL.Dto
public class InventorylogQueryDto : PagerInfo
{
public string RackCode { get; set; }
-
+ public string Partnumber { get; set; }
public int? Operation { get; set; }
}
@@ -20,6 +20,7 @@ namespace DOAN.Model.PBL.Dto
public string Id { get; set; }
public string RackCode { get; set; }
+ public string Partnumber { get; set; }
public int? Operation { get; set; }
@@ -36,4 +37,13 @@ namespace DOAN.Model.PBL.Dto
}
+
+ ///
+ /// 库存日志查询对象
+ ///
+ public class InventorylogExportDto
+ {
+ public string StartTime { get; set; }
+ public string EndTime { get; set; }
+ }
}
\ No newline at end of file
diff --git a/DOAN.Model/PBL/Dto/StoragelocationDto.cs b/DOAN.Model/PBL/Dto/StoragelocationDto.cs
index 5be60b7..84e909f 100644
--- a/DOAN.Model/PBL/Dto/StoragelocationDto.cs
+++ b/DOAN.Model/PBL/Dto/StoragelocationDto.cs
@@ -31,7 +31,6 @@ public class StoragelocationDto
public int? PackageNum { get; set; }
-
///
/// 箱子数
///
@@ -44,4 +43,16 @@ public class StoragelocationDto
public string UpdatedBy { get; set; }
public DateTime? UpdatedTime { get; set; }
-}
\ No newline at end of file
+}
+
+///
+/// 料架表零件号聚合结果
+///
+public class StoragelocationPartNumberGroupDto
+{
+ public string RackCode { get; set; }
+ public string Partnumber { get; set; }
+ public string MirrorshellName { get; set; }
+ public string Productname { get; set; }
+ public int PackageNum { get; set; } = 0;
+}
diff --git a/DOAN.Model/PBL/Inventorylog.cs b/DOAN.Model/PBL/Inventorylog.cs
index de7c07a..a1eea9f 100644
--- a/DOAN.Model/PBL/Inventorylog.cs
+++ b/DOAN.Model/PBL/Inventorylog.cs
@@ -11,47 +11,62 @@ namespace DOAN.Model.PBL
/// 雪花
///
[SugarColumn(IsPrimaryKey = true, IsIdentity = false)]
+ [ExcelIgnore]
public string Id { get; set; }
///
/// 料架号
///
[SugarColumn(ColumnName = "rack_code")]
+ [ExcelColumn(Name = "料架号")]
public string RackCode { get; set; }
+ ///
+ /// 零件号
+ ///
+ [SugarColumn(ColumnName = "partnumber")]
+ [ExcelColumn(Name = "零件号")]
+ public string Partnumber { get; set; }
+
///
/// 操作(1出、2入库)
///
+ [ExcelColumn(Name = "操作(1出库、2入库) ")]
public int? Operation { get; set; }
///
/// 箱子数
///
[SugarColumn(ColumnName = "package_num")]
+ [ExcelColumn(Name = "箱子变动数")]
public int? PackageNum { get; set; }
///
/// 创建人
///
[SugarColumn(ColumnName = "cREATED_BY")]
+ [ExcelColumn(Name = "生成来源")]
public string CreatedBy { get; set; }
///
/// 创建时间
///
[SugarColumn(ColumnName = "cREATED_TIME")]
+ [ExcelColumn(Name = "生成时间", Format = "yyyy-MM-dd HH:mm:ss")]
public DateTime? CreatedTime { get; set; }
///
/// 更新人
///
[SugarColumn(ColumnName = "uPDATED_BY")]
+ [ExcelIgnore]
public string UpdatedBy { get; set; }
///
/// 更新时间
///
[SugarColumn(ColumnName = "uPDATED_TIME")]
+ [ExcelIgnore]
public DateTime? UpdatedTime { get; set; }
}
diff --git a/DOAN.Service/PBL/IService/IInventorylogService.cs b/DOAN.Service/PBL/IService/IInventorylogService.cs
index 6df3f4e..c254206 100644
--- a/DOAN.Service/PBL/IService/IInventorylogService.cs
+++ b/DOAN.Service/PBL/IService/IInventorylogService.cs
@@ -17,6 +17,11 @@ namespace DOAN.Service.PBL.IService
Inventorylog AddInventorylog(Inventorylog parm);
int UpdateInventorylog(Inventorylog parm);
-
+ ///
+ /// 导出日志信息
+ ///
+ ///
+ ///
+ public List ExportInventorylog(InventorylogExportDto model);
}
}
diff --git a/DOAN.Service/PBL/IService/IStoragelocationService.cs b/DOAN.Service/PBL/IService/IStoragelocationService.cs
index 97fd7b8..c362667 100644
--- a/DOAN.Service/PBL/IService/IStoragelocationService.cs
+++ b/DOAN.Service/PBL/IService/IStoragelocationService.cs
@@ -16,6 +16,11 @@ namespace DOAN.Service.PBL.IService
Storagelocation AddStoragelocation(Storagelocation parm);
int UpdateStoragelocation(Storagelocation parm);
-
+ ///
+ /// 获取零件号库存
+ ///
+ ///
+ ///
+ List GetPartNumberList();
}
}
diff --git a/DOAN.Service/PBL/InventorylogService.cs b/DOAN.Service/PBL/InventorylogService.cs
index 97fa258..2420f34 100644
--- a/DOAN.Service/PBL/InventorylogService.cs
+++ b/DOAN.Service/PBL/InventorylogService.cs
@@ -4,6 +4,8 @@ using DOAN.Model.PBL.Dto;
using DOAN.Model.PBL;
using DOAN.Repository;
using DOAN.Service.PBL.IService;
+using Aliyun.OSS;
+using System;
namespace DOAN.Service.PBL
@@ -82,5 +84,47 @@ namespace DOAN.Service.PBL
return predicate;
}
+
+ ///
+ /// 导出库存日志
+ ///
+ ///
+ ///
+ public List ExportInventorylog(InventorylogExportDto model)
+ {
+ try
+ {
+ // 将字符串类型的 StartTime 和 EndTime 转换为 DateTime 类型
+ if (!DateTime.TryParse(model.StartTime, out DateTime startTime))
+ {
+ throw new ArgumentException("开始时间格式无效。");
+ }
+
+ if (!DateTime.TryParse(model.EndTime, out DateTime endTime))
+ {
+ throw new ArgumentException("结束时间格式无效。");
+ }
+
+ // 设置开始时间为当天的开始时间(00:00:00)
+ startTime = startTime.Date;
+
+ // 设置结束时间为当天的结束时间(23:59:59)
+ endTime = endTime.Date.AddDays(1).AddTicks(-1);
+
+ // 查询符合条件的库存日志
+ var response = Queryable()
+ .Where(it => it.CreatedTime >= startTime && it.CreatedTime <= endTime)
+ .OrderBy(it => it.CreatedTime)
+ .ToList();
+
+ return response;
+ }
+ catch (Exception ex)
+ {
+ // 记录异常信息(可以使用日志框架如 NLog 或 Serilog)
+ Console.WriteLine($"导出库存日志异常: {ex.Message}\n堆栈跟踪: {ex.StackTrace}");
+ throw; // 或者返回空列表或其他适当的响应
+ }
+ }
}
}
\ No newline at end of file
diff --git a/DOAN.Service/PBL/StoragelocationService.cs b/DOAN.Service/PBL/StoragelocationService.cs
index 0545e2d..15c6f2d 100644
--- a/DOAN.Service/PBL/StoragelocationService.cs
+++ b/DOAN.Service/PBL/StoragelocationService.cs
@@ -65,6 +65,22 @@ namespace DOAN.Service.PBL
return Update(model, true);
}
+ public List GetPartNumberList()
+ {
+ var response = Queryable()
+ .GroupBy(it=>it.Partnumber)
+ .OrderBy(it=>it.RackCode)
+ .Select(it=>new StoragelocationPartNumberGroupDto()
+ {
+ RackCode = SqlFunc.AggregateMax(it.RackCode),
+ Partnumber = SqlFunc.AggregateMax( it.Partnumber),
+ PackageNum = SqlFunc.AggregateSum(it.PackageNum) ?? 0
+ })
+ .ToList();
+ return response;
+ }
+
+
///
/// 查询导出表达式
///
@@ -79,5 +95,7 @@ namespace DOAN.Service.PBL
return predicate;
}
+
+
}
}
\ No newline at end of file
diff --git a/DOAN.ServiceCore/DoanBackgroundService.cs b/DOAN.ServiceCore/DoanBackgroundService.cs
index 7d491ec..5986805 100644
--- a/DOAN.ServiceCore/DoanBackgroundService.cs
+++ b/DOAN.ServiceCore/DoanBackgroundService.cs
@@ -61,209 +61,114 @@ namespace DOAN.ServiceCore
}
///
- /// 功能:检测传感器信号,判断箱子数
+ /// 功能:检测传感器信号,判断箱子数并更新库存及日志
///
- ///
+ /// 取消令牌
///
private async Task ExecuteAsync(CancellationToken stoppingToken)
{
-
- try {
- //int index = 1;
- //int indexMax = await DbScoped.SugarScope.CopyNew()
- // .Queryable().CountAsync();
+ try
+ {
while (!stoppingToken.IsCancellationRequested)
{
+ // 读取PLC I/O状态 12个数组
+ byte[] plcSensorValues = pLCTool.ReadAllValue("VB100", 12);
- //读取PLC I/O状态 12个数组
- Byte[] getPLCValueByteArray=pLCTool.ReadAllValue("VB100",12);
- //判断 每个料架每层的箱子数
-
- //1. 获取所有料架层 合并的箱子 料架层翻倍
+ // 获取所有料架层
List storagelocationList = await DbScoped.SugarScope.CopyNew().Queryable().ToListAsync();
-
- //2. 获取点位表
+ // 获取点位表
List pointPositionList = await DbScoped.SugarScope.CopyNew().Queryable().ToListAsync();
- List updateStoragelocationList=new List();
- List inventorylogs = new List();
+ List updateStoragelocationList = [];
+ List inventoryLogs = [];
- if (storagelocationList.Count() > 0) {
+ foreach (Storagelocation layerItem in storagelocationList)
+ {
+ // 获取这个料架层的点位表
+ List layerPoints = pointPositionList.Where(it => it.FkStorageId == layerItem.Id).ToList();
- foreach (Storagelocation layerItem in storagelocationList)
+ if (layerPoints != null && layerPoints.Count > 0)
{
- //2 获取这个料架层的点位表
- List thisLayItemPointPositionList= pointPositionList.Where(it => it.FkStorageId == layerItem.Id).ToList();
+ int currentPackageCount = 1; // 默认最小值为1
- //3 判断这个料架层箱子的个数
- if(thisLayItemPointPositionList!=null&& thisLayItemPointPositionList.Count()>0)
+ foreach (PlcAddressTable point in layerPoints)
{
- // 这一层箱子数 默认最小值为1
- int packNum = 1;
- foreach(PlcAddressTable i in thisLayItemPointPositionList)
+ int row = point.ByteNum - 100;
+ int col = point.BitNum - 1;
+
+ if (plcSensorValues != null)
{
-
- int row = i.ByteNum-100;
- int col = i.BitNum - 1;
-
- // Console.WriteLine($"row={row},col={col},PLCValueByteArray[row]={getPLCValueByteArray.Length}");
- packNum= packNum+( GetInvertedBit(getPLCValueByteArray[row], col) ? 1 : 0);
- //Console.WriteLine($"row:{row}-col:{col} packNum:{packNum} ");
+ currentPackageCount += GetInvertedBit(plcSensorValues[row], col) ? 1 : 0;
}
- // 记录日志
- if(packNum> layerItem.PackageNum)
- {
- Storagelocation storagelocation = layerItem;
-
- storagelocation.PackageNum = packNum;
- storagelocation.UpdatedBy = "补料";
- storagelocation.UpdatedTime = DateTime.Now;
- updateStoragelocationList.Add(storagelocation);
+ }
-
-
- Inventorylog inventorylog = new Inventorylog();
- //入库
- inventorylog.Id= SnowFlakeSingle.Instance.NextId().ToString();
- inventorylog.RackCode = storagelocation.RackCode;
- inventorylog.Operation = 2;
- inventorylog.PackageNum = packNum- layerItem.PackageNum;
- inventorylog.CreatedBy = "补料";
- inventorylog.CreatedTime = DateTime.Now.ToLocalTime();
- inventorylogs.Add(inventorylog);
-
- }
- else if(packNum < layerItem.PackageNum)
- {
-
- Storagelocation storagelocation = layerItem;
- storagelocation.PackageNum = packNum;
- storagelocation.UpdatedBy = "出料";
- storagelocation.UpdatedTime = DateTime.Now;
- updateStoragelocationList.Add(storagelocation);
-
- //出库
- Inventorylog inventorylog = new Inventorylog();
- inventorylog.Id = SnowFlakeSingle.Instance.NextId().ToString();
- inventorylog.RackCode = storagelocation.RackCode;
- inventorylog.Operation = 1;
- inventorylog.PackageNum =layerItem.PackageNum - packNum ;
- inventorylog.CreatedBy = "出料";
- inventorylog.CreatedTime = DateTime.Now.ToLocalTime();
- inventorylogs.Add(inventorylog);
- }
-
+ // 检查箱子数量变化并记录日志
+ if (currentPackageCount > layerItem.PackageNum)
+ {
+ UpdateAndLog(layerItem, currentPackageCount, 2, "补料", inventoryLogs);
+ updateStoragelocationList.Add(layerItem);
+ }
+ else if (currentPackageCount < layerItem.PackageNum)
+ {
+ UpdateAndLog(layerItem, currentPackageCount, 1, "出料", inventoryLogs);
+ updateStoragelocationList.Add(layerItem);
}
}
-
- //修正库存
- if (updateStoragelocationList.Count() > 0)
- {
- await DbScoped.SugarScope.CopyNew().Updateable(updateStoragelocationList).ExecuteCommandAsync();
- }
-
- //增加库存变更日志
- if(inventorylogs.Count()>0)
- {
- await DbScoped.SugarScope.CopyNew().Insertable(inventorylogs).ExecuteCommandAsync();
- }
-
-
-
}
+ // 更新库存
+ if (updateStoragelocationList.Count > 0)
+ {
+ await DbScoped.SugarScope.CopyNew().Updateable(updateStoragelocationList).ExecuteCommandAsync();
+ }
+ // 插入库存变更日志
+ if (inventoryLogs.Count > 0)
+ {
+ await DbScoped.SugarScope.CopyNew().Insertable(inventoryLogs).ExecuteCommandAsync();
+ }
-
-
-
-
-
-
-
-
-
- //List storagelocationList = await DbScoped.SugarScope.CopyNew()
- //.Queryable().Where(it => it.Id == index).ToListAsync();
- //if (storagelocationList.Count > 0)
- //{
-
- // foreach (var storagelocation in storagelocationList)
- // {
-
- // //遮挡不亮 false
- // bool result = pLCTool.ReadBit(storagelocation.PlcAddress2);
- // // 写补料日志
- // Inventorylog inventorylog = new Inventorylog();
- // inventorylog.Id = SnowFlakeSingle.Instance.NextId().ToString();
- // inventorylog.RackCode = storagelocation.RackCode;
- // // 合并货架的id
- // //int[] ids = {1,2,3,4,19,20,21,22 };
- // int PackageLine = 2;
- // //if (ids.Contains(storagelocation.Id))
- // //{
- // // PackageLine = 1;
- // //}
- // if (result)
- // {
- // //缺料,需要补料
- // // 仓库库存修正
- // if (storagelocation.PackageNum > PackageLine)
- // {
- // storagelocation.PackageNum = PackageLine;
- // /*inventorylog.Operation = 1;
- // inventorylog.PackageNum = 1;
- // inventorylog.CreatedBy = "PLC";
- // inventorylog.CreatedTime = DateTime.Now.ToLocalTime();*/
- // await DbScoped.SugarScope.CopyNew().Updateable(storagelocation).ExecuteCommandAsync();
- // //await DbScoped.SugarScope.CopyNew().Insertable(inventorylog).ExecuteCommandAsync();
-
-
- // }
- // }
- // else
- // {
- // // 仓库库存修正
- // if (storagelocation.PackageNum <= PackageLine)
- // {
- // //不需要补料 补料成功
- // storagelocation.PackageNum = storagelocation.MaxCapacity;
- // inventorylog.Operation = 2;
- // inventorylog.PackageNum = storagelocation.MaxCapacity;
- // inventorylog.CreatedBy = "PLC";
- // inventorylog.CreatedTime = DateTime.Now.ToLocalTime();
- // await DbScoped.SugarScope.CopyNew().Updateable(storagelocation).ExecuteCommandAsync();
- // await DbScoped.SugarScope.CopyNew().Insertable(inventorylog).ExecuteCommandAsync();
- // }
-
- // }
- // //Console.WriteLine("永驻线程,正在读取对射传感器plc值 " + result + "地址:" + storagelocation.PlcAddress2);
-
- // }
-
-
-
-
-
- //}
-
-
-
- //// await Task.Delay(500, stoppingToken);
-
-
- //index++;
- //if (index > indexMax)
- //{
- // index = 1;
- //}
-
+ // 添加延迟以避免频繁查询
+ await Task.Delay(200, stoppingToken);
}
- } catch (Exception ex) {
- Console.WriteLine("DoanBackGround线程ExecuteAsync异常:" + ex.Message);
}
-
+ catch (OperationCanceledException)
+ {
+ Console.WriteLine("任务已取消");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"DoanBackGround线程ExecuteAsync异常: {ex.Message}\n堆栈跟踪: {ex.StackTrace}");
+ }
+ }
+
+ ///
+ /// 更新料架位置的箱子数量并记录库存日志
+ ///
+ /// 料架位置对象
+ /// 新的箱子数量
+ /// 操作类型 (1-出库, 2-入库)
+ /// 操作员名称
+ /// 库存日志列表
+ private void UpdateAndLog(Storagelocation storageLocation, int newPackageCount, int operation, string operatorName, List inventoryLogs)
+ {
+ storageLocation.PackageNum = newPackageCount;
+ storageLocation.UpdatedBy = operatorName;
+ storageLocation.UpdatedTime = DateTime.Now;
+
+ Inventorylog inventoryLog = new Inventorylog
+ {
+ Id = SnowFlakeSingle.Instance.NextId().ToString(),
+ RackCode = storageLocation.RackCode,
+ Partnumber = storageLocation.Partnumber,
+ Operation = operation,
+ PackageNum = Math.Abs((int)(newPackageCount - storageLocation.PackageNum)),
+ CreatedBy = operatorName,
+ CreatedTime = DateTime.Now.ToLocalTime()
+ };
+
+ inventoryLogs.Add(inventoryLog);
}
public void Dispose()