HKC_Blazor/MasaBlazorApp3/Pages/InvoiceOutDialog.razor

299 lines
13 KiB
Plaintext

@page "/invoice/out/{invoice}"
@using MasaBlazorApp3.Pojo.Config;
@using MasaBlazorApp3.Pojo.Vo;
@using MasaBlazorApp3.Util;
@using Microsoft.Extensions.Options;
@using Newtonsoft.Json;
@using log4net;
<RadzenStack Gap="1rem" Orientation="Orientation.Vertical" JustifyContent="JustifyContent.SpaceBetween" Style="height: 100%;">
<RadzenStack class="rz-p-4 rz-border-radius-1" Style="border: var(--rz-grid-cell-border)" Orientation="Orientation.Horizontal" Gap="1rem">
<RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">单据号:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(invoice?.InvoiceNo)</b></RadzenText>
<RadzenText TextStyle="TextStyle.Overline" Class="rz-mt-2 rz-my-0" Style="color: var(--rz-text-tertiary-color);">时间:</RadzenText>
<RadzenText TextStyle="TextStyle.Body1" Class="rz-text-truncate"><b>@(invoice?.InvoiceDate)</b></RadzenText>
</RadzenStack>
<RadzenStack>
<RadzenDataGrid @ref="grid" Data="@data" ExpandMode="DataGridExpandMode.Multiple"
RowRender="@RowRender"
EmptyText="无数据" AllowAlternatingRows="false">
<Template Context="di">
<RadzenDataGrid Data="@di.ChannelStocks" EmptyText="无数据" @ref="di.Grid"
CellClick="@((DataGridCellMouseEventArgs<ChannelStock> args) => OnCellClick(args, di.Grid))">
<Columns>
<RadzenDataGridColumn Title="库位" Property="DrawerNo">
<Template Context="s">
@s.DrawerNo - @s.ColNo
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Title="库存" Property="Quantity"></RadzenDataGridColumn>
@* <RadzenDataGridColumn Title="批次" Property="ManuNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="效期" Property="EffDate"></RadzenDataGridColumn> *@
<RadzenDataGridColumn Title="出库数量" Property="TakeQuantity">
<EditTemplate Context="cs">
<RadzenNumeric Style="display: block" Min="0" Max="@cs.Quantity" Name="Quantity" @bind-Value=@cs.TakeQuantity />
<RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="0" Max="@cs.Quantity" Text="请填写正确的取出数量" Component="Quantity" />
<RadzenCustomValidator Validator="@(() => di.ChannelStocks.Sum(cs2 => cs2.TakeQuantity) == di.Quantity)" Component="Quantity" Text="出库总量应等于请领数量" Style="position: absolute;z-index: 9999;" />
</EditTemplate>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</Template>
<Columns>
<RadzenDataGridColumn Property="Drug.DrugName" Title="药品" />
<RadzenDataGridColumn Property="Drug.DrugSpec" Title="规格" />
<RadzenDataGridColumn Property="Invoice.DrugManuNo" Title="批次" />
<RadzenDataGridColumn Property="Invoice.EffDate" Title="效期" />
<RadzenDataGridColumn Property="Quantity" Title="请领数量" />
<RadzenDataGridColumn Property="StockQuantity" Title="总库存" />
</Columns>
</RadzenDataGrid>
</RadzenStack>
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Center" Gap="0.5rem">
@if (status < 2)
{
<RadzenButton Click="@StartTake" Disabled="!CanTakeDrug" IsBusy="status > 0" BusyText="取药中。。。" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Text="取药" Style="width: 120px" />
}
@if (status == 2)
{
<RadzenButton Click="@TakeFinish" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Text="完成" Style="width: 120px" />
}
@if (status <= 2)
{
<RadzenButton Click="@((args) => CancelOpera())" Variant="Variant.Flat" Text="取消" Style="width: 120px" />
}
</RadzenStack>
</RadzenStack>
@code {
@inject Radzen.DialogService dialogService;
@inject IInOutInvoiceDao inOutInvoiceDao;
@inject IOptions<DrawerConfig> setting;
@inject NotificationService _message
@inject PortUtil PortUtil;
RadzenDataGrid<InvoiceVo> grid;
private readonly ILog logger = LogManager.GetLogger(typeof(InvoiceOutDialog));
[Parameter] public InOutInvoice invoice { get; set; }
private bool CanTakeDrug = true;
int status = 0;
public List<InvoiceVo> data { get; set; }
async Task StartTake()
{
if(data.Any(it => it.Quantity != it.ChannelStocks.Sum(cs => cs.TakeQuantity)))
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"请填写正确的出库数量!", Duration = 4000 }
);
} else
{
await OpenDrawer();
}
}
async Task CancelOpera()
{
status = 0;
dialogService.Close(false);
}
async Task OpenDrawer()
{
this.status = 1;
// 解析需要打开的抽屉列表
List<ChannelStock> channels = new();
for(int i = 0; i < data.Count; i++)
{
channels = channels.Concat(data[i].ChannelStocks.Where(cs => cs.TakeQuantity > 0)).ToList();
}
List<int> drawerNos = channels.GroupBy(it => it.DrawerNo).Select(it => it.Key).ToList();
// 根据抽屉类型来决定打开前是否需要查询数量
var promiseUtil = new PromiseUtil<int>();
int index = 0;
var BeforeQuantity = new int[9];
var AfterQuantity = new int[9];
await promiseUtil.taskAsyncLoop(500, 0 , async (options, next, stop) =>
{
var drawerNo = drawerNos[index];
try
{
if (this.status == 0)
{
stop();
}
// 开启抽屉
else if (this.status == 1)
{
if (options._data == 0)
{
BeforeQuantity = new int[9];
AfterQuantity = new int[9];
// 判断是否为单支抽屉
if (setting.Value.single.Contains(drawerNo))
{
byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo);
BeforeQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
logger.Info($"单支抽屉【{drawerNo}】,开抽屉前检测数量【{string.Join(",", BeforeQuantity)}】");
await PortUtil.HasLightOnByCol(drawerNo, data.Select(ot => ot.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).Select(cs => cs.ColNo)).Cast<int>().ToArray());
}
var b = await PortUtil.OpenDrawerStatus(drawerNo);
if (b)
{
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,取药");
options._data = 1;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
PortUtil.AllLightOff();
RestData();
stop();
}
}
// 检测状态
else if (options._data == 1)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatus2(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
options._data = 0;
if (setting.Value.single.Contains(drawerNo))
{
PortUtil.AllLightOff();
}
if (index == drawerNos.Count - 1)
{
PortUtil.SpeakAsync($"取药完成,请,点击完成按钮进行确认");
this.status = 2;
stop();
}
else
{
index += 1;
next();
}
}
else
{
if (setting.Value.single.Contains(drawerNo))
{
byte[] quantity = await PortUtil.CheckQuantityByDrawer(drawerNo);
AfterQuantity = quantity.Select(it => Convert.ToInt32(it)).ToArray().Skip(3).Take(9).ToArray();
logger.Info($"单支抽屉【{drawerNo}】,抽屉未关检测数量【{string.Join(",", AfterQuantity)}】");
data.ForEach(cl =>
{
cl.ChannelStocks.Where(cs => cs.DrawerNo == drawerNo).ToList().ForEach(cs =>
{
logger.Info($"单支抽屉【{drawerNo}】,应取药品数量【{cs.TakeQuantity}】,现实取数量【{BeforeQuantity[cs.ColNo - 1] - AfterQuantity[cs.ColNo - 1]}】");
});
});
}
next(); // continue iteration
}
}
}
}
catch (Exception e)
{
RestData();
logger.Info($"调拨取药发生错误,{e.Message}");
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"发生错误,{e.Message}", Duration = 4000 }
);
if (setting.Value.single.Contains(drawerNo))
{
PortUtil.AllLightOff();
}
stop();
}
});
}
void RestData()
{
this.status = 0;
}
async Task TakeFinish()
{
// 保存账册、操作记录
var b = await inOutInvoiceDao.InvoiceOutFinish(data);
if (!b)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
logger.Error($"抽屉加药保存数据库失败,数据{JsonConvert.SerializeObject(data)}");
// 关闭弹窗
dialogService.Close(false);
}
else
{
// 关闭弹窗
dialogService.Close(true);
}
//重置状态
this.RestData();
}
protected override async Task OnInitializedAsync()
{
data = await inOutInvoiceDao.getTakeInfoByInvoiceNo(invoice.InvoiceNo);
// 如果有【stockQuantity】字段说明有药品库存不足
if (data.Any(it => it.ChannelStocks == null || it.ChannelStocks.Count == 0))
{
CanTakeDrug = false;
}
base.OnInitializedAsync();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
base.OnAfterRender(firstRender);
if (firstRender)
{
await Task.Delay(15);
await grid.ExpandRows(grid.PagedView.Where(it => it.ChannelStocks.Count > 0));
}
}
void RowRender(RowRenderEventArgs<InvoiceVo> args)
{
args.Expandable = args.Data.ChannelStocks != null && args.Data.ChannelStocks.Count > 0;
}
void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args, RadzenDataGrid<ChannelStock> Grid)
{
Grid.EditRow(args.Data);
}
}