ReportPage.razor 8.72 KB
@page "/DataAnalysis/Report"

@using AntDesign.TableModels
@using DataAcquisition.Common.Enums
@using DataAcquisition.DataAccess
@using DataAcquisition.Models
@using DataAcquisition.ViewModels
@using LinqKit
@using Microsoft.EntityFrameworkCore
@using NPOI.XSSF.UserModel
@using System.Linq.Expressions
@inject IJSRuntime JS
@inject IDbContextFactory<DataContext> dbContextFactory;
@inject IMessageService _message

<Flex Justify="space-between" Align="center">
    <Flex Justify="flex-start" Align="center" Gap="small">
        <Select DataSource="@_selectList"
                @bind-Value="@equipmentCode"
                ValueProperty="c=>c.Value"
                LabelProperty="c=>c.Key"
                Style="width:320px">
        </Select>
        <DatePicker TValue="DateTime" Picker="@DatePickerType.Month" @bind-Value="inputDate" DisabledDate="date => date <= DateTime.Now.AddMonths(-3)|| date >DateTime.Now" Style="width:100px" ShowToday AllowClear="false" />
        <Button Type="@ButtonType.Primary" Icon="@IconType.Outline.Search" @onclick="SearchEvent">搜索</Button>
        <Button Type="@ButtonType.Default" Icon="@IconType.Outline.Redo" @onclick="ResetEvent">重置</Button>
    </Flex>
    <Flex Justify="flex-end" Align="center" Gap="small">
        <Button @onclick="ExportToExcel" Icon="@IconType.Outline.Download">导出Excel</Button>
    </Flex>
</Flex>

<Table @ref="table"
       TItem="ReportDto"
       DataSource="@dataItems"
       @bind-PageSize="_pageSize"
       @bind-SelectedRows="selectedRows"
       OnChange="OnChange"
       Size="TableSize.Small"
       RowKey="x=>x.Id">
    <Selection Key="@(context.Id.ToString())" />
    <PropertyColumn Property="c=>c.Id" Hidden />
    <PropertyColumn Title="设备编号" Property="c=>c.EquipmentCode" />
    <PropertyColumn Title="日期" Property="c=>c.Date" />
    @* <PropertyColumn Title="用气量(L)" Property="c=>c.GasConsumption" /> *@
    <PropertyColumn Title="焊丝消耗(KG)" Property="c=>c.WireConsumption" />
    <PropertyColumn Title="产量(件)" Property="c=>c.ProductionCapacity" />
    <PropertyColumn Title="焊接时间(H)" Property="c=>c.ArcingTime" />
    <PropertyColumn Title="待机时间(H)" Property="c=>c.FreeTime" />
    <PropertyColumn Title="燃弧率(%)" Property="c=>c.ArcingRate" />
</Table>

@code {

    string equipmentCode = EquipmentConst.Fanuc_1.ToString();

    DateTime inputDate = DateTime.Now;

    IEnumerable<ReportDto> selectedRows = null!;

    int _pageSize = 35;

    string _currentSelectEquipmentCode = string.Empty;
    Dictionary<string, string> _selectList = null!;
    IEnumerable<ReportDto> dataItems = null!;
    ITable table = null!;

    public void SearchEvent()
    {
        LoadData();
    }

    public void ResetEvent()
    {
        equipmentCode = EquipmentConst.Fanuc_1.ToString();
        inputDate = DateTime.Now;
    }

    protected override void OnInitialized()
    {
        _selectList = new Dictionary<string, string>
        {
            { "Fanuc", EquipmentConst.Fanuc_1.ToString() },
        };
        base.OnInitialized();
    }

    public void OnChange(QueryModel<ReportDto> queryModel)
    {
        LoadData();
    }

    private void LoadData()
    {
        try
        {
            _currentSelectEquipmentCode = equipmentCode;
            using var context = dbContextFactory.CreateDbContext();
            var (startTime, endTime) = GetRangePicker(inputDate);
            var dates = Enumerable.Range(0, (endTime - startTime).Days + 1).Select(x => startTime.AddDays(x)).ToList();
            dataItems = dates.Select(dateTime =>
            {
                var runTicks = context.EquipmentPropertyRecords.Where(p => p.EquipmentCode == equipmentCode && p.EquipmentPropertyCode == RobotProps.BootFlag.ToString() && p.CreateTime.Date == dateTime.Date).Sum(s => s.UpdateTime.Ticks - s.CreateTime.Ticks);
                var weldTicks = context.EquipmentPropertyRecords.Where(p => p.EquipmentCode == equipmentCode && p.EquipmentPropertyCode == RobotProps.WeldFlag.ToString() && p.CreateTime.Date == dateTime.Date).Sum(s => s.UpdateTime.Ticks - s.CreateTime.Ticks);
                var arcingRate = 0d;
                if (runTicks > 0)
                {
                    arcingRate = Math.Round(weldTicks * 100d / runTicks, 2);
                }

                var data = new ReportDto
                    {
                        Date = dateTime.ToLongDateString(),
                        EquipmentCode = equipmentCode,
                        WireConsumption = Math.Round(context.EquipmentPropertyRecords.Where(x => x.EquipmentCode == equipmentCode && x.EquipmentPropertyCode == RobotProps.Weld_Speed.ToString() && x.CreateTime.Date == dateTime.Date).Select(x => x.Value).AsEnumerable().Sum(Convert.ToSingle), 2),
                        ProductionCapacity = context.WorkpieceProductions.Where(x => x.EquipmentCode == equipmentCode && x.CreateTime.Date == dateTime.Date).Count(),
                        ArcingTime = Math.Round(TimeSpan.FromTicks(weldTicks).TotalHours, 2),
                        FreeTime = Math.Round(TimeSpan.FromTicks(runTicks - weldTicks).TotalHours, 2),
                        ArcingRate = arcingRate
                    };
                return data;
            }).ToList();
        }
        catch (Exception ex)
        {
            _message.Error($"加载数据异常:{ex.Message}");
        }
    }

    private Expression<Func<WorkpieceProduction, bool>> QueryExpression()
    {
        var filter = PredicateBuilder.New<WorkpieceProduction>(true);
        if (!string.IsNullOrWhiteSpace(equipmentCode))
        {
            filter = filter.And(x => x.EquipmentCode.Contains(equipmentCode));
        }
        return filter;
    }

    private async Task ExportToExcel()
    {
        try
        {
            if (dataItems == null || !dataItems.Any())
            {
                await _message.Warning($"设备{equipmentCode}数据为空!");
                return;
            }
            var stream = ExportToExcel(dataItems);
            using var streamRef = new DotNetStreamReference(stream);
            var equipmentName = _selectList.Where(x => x.Value == _currentSelectEquipmentCode).Select(x => x.Key).First();
            await JS.InvokeVoidAsync("downloadFileFromStream", $"{equipmentName}_{inputDate.ToString("Y")}.xlsx", streamRef);
        }
        catch (Exception ex)
        {
            await _message.Error(ex.Message);
        }
    }

    private (DateTime, DateTime) GetRangePicker(DateTime dateTime)
    {
        var startTime = dateTime.AddDays(1 - DateTime.Now.Day).Date;
        var endTime = dateTime.AddDays(1 - DateTime.Now.Day).Date.AddMonths(1).AddSeconds(-1);
        return (startTime, endTime);
    }

    private MemoryStream ExportToExcel(IEnumerable<ReportDto> data)
    {
        var workbook = new XSSFWorkbook();
        var sheetName = _selectList.Where(x => x.Value == equipmentCode).Select(x => x.Key).First();
        var sheet = workbook.CreateSheet(sheetName);

        // 创建表头
        var headerRow = sheet.CreateRow(0);
        // 填充表头内容
        headerRow.CreateCell(0).SetCellValue("日期");
        headerRow.CreateCell(1).SetCellValue("焊丝消耗(KG)");
        headerRow.CreateCell(2).SetCellValue("产量(件)");
        headerRow.CreateCell(3).SetCellValue("焊接时间(H)");
        headerRow.CreateCell(4).SetCellValue("待机时间(H)");
        headerRow.CreateCell(5).SetCellValue("燃弧率(%)");

        // 填充数据行
        int rowIndex = 1;
        foreach (var item in data)
        {
            var row = sheet.CreateRow(rowIndex++);
            row.CreateCell(0).SetCellValue(item.Date);
            row.CreateCell(1).SetCellValue(item.WireConsumption);
            row.CreateCell(2).SetCellValue(item.ProductionCapacity);
            row.CreateCell(3).SetCellValue(item.ArcingTime);
            row.CreateCell(4).SetCellValue(item.FreeTime);
            row.CreateCell(5).SetCellValue(item.ArcingRate);
        }
        //合计
        var lastRow = sheet.CreateRow(rowIndex++);
        lastRow.CreateCell(0).SetCellValue("合计");
        lastRow.CreateCell(1).SetCellValue($"总焊丝消耗:{Math.Round(data.Sum(x => x.WireConsumption), 2)}");
        lastRow.CreateCell(2).SetCellValue($"总产量:{data.Sum(x => x.ProductionCapacity)}");
        lastRow.CreateCell(3).SetCellValue($"总焊接时间:{Math.Round(data.Sum(x => x.ArcingTime), 2)}");
        lastRow.CreateCell(4).SetCellValue($"总待机时间:{Math.Round(data.Sum(x => x.FreeTime), 2)}");
        lastRow.CreateCell(5).SetCellValue($"平均燃弧率:{Math.Round(data.Sum(x => x.ArcingRate) / data.Count(), 2)}");

        var stream = new MemoryStream();
        workbook.Write(stream, true);
        stream.Seek(0, SeekOrigin.Begin);
        return stream;
    }
}