517 lines
23 KiB
Plaintext
517 lines
23 KiB
Plaintext
@page "/add/drawer"
|
||
@using MasaBlazorApp3.Pojo.Config;
|
||
@using MasaBlazorApp3.Util;
|
||
@using Microsoft.Extensions.Options;
|
||
@using Newtonsoft.Json;
|
||
@using log4net;
|
||
<style>
|
||
.rz-custom-header {
|
||
width: 100%;
|
||
}
|
||
</style>
|
||
<RadzenStack Orientation="Orientation.Horizontal">
|
||
<div class="row justify-content-center">
|
||
@if (DrawerNos.Count() > 8)
|
||
{
|
||
<div class="col-12 row justify-content-center align-items-center text-center" style="background: url('/images/box-16.jpg') no-repeat; background-size: 100% 100%; width: 380px; height:650px">
|
||
<div class="row justify-content-around align-items-center" style="margin-top: 220px; height: 430px;">
|
||
@foreach (int i in DrawerNos)
|
||
{
|
||
<RadzenButton class="col-5" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" />
|
||
|
||
}
|
||
</div>
|
||
</div>
|
||
}
|
||
else
|
||
{
|
||
<div class="col-12 row justify-content-center align-items-center text-center" style="background: url('/images/box.png') no-repeat; background-size: 100% 100%; width: 380px; height:650px">
|
||
<div class="row justify-content-around align-items-center" style="margin-top: 220px; height: 430px;">
|
||
@foreach (int i in DrawerNos)
|
||
{
|
||
<RadzenButton class="col-12" Click="@(() => SelectDrawer(i))" Text="@i.ToString()" Disabled="@(status > 0)" Shade="Shade.Light" Variant="@(drawerNo !=i ? Variant.Outlined : Variant.Flat)" />
|
||
|
||
}
|
||
</div>
|
||
</div>
|
||
}
|
||
</div>
|
||
<RadzenDataGrid @ref="grid"
|
||
LoadData="@LoadData"
|
||
IsLoading="@isLoading"
|
||
Count="@count"
|
||
EmptyText="无数据"
|
||
Data="@channels"
|
||
AllowColumnResize="true" AllowAlternatingRows="false"
|
||
CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args))"
|
||
AllowPaging="true" PageSize="10" PagerHorizontalAlign="HorizontalAlign.Left" ShowPagingSummary="true" PagingSummaryFormat="{0}/{1} 共{2}条数据">
|
||
<HeaderTemplate>
|
||
<RadzenRow JustifyContent="JustifyContent.End">
|
||
@if (status < 3)
|
||
{
|
||
<RadzenButton IsBusy="@(status>0)" BusyText="加药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="加药" Click="@OpenDrawer" />
|
||
}
|
||
@if (status == 3)
|
||
{
|
||
<RadzenButton Visible="@CompleteIsEnable" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="完成" Click="@AddFinish" />
|
||
}
|
||
@if (status > 0 && status <= 3)
|
||
{
|
||
<RadzenButton Visible="@CancleIsEnable" Variant="Variant.Flat" Text="取消" Click="@Cancel" Style="width: 120px" />
|
||
}
|
||
</RadzenRow>
|
||
</HeaderTemplate>
|
||
<Columns>
|
||
<RadzenDataGridColumn Width="70px" Title="库位" Property="ColNo"></RadzenDataGridColumn>
|
||
<RadzenDataGridColumn Title="药品名称" Property="Drug.DrugName">
|
||
<Template Context="channel">
|
||
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.Drug?.DrugName</RadzenText>
|
||
<RadzenText TextStyle="TextStyle.Caption">@channel.Drug?.DrugSpec</RadzenText>
|
||
</Template>
|
||
</RadzenDataGridColumn>
|
||
<RadzenDataGridColumn Title="批次" Property="ManuNo">
|
||
<Template Context="channel">
|
||
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
|
||
|
||
@if (channel.drugManuNo != null && channel.drugManuNo.EffDate.ToString().Length > 10)
|
||
{
|
||
<RadzenText TextStyle="TextStyle.Caption">
|
||
@channel.drugManuNo.EffDate.ToString().Substring(0, 10)
|
||
</RadzenText>
|
||
}
|
||
else
|
||
{
|
||
<RadzenText TextStyle="TextStyle.Caption">
|
||
@channel.drugManuNo?.EffDate
|
||
</RadzenText>
|
||
}
|
||
</Template>
|
||
<EditTemplate Context="channel">
|
||
|
||
@if (channel.Quantity == 0 && !String.IsNullOrEmpty(channel.DrugId))
|
||
{
|
||
<RadzenDropDown TValue="DrugManuNo" Name="ManuNo" @bind-Value="channel.drugManuNo" Data="@channel.Drug?.Manus" Style="width:100%; display: block;">
|
||
<Template>
|
||
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
|
||
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
|
||
{
|
||
|
||
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
|
||
}
|
||
else
|
||
{
|
||
|
||
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
|
||
}
|
||
</Template>
|
||
<ValueTemplate>
|
||
<RadzenStack Orientation="Orientation.Horizontal">
|
||
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@((context as DrugManuNo)?.ManuNo)</RadzenText>
|
||
@if ((context as DrugManuNo).EffDate != null && (context as DrugManuNo).EffDate.ToString().Length > 10)
|
||
{
|
||
|
||
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo).EffDate.ToString().Substring(0, 10))</RadzenText>
|
||
}
|
||
else
|
||
{
|
||
|
||
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
|
||
}
|
||
</RadzenStack>
|
||
</ValueTemplate>
|
||
</RadzenDropDown>
|
||
<RadzenRequiredValidator Text="请选择批次" Component="ManuNo" Popup="true" />
|
||
}
|
||
else
|
||
{
|
||
|
||
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
|
||
<RadzenText TextStyle="TextStyle.Caption">@channel.drugManuNo?.EffDate</RadzenText>
|
||
}
|
||
</EditTemplate>
|
||
</RadzenDataGridColumn>
|
||
<RadzenDataGridColumn Title="库存" Property="Quantity">
|
||
<Template Context="cs">
|
||
<RadzenButton ButtonStyle="ButtonStyle.Info" Variant="Variant.Flat" Shade="Shade.Lighter" class="m-1" Text="@cs.Quantity.ToString()" />
|
||
</Template>
|
||
</RadzenDataGridColumn>
|
||
<RadzenDataGridColumn MinWidth="100px" Title="加药数量" Property="AddQuantity">
|
||
<EditTemplate Context="cs">
|
||
@if (cs.BoardType.ToString().Contains("2") || cs.BoardType.ToString().Contains("3"))
|
||
{
|
||
@cs.AddQuantity
|
||
}
|
||
else
|
||
{
|
||
<RadzenNumeric Min="0" Style="display: block" Name="Quantity" @bind-Value=@cs.AddQuantity />
|
||
<RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Text="请填写正确的添加数量" Component="Quantity" Popup="true" />
|
||
}
|
||
</EditTemplate>
|
||
</RadzenDataGridColumn>
|
||
</Columns>
|
||
</RadzenDataGrid>
|
||
|
||
</RadzenStack>
|
||
@code {
|
||
@inject IChannelListDao channelListDao;
|
||
@inject NavigationManager na;
|
||
@inject PortUtil PortUtil;
|
||
@inject NotificationService _message
|
||
@inject IOptions<DrawerConfig> setting;
|
||
int status = 0;
|
||
int drawerNo = 1;
|
||
RadzenDataGrid<ChannelStock> grid;
|
||
private List<ChannelStock>? channels;
|
||
bool isLoading;
|
||
int count;
|
||
int[] DrawerNos = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
|
||
int[] BeforeQuantity = new int[9];
|
||
int[] AfterQuantity = new int[9];
|
||
private readonly ILog logger = LogManager.GetLogger(typeof(DrawerAdd));
|
||
|
||
// 当前操作的库位号列表
|
||
public List<int> ColNos { get; set; } = new List<int>();
|
||
int currentCol = 0;
|
||
bool CompleteIsEnable = true;
|
||
bool CancleIsEnable = true;
|
||
async Task LoadData(LoadDataArgs args)
|
||
{
|
||
isLoading = true;
|
||
|
||
var result = await channelListDao.GetChannelStockByDrawerNoWithDrawers(drawerNo);
|
||
// var result = await channelListDao.GetChannelStockByDrawerNo(drawerNo);
|
||
// Update the Data property
|
||
DrawerNos = result.DrawerArray;
|
||
channels = result.ChannelStocks;
|
||
// Update the count
|
||
count = result.ChannelStocks.Count;
|
||
|
||
|
||
isLoading = false;
|
||
}
|
||
async Task OpenDrawer()
|
||
{
|
||
PortUtil.DrawerNo = this.drawerNo;
|
||
this.status = 1;
|
||
// 根据抽屉类型来决定打开前是否需要查询数量
|
||
var promiseUtil = new PromiseUtil<object>();
|
||
await promiseUtil.taskAsyncLoop(500, null, async (data, next, stop) =>
|
||
{
|
||
try
|
||
{
|
||
if (this.status == 0)
|
||
{
|
||
stop();
|
||
}
|
||
// 开启抽屉
|
||
else if (this.status == 1)
|
||
{
|
||
// 判断是否为单支抽屉
|
||
if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo))
|
||
{
|
||
byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo);
|
||
BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
|
||
logger.Info($"单支抽屉,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】");
|
||
}
|
||
// 判断是否为称重抽屉
|
||
// if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo))
|
||
// {
|
||
// //开抽屉前先查数
|
||
// for (int i = 0; i < 9; i++)
|
||
// {
|
||
// int beforeQuantity = await PortUtil.CheckQuantityForSingle(i + 1);
|
||
// BeforeQuantity[i] = beforeQuantity;
|
||
// logger.Info($"BeforeQuantity:{i++}-{beforeQuantity}数量{string.Join(",", BeforeQuantity)}");
|
||
// }
|
||
// }
|
||
|
||
var b = await PortUtil.OpenDrawerStatus(this.drawerNo);
|
||
if (b)
|
||
{
|
||
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,加药");
|
||
this.status = 2;
|
||
PortUtil.Operate = true;
|
||
next();
|
||
}
|
||
else
|
||
{
|
||
_message.Notify(
|
||
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
|
||
);
|
||
logger.Info($"抽屉打开失败");
|
||
RestData();
|
||
PortUtil.Operate = false;
|
||
stop();
|
||
}
|
||
|
||
}
|
||
// 检测状态
|
||
else if (this.status == 2)
|
||
{
|
||
// 查询抽屉是否为关闭状态
|
||
var b = await PortUtil.CheckDrawerStatus2(drawerNo);
|
||
// 关闭则改变状态并终止循环
|
||
if (b)
|
||
{
|
||
PortUtil.SpeakAsync($"加药完成,请,核对,或,录入,正确的,添加数量");
|
||
// 判断是否为称重抽屉
|
||
if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo))
|
||
{
|
||
//关闭抽屉后获取称重稳定数量
|
||
await GetWeightQuantity();
|
||
}
|
||
this.status = 3;
|
||
PortUtil.Operate = false;
|
||
stop();
|
||
}
|
||
else
|
||
{
|
||
//药盒抽屉,开药盒
|
||
if (setting.Value.box != null && setting.Value.box.Contains(this.drawerNo))
|
||
{
|
||
if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo))
|
||
{
|
||
if (currentCol > 0)
|
||
{
|
||
//开药盒前先查数
|
||
int beforeQuantity = await PortUtil.CheckQuantityForSingle(currentCol);
|
||
BeforeQuantity[currentCol - 1] = beforeQuantity;
|
||
logger.Info($"BeforeQuantity:{currentCol}-{beforeQuantity}数量{string.Join(",", BeforeQuantity)}");
|
||
await Task.Delay(200);
|
||
ColNos.Add(currentCol);
|
||
}
|
||
}
|
||
//药盒抽屉,开药盒
|
||
if (currentCol > 0)
|
||
{
|
||
await PortUtil.OpenBoxByColNo(currentCol);
|
||
}
|
||
currentCol = 0;
|
||
}
|
||
|
||
if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo))
|
||
{
|
||
byte[] quantity = await PortUtil.CheckQuantityByDrawer(this.drawerNo);
|
||
AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
|
||
logger.Info($"单支抽屉,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】");
|
||
|
||
channels.ForEach(cl =>
|
||
{
|
||
cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1];
|
||
});
|
||
}
|
||
// 判断是否为称重抽屉
|
||
if (setting.Value.weigh != null && setting.Value.weigh.Contains(this.drawerNo))
|
||
{
|
||
//开抽屉后查数
|
||
for (int i = 0; i < ColNos.Count; i++)
|
||
{
|
||
int afterQuantity = await PortUtil.CheckQuantityForSingle(ColNos[i]);
|
||
AfterQuantity[ColNos[i]-1] = afterQuantity;
|
||
logger.Info($"AfterQuantity:{ColNos[i]}-{string.Join(",", AfterQuantity)}数量{string.Join(", ", BeforeQuantity)}");
|
||
}
|
||
channels.Where(cl => ColNos.Contains(cl.ColNo)).ToList().ForEach(cl =>
|
||
{
|
||
cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1];
|
||
});
|
||
await InvokeAsync(StateHasChanged);
|
||
}
|
||
next(); // continue iteration
|
||
}
|
||
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
logger.Info($"抽屉加药发生错误,{e.Message}");
|
||
_message.Notify(
|
||
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 }
|
||
);
|
||
if (setting.Value.single != null && setting.Value.single.Contains(this.drawerNo))
|
||
{
|
||
PortUtil.AllLightOff();
|
||
}
|
||
RestData();
|
||
stop();
|
||
}
|
||
});
|
||
}
|
||
|
||
void RestData()
|
||
{
|
||
this.status = 0;
|
||
this.BeforeQuantity = new int[9];
|
||
this.AfterQuantity = new int[9];
|
||
currentCol = 0;
|
||
ColNos.Clear();
|
||
}
|
||
//关闭抽屉后获取称重稳定数量
|
||
public async Task GetWeightQuantity()
|
||
{
|
||
List<int[]> finallyQuantity = new List<int[]>();
|
||
await new PromiseUtil<int>().taskAsyncLoop(200, 0, async (options, next, stop) =>
|
||
{
|
||
if (!PortUtil.Operate || this.status == 0)
|
||
{
|
||
stop();
|
||
}
|
||
else
|
||
{
|
||
try
|
||
{
|
||
logger.Info("关闭抽屉后获取称重稳定数量");
|
||
if (finallyQuantity.Count >= 10)
|
||
{
|
||
for (int i = 0; i < finallyQuantity.Count; i++)
|
||
{
|
||
logger.Info($"finallyQuantity{i} {string.Join(",", finallyQuantity[i])}");
|
||
}
|
||
if (AreAllArraysEqual(finallyQuantity))
|
||
{
|
||
stop();
|
||
channels.ForEach(cl =>
|
||
{
|
||
cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1];
|
||
});
|
||
CompleteIsEnable = true;
|
||
CancleIsEnable = true;
|
||
logger.Info("对比成功停止循环");
|
||
await InvokeAsync(StateHasChanged);
|
||
}
|
||
else
|
||
{
|
||
finallyQuantity.RemoveAt(0);
|
||
next();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (finallyQuantity.Count >= 9)
|
||
{
|
||
CancleIsEnable = true;
|
||
}
|
||
else
|
||
{
|
||
CancleIsEnable = false;
|
||
}
|
||
CompleteIsEnable = false;
|
||
PortUtil.DrawerNo = drawerNo;
|
||
PortUtil.ColNoLst = ColNos;
|
||
int[] quantity = await PortUtil.CheckQuantityByAddrForMulti();
|
||
AfterQuantity = quantity;
|
||
int[] Quantitys = new int[BeforeQuantity.Length];
|
||
for (int i = 0; i < BeforeQuantity.Length; i++)
|
||
{
|
||
Quantitys[i] = BeforeQuantity[i] - AfterQuantity[i];
|
||
}
|
||
finallyQuantity.Add(Quantitys);
|
||
logger.Info($"Quantity{string.Join(",", Quantitys)}");
|
||
|
||
channels.ForEach(cl =>
|
||
{
|
||
cl.AddQuantity = this.AfterQuantity[cl.ColNo - 1] - this.BeforeQuantity[cl.ColNo - 1];
|
||
});
|
||
next();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
logger.Info($"关闭抽屉后获取称重稳定数量异常{ex.Message}");
|
||
next();
|
||
}
|
||
}
|
||
});
|
||
}
|
||
public bool AreAllArraysEqual(List<int[]> arrays)
|
||
{
|
||
if (arrays == null || arrays.Count == 0) return false;
|
||
// 取第一个数组作为参照进行比较
|
||
var referenceArray = arrays[0];
|
||
// 检查列表中除了第一个数组外的所有数组是否与第一个数组相等
|
||
return arrays.Skip(1).All(array => array.SequenceEqual(referenceArray));
|
||
}
|
||
async Task AddFinish()
|
||
{
|
||
if (channels.Any(cl => cl.AddQuantity != 0 && cl.DrugId != null && cl.drugManuNo != null))
|
||
{
|
||
// 保存账册、操作记录
|
||
var b = await channelListDao.DrawerOperationFinish(channels.Where(cl => cl.AddQuantity != 0).ToList(), 1);
|
||
if (!b)
|
||
{
|
||
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
|
||
logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(channels)}");
|
||
}
|
||
else
|
||
{
|
||
// 判断是否为标签抽屉
|
||
if (setting.Value != null && setting.Value.label != null && setting.Value.label.Contains(this.drawerNo))
|
||
{
|
||
//写标签数量
|
||
channels.Where(it => it.AddQuantity > 0).ToList().ForEach(async it =>
|
||
{
|
||
await PortUtil.WriteQuantityMethod(it.Quantity + it.AddQuantity, it.DrawerNo, it.ColNo);
|
||
});
|
||
}
|
||
ColNos.Clear();
|
||
}
|
||
}
|
||
|
||
//重置状态
|
||
this.RestData();
|
||
// 重新查询库存
|
||
await grid.Reload();
|
||
}
|
||
|
||
void Cancel()
|
||
{
|
||
RestData();
|
||
}
|
||
|
||
void SelectDrawer(int drawerNo)
|
||
{
|
||
this.drawerNo = drawerNo;
|
||
grid.Reload();
|
||
}
|
||
|
||
void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args)
|
||
{
|
||
// if (args.Data.BoardType.ToString().Contains("3"))
|
||
// {
|
||
// //是药盒抽屉则点击行,打开对应行的药箱
|
||
// if (!ColNos.Contains(args.Data.ColNo))
|
||
// {
|
||
// ColNos.Add(args.Data.ColNo);
|
||
// }
|
||
// }
|
||
if (setting.Value.box.Contains(args.Data.DrawerNo) && status != 2)
|
||
{
|
||
PortUtil.SpeakAsync("请先点取药按钮打开抽屉");
|
||
}
|
||
currentCol = args.Data.ColNo;
|
||
grid.EditRow(args.Data);
|
||
}
|
||
private IDisposable? registration;
|
||
protected override void OnAfterRender(bool firstRender)
|
||
{
|
||
if (firstRender)
|
||
{
|
||
registration = na.RegisterLocationChangingHandler(OnLocationChanging);
|
||
}
|
||
}
|
||
|
||
private ValueTask OnLocationChanging(LocationChangingContext context)
|
||
{
|
||
// 操作中不可跳转页面
|
||
if (status > 0)
|
||
{
|
||
context.PreventNavigation(); //阻止导航
|
||
}
|
||
return ValueTask.CompletedTask;
|
||
}
|
||
//在生命周期函数Dispose中,移除订阅的事件,并销毁非托管资源registration===========================================
|
||
public void Dispose()
|
||
{
|
||
registration?.Dispose();
|
||
}
|
||
}
|