311 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			311 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
@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="无数据"
 | 
						||
    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 ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Shade="Shade.Light" Text="完成" Click="@CheckFinish" />
 | 
						||
                }
 | 
						||
                @if (status > 0 && status <= 3)
 | 
						||
                {
 | 
						||
                    <RadzenButton Variant="Variant.Flat" Shade="Shade.Light" 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>
 | 
						||
                    <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="请选择批次" 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="120px" Title="盘点数量" 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="请填写正确的取出数量" 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;
 | 
						||
    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));
 | 
						||
 | 
						||
    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();
 | 
						||
    }
 | 
						||
}
 |