HKC_Blazor/MasaBlazorApp3/Pages/StockCheck.razor

318 lines
14 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@page "/stock/check"
@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">
<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">
@* <RadzenStack AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Center" Orientation="Orientation.Vertical" Style="margin-top: 220px"> *@
<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>
@* </RadzenStack> *@
</div>
</div>
<RadzenDataGrid @ref="grid"
LoadData="@LoadData"
IsLoading="@isLoading"
Count="@count"
EmptyText="@myText.NoDate"
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="@myText.Checking" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="@myText.Check" Click="@OpenDrawer" />
}
@if (status == 3)
{
<RadzenButton ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="@myText.Complete" Click="@CheckFinish" />
}
@if (status > 0 && status <= 3)
{
<RadzenButton Variant="Variant.Flat" Shade="Shade.Light" Text="@myText.Cancel" Click="@Cancel" Style="width: 120px" />
}
</RadzenRow>
</HeaderTemplate>
<Columns>
<RadzenDataGridColumn Width="70px" Title="@myText.StorageLocation" Property="ColNo"></RadzenDataGridColumn>
<RadzenDataGridColumn Title="@myText.DrugName" 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="@myText.Batch" Property="ManuNo">
<Template Context="channel">
<RadzenText TextStyle="TextStyle.Subtitle2" class="mb-0">@channel.drugManuNo?.ManuNo</RadzenText>
<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>
<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>
<RadzenText TextStyle="TextStyle.Caption">@((context as DrugManuNo)?.EffDate)</RadzenText>
</RadzenStack>
</ValueTemplate>
</RadzenDropDown>
<RadzenRequiredValidator Text="@myText.SelectBatch" 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="@myText.Inventory" 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="120px" Title="@myText.CheckQuantity" Property="CheckQuantity">
<EditTemplate Context="cs">
@if (cs.BoardType.ToString().Contains("2") || cs.BoardType.ToString().Contains("3"))
{
@cs.CheckQuantity
}
else
{
<RadzenNumeric Style="display: block" Name="CheckQuantity" @bind-Value=@cs.CheckQuantity>
<RadzenNumericRangeValidator Style="position: absolute;z-index: 9999;" Min="1" Max="100" Text="@myText.InputTips" Component="CheckQuantity" />
</RadzenNumeric>
}
</EditTemplate>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
</RadzenStack>
@code {
@inject IChannelListDao channelListDao;
@inject NavigationManager na;
@inject PortUtil PortUtil;
@inject NotificationService _message
@inject IOptions<DrawerConfig> setting;
@inject Toolbelt.Blazor.I18nText.I18nText I18nText;
private I18nText.local myText = new I18nText.local();
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));
protected override async Task OnInitializedAsync()
{
myText = await I18nText.GetTextTableAsync<I18nText.local>(this);
await base.OnInitializedAsync();
}
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;
// for (int i = 0; i < result.ChannelStocks.Count; i++)
// {
// result.ChannelStocks[i].CheckQuantity = result.ChannelStocks[i].Quantity;
// }
result.ChannelStocks.ForEach(cs => cs.CheckQuantity = cs.Quantity);
channels = result.ChannelStocks;
// Update the count
count = result.ChannelStocks.Count;
isLoading = false;
}
async Task OpenDrawer()
{
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.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)}】");
}
var b = await PortUtil.OpenDrawerStatus(this.drawerNo);
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"{drawerNo}号抽屉已经打开,请,盘点");
this.status = 2;
next();
}
else
{
_message.Notify(
new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"抽屉【{drawerNo}】打开失败,请检测硬件", Duration = 4000 }
);
logger.Info($"抽屉打开失败");
RestData();
stop();
}
}
// 检测状态
else if (this.status == 2)
{
// 查询抽屉是否为关闭状态
var b = await PortUtil.CheckDrawerStatus2(drawerNo);
// 关闭则改变状态并终止循环
if (b)
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
PortUtil.SpeakAsync($"盘点完成,请,核对,或,录入,正确的,盘点数量");
this.status = 3;
stop();
}
else
{
if (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.CheckQuantity = this.AfterQuantity[cl.ColNo - 1];// - this.BeforeQuantity[cl.ColNo - 1];
});
}
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.Contains(this.drawerNo))
{
PortUtil.AllLightOff();
}
RestData();
stop();
}
});
}
void RestData()
{
PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
this.status = 0;
this.BeforeQuantity = new int[9];
this.AfterQuantity = new int[9];
}
async Task CheckFinish()
{
if (channels.Any(cl => cl.CheckQuantity != cl.Quantity && cl.DrugId != null && cl.drugManuNo != null))
{
// 保存账册、操作记录
var b = await channelListDao.DrawerCheckFinish(channels.Where(cl => cl.CheckQuantity != cl.Quantity).ToList());
if (!b)
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"数据保存失败", Duration = 4000 });
logger.Error($"盘点保存数据库失败,数据{JsonConvert.SerializeObject(channels)}");
}
else
{
_message.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = "提示", Detail = $"盘点完成", Duration = 4000 });
logger.Info($"盘点完成");
}
}
//重置状态
this.RestData();
// 重新查询库存
await grid.Reload();
}
void Cancel()
{
RestData();
}
void SelectDrawer(int drawerNo)
{
this.drawerNo = drawerNo;
grid.Reload();
}
void OnCellClick(DataGridCellMouseEventArgs<ChannelStock> args)
{
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();
}
}