<add>[important]电子标签基本完成

This commit is contained in:
葛林强 2024-05-31 13:35:41 +08:00
parent 01fd5fa294
commit fcf6acb39b
13 changed files with 392 additions and 33 deletions

View File

@ -0,0 +1,83 @@
using DataCheck;
using System.Text.Json.Serialization;
namespace WcsMain.ApiServe.Controllers.Dto.WcsDto.ElTag;
public class AddTaskInfoRequest
{
/// <summary>
/// 任务号
/// </summary>
[JsonPropertyName("taskId")]
public string? TaskId { get; set; }
/// <summary>
/// 任务组
/// </summary>
[JsonPropertyName("taskGroup")]
public string? TaskGroup { get; set; }
/// <summary>
/// 点位
/// </summary>
[DataRules]
[JsonPropertyName("location")]
public string? Location { get; set; }
/// <summary>
/// 订单号
/// </summary>
[JsonPropertyName("orderId")]
public string? OrderId { get; set; }
/// <summary>
/// 载具号
/// </summary>
[JsonPropertyName("vehicleNo")]
public string? VehicleNo { get; set; }
/// <summary>
/// 物料编号
/// </summary>
[JsonPropertyName("goodsId")]
public string? GoodsId { get; set; }
/// <summary>
/// 物料名称
/// </summary>
[JsonPropertyName("goodsName")]
public string? GoodsName { get; set; }
/// <summary>
/// 任务状态
/// </summary>
[JsonPropertyName("taskStatus")]
public int? TaskStatus { get; set; }
/// <summary>
/// 需求数量
/// </summary>
[DataRules]
[JsonPropertyName("needNum")]
public int? NeedNum { get; set; }
/// <summary>
/// 拣选数量
/// </summary>
[JsonPropertyName("pickNum")]
public int? PickNum { get; set; }
/// <summary>
/// 创建人
/// </summary>
[JsonPropertyName("createPerson")]
public string? CreatePerson { get; set; }
/// <summary>
/// 备注
/// </summary>
[JsonPropertyName("remark")]
public string? Remark { get; set; }
}

View File

@ -56,5 +56,17 @@ public class ElTagController(ElTagService elTagService) : ControllerBase
}
/// <summary>
/// 添加一个电子标签任务信息
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("addTask")]
public WcsApiResponse AddTaskInfo([FromBody] AddTaskInfoRequest request)
{
return _elTagService.AddTaskInfo(request);
}
}

View File

@ -1,16 +1,19 @@
using WcsMain.ApiServe.Controllers.Dto;
using DataCheck;
using WcsMain.ApiServe.Controllers.Dto;
using WcsMain.ApiServe.Controllers.Dto.WcsDto.ElTag;
using WcsMain.ApiServe.Factory;
using WcsMain.DataBase.Dao;
using WcsMain.DataBase.TableEntity;
using WcsMain.DataService;
using WcsMain.Enum.TaskEnum;
using WcsMain.WcsAttribute.AutoFacAttribute;
namespace WcsMain.ApiServe.Service.WcsService;
[Service]
public class ElTagService(AppElTagTaskDao tagTaskDao)
public class ElTagService(AppElTagTaskDao tagTaskDao, DataBaseData dataBaseData)
{
private readonly DataBaseData _dataBaseData = dataBaseData;
private readonly AppElTagTaskDao _tagTaskDao = tagTaskDao;
/// <summary>
@ -54,4 +57,33 @@ public class ElTagService(AppElTagTaskDao tagTaskDao)
return updateResult > 0 ? WcsApiResponseFactory.Success() : WcsApiResponseFactory.DataBaseErr();
}
/// <summary>
/// 添加电子标签任务
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public WcsApiResponse AddTaskInfo(AddTaskInfoRequest request)
{
if (!CheckData.CheckDataRules(request)) return WcsApiResponseFactory.RequestErr();
if(string.IsNullOrEmpty(request.TaskId)) request.TaskId = _dataBaseData.GetNewUUID();
if(string.IsNullOrEmpty(request.TaskGroup)) request.TaskGroup = _dataBaseData.GetNewUUID2();
var insertResult = _tagTaskDao.Insert(new AppElTagTask
{
TaskId = request.TaskId,
TaskGroup = request.TaskGroup,
Location = request.Location,
OrderId = request.OrderId,
VehicleNo = request.VehicleNo,
GoodsId = request.GoodsId,
GoodsName = request.GoodsName,
TaskStatus = (int)ElTagTaskStatusEnum.NeedLight,
NeedNum = request.NeedNum,
CreatePerson = StaticData.StaticString.WCS,
CreateTime = DateTime.Now
});
return insertResult > 0 ? WcsApiResponseFactory.Success() : WcsApiResponseFactory.DataBaseErr();
}
}

View File

@ -0,0 +1,91 @@
using CirculateTool;
using WcsMain.Common;
using WcsMain.DataBase.Dao;
using WcsMain.DataBase.TableEntity;
using WcsMain.ElTag.Atop.Entity;
using WcsMain.Enum.TaskEnum;
using WcsMain.EquipOperation.ElTag;
namespace WcsMain.Business.CirculationTask.ElTag;
/*************************
*
*
*
* *******************/
/// <summary>
/// 熄灭电子标签
/// </summary>
[Circulation]
public class OffElTag(AppElTagTaskDao tagTaskDao, AtopOperation atopOperation)
{
private readonly AppElTagTaskDao _tagTaskDao = tagTaskDao;
private readonly AtopOperation _atopOperation = atopOperation;
/// <summary>
/// 检验任务组内任务是否全部确认,若全部确认则熄灭所有标签
/// </summary>
/// <returns></returns>
[Circulation("检验任务组内任务是否全部确认", 1000)]
public bool CheckTaskIsConfirmAll()
{
/* 查询已经确认的任务的任务组 */
List<AppElTagTask>? tasks = _tagTaskDao.QueryRunningTask();
if (tasks == default)
{
ConsoleLog.Exception("【异常】查询 电子标签 任务失败,数据库连接异常");
Thread.Sleep(5000);
return true;
}
CheckTaskIsConfirmAllMethod(tasks);
return true;
}
/// <summary>
/// 检验任务组内任务是否全部确认,若全部确认则熄灭所有标签
/// </summary>
/// <returns></returns>
public void CheckTaskIsConfirmAllMethod(List<AppElTagTask> tasks)
{
if (tasks.Count == 0) return;
List<string?> taskGroups = [];
foreach (var task in tasks)
{
if (taskGroups.Contains(task.TaskGroup)) continue;
taskGroups.Add(task.TaskGroup);
}
List<AppElTagTask> offTasks = []; // 需要熄灭的任务
foreach (var taskGroup in taskGroups)
{
/* 检查其是否还有未确认的标签,若没有未确认的则关闭这些标签 */
var groupTasks = tasks.FindAll(f => f.TaskGroup == taskGroup);
bool isHaveLightingTask = groupTasks.Exists(e => e.TaskStatus == (int)ElTagTaskStatusEnum.Lighting);
if (isHaveLightingTask) continue;
// 没有点亮的标签了
ConsoleLog.Info($"电子标签任务组:{taskGroup} 全部确认,熄灭标签");
foreach (var groupTask in groupTasks)
{
var tagInfo = CommonData.AppElTags.Find(f => f.Location == groupTask.Location);
if (tagInfo == default) continue;
var sendResult = CommonTool.OprTcpClient.Send(TagSendInfo.TurnOffTag(Convert.ToByte(tagInfo.TagId)), tagInfo.ControllerDisplayName!);
if (!sendResult.Success) continue; // 没有发送电子标签成功
offTasks.Add(new AppElTagTask { TaskId = groupTask.TaskId, TaskStatus = (int)ElTagTaskStatusEnum.Off, OffTime = DateTime.Now });
}
}
if (offTasks.Count < 1) return;
_tagTaskDao.Update([.. offTasks]); // 更新状态为熄灭
}
}

View File

@ -36,7 +36,7 @@ public class ConsoleLog
}
lock (_locker)
{
Console.ForegroundColor = ConsoleColor.Magenta;
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.Write(stringBuilder.ToString());
WcsLog.Instance().WriteEventLog(stringBuilder);
}

View File

@ -1,6 +1,7 @@
using WcsMain.ApiServe.Controllers.Dto.WcsDto.ElTag;
using WcsMain.Common;
using WcsMain.DataBase.TableEntity;
using WcsMain.Enum.TaskEnum;
using WcsMain.WcsAttribute.AutoFacAttribute;
namespace WcsMain.DataBase.Dao;
@ -20,6 +21,7 @@ public class AppElTagTaskDao
{
var sqlFuc = CommonTool.DbServe.Queryable<AppElTagTask>()
.WhereIF(queryData.TaskId != default, w => w.TaskId == queryData.TaskId)
.WhereIF(queryData.TaskGroup != default, w => w.TaskGroup == queryData.TaskGroup)
.WhereIF(queryData.Location != default, w => w.Location == queryData.Location)
.WhereIF(queryData.OrderId != default, w => w.OrderId == queryData.OrderId)
.WhereIF(queryData.VehicleNo != default, w => w.VehicleNo == queryData.VehicleNo)
@ -49,13 +51,32 @@ public class AppElTagTaskDao
/// <summary>
/// 根据主键更新
/// </summary>
/// <param name="updateData"></param>
/// <param name="updateDatas"></param>
/// <returns></returns>
public int Update(AppElTagTask updateData)
public int Update(params AppElTagTask[] updateDatas)
{
try
{
var sqlFuc = CommonTool.DbServe.Updateable(updateData).IgnoreColumns(ignoreAllNullColumns: true);
var sqlFuc = CommonTool.DbServe.Updateable(updateDatas).IgnoreColumns(ignoreAllNullColumns: true);
return sqlFuc.ExecuteCommand();
}
catch (Exception ex)
{
_ = ex;
return 0;
}
}
/// <summary>
/// 添加数据
/// </summary>
/// <param name="updateDatas"></param>
/// <returns></returns>
public int Insert(params AppElTagTask[] updateDatas)
{
try
{
var sqlFuc = CommonTool.DbServe.Insertable(updateDatas);
return sqlFuc.ExecuteCommand();
}
catch (Exception ex)
@ -82,6 +103,7 @@ public class AppElTagTaskDao
var sqlFuc = CommonTool.DbServe.Queryable<AppElTagTask>()
.WhereIF(!string.IsNullOrEmpty(request.SearchStr),
w => w.TaskId!.Contains(request.SearchStr!)
|| w.TaskGroup!.Contains(request.SearchStr!)
|| w.Location!.Contains(request.SearchStr!)
|| w.VehicleNo!.Contains(request.SearchStr!)
|| w.GoodsId!.Contains(request.SearchStr!)
@ -109,8 +131,24 @@ public class AppElTagTaskDao
/// <summary>
/// 查询正在运行的电子标签任务 ---- 点亮中和已确认
/// </summary>
/// <returns></returns>
public List<AppElTagTask>? QueryRunningTask()
{
try
{
var sqlFuc = CommonTool.DbServe.Queryable<AppElTagTask>()
.Where(w => w.TaskStatus == (int)ElTagTaskStatusEnum.Lighting || w.TaskStatus == (int)ElTagTaskStatusEnum.Confirm);
return sqlFuc.ToList();
}
catch (Exception ex)
{
_ = ex;
return default;
}
}
}

View File

@ -13,6 +13,13 @@ public class AppElTagTask
[JsonPropertyName("taskId")]
public string? TaskId { get; set; }
/// <summary>
/// 任务组
/// </summary>
[SugarColumn(ColumnName = "task_group")]
[JsonPropertyName("taskGroup")]
public string? TaskGroup { get; set; }
/// <summary>
/// 点位
/// </summary>
@ -98,6 +105,13 @@ public class AppElTagTask
[JsonPropertyName("confirmTime")]
public DateTime? ConfirmTime { get; set;}
/// <summary>
/// 熄灭时间
/// </summary>
[SugarColumn(ColumnName = "off_time")]
[JsonPropertyName("offTime")]
public DateTime? OffTime { get; set; }
/// <summary>
/// 备注
/// </summary>

View File

@ -70,7 +70,7 @@ public class DataBaseData(AppSettingsDao settingsDao)
return ints.First();
}
#region UUID yyyyMMdd
private static readonly object getNewUUIDLock = new();
private string lastUUID = string.Empty;
@ -113,4 +113,59 @@ public class DataBaseData(AppSettingsDao settingsDao)
}
}
}
#endregion
#region UUID
private static readonly object getNewUUIDLock2 = new();
private string lastUUID2 = string.Empty;
private string lasTimeTick2 = DateTime.Now.ToString("yyyyMMddHHmmssfff");
private ushort sortUUID2 = 0;
/// <summary>
/// 返回一个唯一识别号 以时间戳为基础
/// </summary>
/// <returns></returns>
/// <remarks>
/// 这方法产生的ID会短一点但是单位时间内产生的数量较少
/// </remarks>
public string GetNewUUID2()
{
lock (getNewUUIDLock2)
{
while (true)
{
string? wcsId = CommonData.AppConfig.WcsId;
if (string.IsNullOrEmpty(wcsId))
{
wcsId = "0";
}
string timeTick = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
if (timeTick != lasTimeTick2)
{
lasTimeTick2 = timeTick;
sortUUID2 = 0;
}
string idNo = wcsId.PadLeft(3, '0');
string sort = sortUUID2.ToString().PadLeft(3, '0');
string newUUID = $"{timeTick}{idNo}{sort}";
sortUUID2++;
if (sortUUID2 > 900)
{
sortUUID2 = 0;
}
if (newUUID != lastUUID2)
{
lastUUID2 = newUUID;
return newUUID;
}
}
}
}
#endregion
}

View File

@ -58,6 +58,7 @@ public class BaseOprDataHandler(AppElTagBaseDao tagBaseDao, AppElTagTaskDao tagT
/// <param name="tcpServe"></param>
public void Confirm(TagReturnInfo tcpServe)
{
_atopOperation.ShowMsgOnly(tcpServe.ControllerDisplayName, tcpServe.TagId, tcpServe.Data); // 重新点亮标签,仅显示字符
/* 找出这个标签最新点亮的那条记录 */
List<AppElTagBase>? eltags = _tagBaseDao.Query(new AppElTagBase { ControllerDisplayName = tcpServe.ControllerDisplayName, TagId = tcpServe.TagId });
if(eltags == default)

View File

@ -9,7 +9,7 @@ namespace WcsMain.ElTag.Atop.Entity;
public class TagSendInfo
{
/// <summary>
/// 标签自检 ????
/// 标签自检
/// </summary>
/// <returns></returns>
public static byte[] CheckAllTag()
@ -128,6 +128,28 @@ public class TagSendInfo
return data;
}
/// <summary>
/// 使电子标签按钮按下后保持数字显示 ---- 需要手动熄灭
/// </summary>
/// <param name="tagId"></param>
/// <returns></returns>
/// <remarks>
/// 该命令会导致按钮失效
/// </remarks>
public static byte[] SetValueKeepAlive(byte tagId)
{
byte[] data = new byte[8];
data[0] = 8;
data[1] = 0;
data[2] = 0x60;
data[6] = 3;
data[7] = tagId;
return data;
}
/// <summary>
/// 展示字符串
/// </summary>
@ -147,7 +169,7 @@ public class TagSendInfo
}
if(showStr!.Length < 6)
{
showStr = showStr.PadLeft(6, '0');
showStr = showStr.PadLeft(6, ' ');
}
else
{
@ -176,18 +198,14 @@ public class TagSendInfo
/// <returns></returns>
public static byte[] ShowValue(byte tagId, string? value)
{
string showStr;
string showStr = value ?? "";
if (string.IsNullOrEmpty(value))
{
showStr = "ERR";
}
else
{
showStr = value!.ToString()!;
}
if (showStr!.Length < 6)
{
showStr = showStr.PadLeft(6, '0');
showStr = showStr.PadLeft(6, ' ');
}
else
{

View File

@ -6,8 +6,9 @@
public enum ElTagTaskStatusEnum
{
NeedLight = 0, // 待点亮
Lighting = 1, // 点亮
Lighting = 1, // 点亮
Confirm = 2, // 已确认
Off = 3, // 已熄灭
Error = 9, // 发生异常

View File

@ -21,9 +21,11 @@ public class AtopOperation
if (tagInfos == default) return;
/* 使标签闪烁一段时间,告知使用者电子标签已经连上 */
Thread.Sleep(5000);
int col = new Random().Next(0, 5);
foreach (var tagInfo in tagInfos)
{
int col = new Random().Next(0, 6);
col++;
if (col >= 5) col = 0;
CommonTool.OprTcpClient.Send(TagSendInfo.ShowTagId(Convert.ToByte(tagInfo.TagId)), tagInfo.ControllerDisplayName!);
CommonTool.OprTcpClient.Send(TagSendInfo.LedColor(Convert.ToByte(tagInfo.TagId), (LedColor)col), tagInfo.ControllerDisplayName!); // 显示颜色
CommonTool.OprTcpClient.Send(TagSendInfo.LedStatus(Convert.ToByte(tagInfo.TagId), LedStatus._0_25secblinking), tagInfo.ControllerDisplayName!); // 显示闪烁频率
@ -46,18 +48,8 @@ public class AtopOperation
/// <param name="ledStatus"></param>
/// <returns></returns>
public Exception? ShowMsg(string? controllerDisplayName, int? tagId, int? value, LedColor ledColor = LedColor.Green, LedStatus ledStatus = LedStatus._0_5secblinking)
{
if (controllerDisplayName == default || tagId == default || value == default)
{
return new Exception("必须的值为空,无法发送电子标签");
}
byte[] elTagData = TagSendInfo.ShowValue(Convert.ToByte(tagId), value);
var sendResult = CommonTool.OprTcpClient.Send(elTagData, controllerDisplayName); // 显示字符
CommonTool.OprTcpClient.Send(TagSendInfo.LedColor(Convert.ToByte(tagId), ledColor), controllerDisplayName); // 显示颜色
CommonTool.OprTcpClient.Send(TagSendInfo.LedStatus(Convert.ToByte(tagId), ledStatus), controllerDisplayName); // 显示闪烁频率
if (sendResult.Success) return default;
return sendResult.Exception;
}
=> ShowMsg(controllerDisplayName, tagId, value.ToString(), ledColor, ledStatus);
/// <summary>
@ -77,12 +69,34 @@ public class AtopOperation
}
byte[] elTagData = TagSendInfo.ShowValue(Convert.ToByte(tagId), value);
var sendResult = CommonTool.OprTcpClient.Send(elTagData, controllerDisplayName); // 显示字符
//CommonTool.OprTcpClient.Send(TagSendInfo.SetValueKeepAlive(Convert.ToByte(tagId)), controllerDisplayName); // 使标签确认后仍然显示字符
CommonTool.OprTcpClient.Send(TagSendInfo.LedColor(Convert.ToByte(tagId), ledColor), controllerDisplayName); // 显示颜色
CommonTool.OprTcpClient.Send(TagSendInfo.LedStatus(Convert.ToByte(tagId), ledStatus), controllerDisplayName); // 显示闪烁频率
if (sendResult.Success) return default;
return sendResult.Exception;
}
/// <summary>
/// 仅显示数据,不亮灯
/// </summary>
/// <param name="controllerDisplayName"></param>
/// <param name="tagId"></param>
/// <param name="value"></param>
/// <returns></returns>
public Exception? ShowMsgOnly(string? controllerDisplayName, int? tagId, string? value)
{
if (controllerDisplayName == default || tagId == default || value == default)
{
return new Exception("必须的值为空,无法发送电子标签");
}
byte[] elTagData = TagSendInfo.ShowValue(Convert.ToByte(tagId), value);
var sendResult = CommonTool.OprTcpClient.Send(elTagData, controllerDisplayName); // 显示字符
CommonTool.OprTcpClient.Send(TagSendInfo.SetValueKeepAlive(Convert.ToByte(tagId)), controllerDisplayName); // 使标签确认后仍然显示字符
CommonTool.OprTcpClient.Send(TagSendInfo.LedStatus(Convert.ToByte(tagId), LedStatus.LEDOff), controllerDisplayName); // 显示闪烁频率 -- 关闭按钮
if (sendResult.Success) return default;
return sendResult.Exception;
}
}

View File

@ -14,7 +14,7 @@
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:18990",
"applicationUrl": "http://localhost:890",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}