修改了background代码!!!!import 修改了库存日志数据库,前端修改,添加库存日志导出功能

This commit is contained in:
2025-01-20 15:55:34 +08:00
parent f781c59473
commit 8bc94c1257
11 changed files with 226 additions and 183 deletions

View File

@@ -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));
}
/// <summary>
/// 导出库存日志
/// </summary>
/// <returns></returns>
[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);
}
}
}

View File

@@ -37,6 +37,19 @@ namespace DOAN.Admin.WebApi.Controllers.PBL
return SUCCESS(response);
}
/// <summary>
/// 查询料架表列表(零件号聚合)
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("listByPartnumber")]
[ActionPermissionFilter(Permission = "storagelocation:list")]
public IActionResult QueryListByPartnumber()
{
var response = _StoragelocationService.GetPartNumberList();
return SUCCESS(response);
}
/// <summary>
/// 查询料架表详情

View File

@@ -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 = 3PgSql = 4
"ConfigId": "0", //多租户唯一标识
"IsAutoCloseConnection": true

View File

@@ -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
}
/// <summary>
/// 库存日志查询对象
/// </summary>
public class InventorylogExportDto
{
public string StartTime { get; set; }
public string EndTime { get; set; }
}
}

View File

@@ -31,7 +31,6 @@ public class StoragelocationDto
public int? PackageNum { get; set; }
/// <summary>
/// 箱子数
/// </summary>
@@ -45,3 +44,15 @@ public class StoragelocationDto
public DateTime? UpdatedTime { get; set; }
}
/// <summary>
/// 料架表零件号聚合结果
/// </summary>
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;
}

View File

@@ -11,47 +11,62 @@ namespace DOAN.Model.PBL
/// 雪花
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = false)]
[ExcelIgnore]
public string Id { get; set; }
/// <summary>
/// 料架号
/// </summary>
[SugarColumn(ColumnName = "rack_code")]
[ExcelColumn(Name = "料架号")]
public string RackCode { get; set; }
/// <summary>
/// 零件号
/// </summary>
[SugarColumn(ColumnName = "partnumber")]
[ExcelColumn(Name = "零件号")]
public string Partnumber { get; set; }
/// <summary>
/// 操作1出、2入库
/// </summary>
[ExcelColumn(Name = "操作1出库、2入库 ")]
public int? Operation { get; set; }
/// <summary>
/// 箱子数
/// </summary>
[SugarColumn(ColumnName = "package_num")]
[ExcelColumn(Name = "箱子变动数")]
public int? PackageNum { get; set; }
/// <summary>
/// 创建人
/// </summary>
[SugarColumn(ColumnName = "cREATED_BY")]
[ExcelColumn(Name = "生成来源")]
public string CreatedBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnName = "cREATED_TIME")]
[ExcelColumn(Name = "生成时间", Format = "yyyy-MM-dd HH:mm:ss")]
public DateTime? CreatedTime { get; set; }
/// <summary>
/// 更新人
/// </summary>
[SugarColumn(ColumnName = "uPDATED_BY")]
[ExcelIgnore]
public string UpdatedBy { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnName = "uPDATED_TIME")]
[ExcelIgnore]
public DateTime? UpdatedTime { get; set; }
}

View File

@@ -17,6 +17,11 @@ namespace DOAN.Service.PBL.IService
Inventorylog AddInventorylog(Inventorylog parm);
int UpdateInventorylog(Inventorylog parm);
/// <summary>
/// 导出日志信息
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<Inventorylog> ExportInventorylog(InventorylogExportDto model);
}
}

View File

@@ -16,6 +16,11 @@ namespace DOAN.Service.PBL.IService
Storagelocation AddStoragelocation(Storagelocation parm);
int UpdateStoragelocation(Storagelocation parm);
/// <summary>
/// 获取零件号库存
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
List<StoragelocationPartNumberGroupDto> GetPartNumberList();
}
}

View File

@@ -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;
}
/// <summary>
/// 导出库存日志
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<Inventorylog> 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; // 或者返回空列表或其他适当的响应
}
}
}
}

View File

@@ -65,6 +65,22 @@ namespace DOAN.Service.PBL
return Update(model, true);
}
public List<StoragelocationPartNumberGroupDto> 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;
}
/// <summary>
/// 查询导出表达式
/// </summary>
@@ -79,5 +95,7 @@ namespace DOAN.Service.PBL
return predicate;
}
}
}

View File

@@ -61,209 +61,114 @@ namespace DOAN.ServiceCore
}
/// <summary>
/// 功能:检测传感器信号,判断箱子数
/// 功能:检测传感器信号,判断箱子数并更新库存及日志
/// </summary>
/// <param name="stoppingToken"></param>
/// <param name="stoppingToken">取消令牌</param>
/// <returns></returns>
private async Task ExecuteAsync(CancellationToken stoppingToken)
{
try {
//int index = 1;
//int indexMax = await DbScoped.SugarScope.CopyNew()
// .Queryable<Storagelocation>().CountAsync();
try
{
while (!stoppingToken.IsCancellationRequested)
{
// 读取PLC I/O状态 12个数组
Byte[] getPLCValueByteArray=pLCTool.ReadAllValue("VB100",12);
//判断 每个料架每层的箱子数
byte[] plcSensorValues = pLCTool.ReadAllValue("VB100", 12);
//1. 获取所有料架层 合并的箱子 料架层翻倍
// 获取所有料架层
List<Storagelocation> storagelocationList = await DbScoped.SugarScope.CopyNew().Queryable<Storagelocation>().ToListAsync();
//2. 获取点位表
// 获取点位表
List<PlcAddressTable> pointPositionList = await DbScoped.SugarScope.CopyNew().Queryable<PlcAddressTable>().ToListAsync();
List<Storagelocation> updateStoragelocationList=new List<Storagelocation>();
List<Inventorylog> inventorylogs = new List<Inventorylog>();
if (storagelocationList.Count() > 0) {
List<Storagelocation> updateStoragelocationList = [];
List<Inventorylog> inventoryLogs = [];
foreach (Storagelocation layerItem in storagelocationList)
{
//2 获取这个料架层的点位表
List<PlcAddressTable> thisLayItemPointPositionList= pointPositionList.Where(it => it.FkStorageId == layerItem.Id).ToList();
// 获取这个料架层的点位表
List<PlcAddressTable> layerPoints = pointPositionList.Where(it => it.FkStorageId == layerItem.Id).ToList();
//3 判断这个料架层箱子的个数
if(thisLayItemPointPositionList!=null&& thisLayItemPointPositionList.Count()>0)
if (layerPoints != null && layerPoints.Count > 0)
{
// 这一层箱子数 默认最小值为1
int packNum = 1;
foreach(PlcAddressTable i in thisLayItemPointPositionList)
int currentPackageCount = 1; // 默认最小值为1
foreach (PlcAddressTable point in layerPoints)
{
int row = point.ByteNum - 100;
int col = point.BitNum - 1;
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} ");
}
// 记录日志
if(packNum> layerItem.PackageNum)
if (plcSensorValues != null)
{
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);
currentPackageCount += GetInvertedBit(plcSensorValues[row], col) ? 1 : 0;
}
else if(packNum < layerItem.PackageNum)
}
// 检查箱子数量变化并记录日志
if (currentPackageCount > 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);
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)
// 更新库存
if (updateStoragelocationList.Count > 0)
{
await DbScoped.SugarScope.CopyNew().Updateable(updateStoragelocationList).ExecuteCommandAsync();
}
//增加库存变更日志
if(inventorylogs.Count()>0)
// 插入库存变更日志
if (inventoryLogs.Count > 0)
{
await DbScoped.SugarScope.CopyNew().Insertable(inventorylogs).ExecuteCommandAsync();
await DbScoped.SugarScope.CopyNew().Insertable(inventoryLogs).ExecuteCommandAsync();
}
// 添加延迟以避免频繁查询
await Task.Delay(200, stoppingToken);
}
}
catch (OperationCanceledException)
{
Console.WriteLine("任务已取消");
}
catch (Exception ex)
{
Console.WriteLine($"DoanBackGround线程ExecuteAsync异常: {ex.Message}\n堆栈跟踪: {ex.StackTrace}");
}
}
/// <summary>
/// 更新料架位置的箱子数量并记录库存日志
/// </summary>
/// <param name="storageLocation">料架位置对象</param>
/// <param name="newPackageCount">新的箱子数量</param>
/// <param name="operation">操作类型 (1-出库, 2-入库)</param>
/// <param name="operatorName">操作员名称</param>
/// <param name="inventoryLogs">库存日志列表</param>
private void UpdateAndLog(Storagelocation storageLocation, int newPackageCount, int operation, string operatorName, List<Inventorylog> 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()
};
//List <Storagelocation> storagelocationList = await DbScoped.SugarScope.CopyNew()
//.Queryable<Storagelocation>().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;
//}
}
} catch (Exception ex) {
Console.WriteLine("DoanBackGround线程ExecuteAsync异常:" + ex.Message);
}
inventoryLogs.Add(inventoryLog);
}
public void Dispose()