From 62e3fbe37bb9fb531391fcf19ccc33adef0d6778 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Tue, 14 Oct 2025 12:32:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=92=8C=E5=A2=9E=E5=8A=A0=E9=A4=90=E9=A5=AE=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implements/MealSupplementRecordService.cs | 32 ++++---- .../Controllers/BalanceSummaryController.cs | 11 +++ .../BalanceRecordDetailPageResponse.cs | 17 +++++ .../ShiftAndBusinessPlaceAnalysisResponse.cs | 75 +++++++++++++++++++ .../Order/Services/IBalanceSummaryService.cs | 2 + .../Services/Implements/BalanceService.cs | 37 ++++----- .../Implements/BalanceSummaryService.cs | 59 +++++++++++---- .../appsettings.Development.json | 4 +- 8 files changed, 190 insertions(+), 47 deletions(-) create mode 100644 Src/Dlhis.Canteen/Order/Response/ShiftAndBusinessPlaceAnalysisResponse.cs diff --git a/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs b/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs index 79f03e25..93b7c31b 100644 --- a/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs +++ b/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs @@ -31,19 +31,7 @@ public class MealSupplementRecordService : IMealSupplementRecordService public async Task GetPageAsync(MealSupplementRecordRequest request) { - var queryable = _dbContext.Queryable() - .LeftJoin((x, ga) => x.Code == ga.Code) - .LeftJoin((x, ga, gaLeave) => gaLeave.Code == x.Code) - .WhereIF(request.Status.HasValue, x => x.Status == request.Status) - .WhereIF(request.Sync.HasValue, x => x.Sync == request.Sync) - .WhereIF(request.Workplace.IsPresent(), x => x.Workplace == request.Workplace) - .WhereIF(request.Factory.IsPresent(), x => x.Factory == request.Factory) - .WhereIF(request.DepartmentNo.IsPresent(), (x, ga, gaLeave) => ga.DepartmentNo == request.DepartmentNo || gaLeave.DepartmentNo == request.DepartmentNo) - .WhereIF(request.Werks.IsPresent(), (x, ga) => ga.Werks == request.Werks) - .WhereIF(request.DateTimePeriod.HasValue(), x => x.Date >= request.DateTimePeriod.Start && x.Date <= request.DateTimePeriod.End) - .WhereIF(request.Search.IsPresent(), (x, ga) => x.Code == request.Search || ga.Name == request.Search); - - var page = await queryable + var page = await GetBaseQueryable() .Select((x, ga, gaLeave) => new MealSupplementRecordResponse { Amount = x.Amount, @@ -87,9 +75,25 @@ public class MealSupplementRecordService : IMealSupplementRecordService return new MealSupplementRecordSummaryResponse { - Amount = await queryable.SumAsync(x => x.Amount), + Amount = await GetBaseQueryable().SumAsync(x => x.Amount), Pagination = page }; + + + ISugarQueryable GetBaseQueryable() + { + return _dbContext.Queryable() + .LeftJoin((x, ga) => x.Code == ga.Code) + .LeftJoin((x, ga, gaLeave) => gaLeave.Code == x.Code) + .WhereIF(request.Status.HasValue, x => x.Status == request.Status) + .WhereIF(request.Sync.HasValue, x => x.Sync == request.Sync) + .WhereIF(request.Workplace.IsPresent(), x => x.Workplace == request.Workplace) + .WhereIF(request.Factory.IsPresent(), x => x.Factory == request.Factory) + .WhereIF(request.DepartmentNo.IsPresent(), (x, ga, gaLeave) => ga.DepartmentNo == request.DepartmentNo || gaLeave.DepartmentNo == request.DepartmentNo) + .WhereIF(request.Werks.IsPresent(), (x, ga) => ga.Werks == request.Werks) + .WhereIF(request.DateTimePeriod.HasValue(), x => x.Date >= request.DateTimePeriod.Start && x.Date <= request.DateTimePeriod.End) + .WhereIF(request.Search.IsPresent(), (x, ga) => x.Code == request.Search || ga.Name == request.Search); + } } public async Task GetMyMealSupplementRecords(MealSupplementRecordMyRequest request) diff --git a/Src/Dlhis.Canteen/Order/Controllers/BalanceSummaryController.cs b/Src/Dlhis.Canteen/Order/Controllers/BalanceSummaryController.cs index 78876c22..37202407 100644 --- a/Src/Dlhis.Canteen/Order/Controllers/BalanceSummaryController.cs +++ b/Src/Dlhis.Canteen/Order/Controllers/BalanceSummaryController.cs @@ -82,4 +82,15 @@ public class BalanceSummaryController : ControllerBase { return await _balanceSummaryService.BalanceRecordAnalysisByFactoryAsync(request); } + + /// + /// 餐次和营业点就餐分析,统计金额和人数/人次 + /// + /// + /// + [HttpGet("shiftAndBusinessPlace/analysis/amountAndUserCountAndCostCount")] + public async Task ShiftAndBusinessPlaceAnalysisAsync([FromQuery] BalanceRecordPageDetailRequest request) + { + return await _balanceSummaryService.ShiftAndBusinessPlaceAnalysisAsync(request); + } } \ No newline at end of file diff --git a/Src/Dlhis.Canteen/Order/Response/BalanceRecordDetailPageResponse.cs b/Src/Dlhis.Canteen/Order/Response/BalanceRecordDetailPageResponse.cs index aa688ebe..5355be3a 100644 --- a/Src/Dlhis.Canteen/Order/Response/BalanceRecordDetailPageResponse.cs +++ b/Src/Dlhis.Canteen/Order/Response/BalanceRecordDetailPageResponse.cs @@ -19,6 +19,11 @@ public class BalanceRecordByBusinessPlaceResponse /// public int Total { get; set; } + /// + /// 消费次数 + /// + public int CostCount => Pagination.Total; + /// /// 分页数据 /// @@ -28,6 +33,9 @@ public class BalanceRecordByBusinessPlaceResponse [Excel("BalanceRecordDetail")] public class BalanceRecordDetailPageResponse : IExcelExportable { + /// + /// id + /// public long Id { get; set; } /// @@ -108,6 +116,15 @@ public class BalanceRecordDetailPageResponse : IExcelExportable /// public BalanceRecordSourceEnumType Source { get; set; } + // /// + // /// 消费人数 + // /// + // public int UserCount { get; set; } + // + // /// + // /// 消费次数 + // /// + // public int CostCount { get; set; } /// /// 厂区 diff --git a/Src/Dlhis.Canteen/Order/Response/ShiftAndBusinessPlaceAnalysisResponse.cs b/Src/Dlhis.Canteen/Order/Response/ShiftAndBusinessPlaceAnalysisResponse.cs new file mode 100644 index 00000000..369de506 --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Response/ShiftAndBusinessPlaceAnalysisResponse.cs @@ -0,0 +1,75 @@ +using System.Text.Json.Serialization; +using Dlhis.Entity.Canteen.Enums; +using Dlhis.ExcelHelper; +using Kurisu.AspNetCore.DataAccess.Dto; +using Kurisu.AspNetCore.Utils.Extensions; + +namespace Dlhis.Canteen.Order.Response; + +public class ShiftAndBusinessPlaceAnalysisResponse +{ + /// + /// 消费总金额 + /// + public decimal Amount { get; set; } + + /// + /// 消费人数 + /// + public int Total { get; set; } + + /// + /// 消费次数 + /// + public int CostCount => Pagination.Total; + + /// + /// 分页数据 + /// + public Pagination Pagination { get; set; } +} + +[Excel("ShiftAndBusinessPlaceAnalysis")] +public class ShiftAndBusinessPlaceAnalysisItemResponse : IExcelExportable +{ + /// + /// 消费额 + /// + [JsonIgnore] + public decimal CurrentAmount { get; set; } + + /// + /// 消费额 + /// + [Excel("消费额")] + public string Amount => Math.Abs(CurrentAmount).ToString("F2"); + + /// + /// 营业点 + /// + [Excel("营业点")] + public string BusinessPlaceName { get; set; } + + /// + /// 餐次 + /// + public ShiftEnumType? ShiftType { get; set; } + + /// + /// 餐次 + /// + [Excel("餐次")] + public string ShiftTypeDesc => ShiftType?.GetDescription(); + + /// + /// 消费人数 + /// + [Excel("消费人数")] + public int UserCount { get; set; } + + /// + /// 消费次数 + /// + [Excel("消费次数")] + public int CostCount { get; set; } +} \ No newline at end of file diff --git a/Src/Dlhis.Canteen/Order/Services/IBalanceSummaryService.cs b/Src/Dlhis.Canteen/Order/Services/IBalanceSummaryService.cs index 4bcfa7dd..3147b6fe 100644 --- a/Src/Dlhis.Canteen/Order/Services/IBalanceSummaryService.cs +++ b/Src/Dlhis.Canteen/Order/Services/IBalanceSummaryService.cs @@ -18,4 +18,6 @@ public interface IBalanceSummaryService : IScopeDependency Task BalanceRecordShiftAnalysisAmountAndCountAsync(BalanceRecordAnalysisByShiftRequest request); Task> BalanceRecordAnalysisByFactoryAsync(SummaryCommonDto request); + + Task ShiftAndBusinessPlaceAnalysisAsync(BalanceRecordPageDetailRequest request); } \ No newline at end of file diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs index 9fabbcd8..d63c8e65 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs @@ -298,16 +298,7 @@ public class BalanceService : IBalanceService //var myCodes = request.BusinessplaceCodes; - var queryable = _dbContext.Queryable() - .LeftJoin((record, department) => record.DepartmentNo == department.No) - .LeftJoin((record, department, bPlace) => record.BusinessPlaceCode == bPlace.Code) - .WhereIF(request.SearchDateTimePeriod.HasValue(), record => record.CostDate >= request.SearchDateTimePeriod.Start && record.CostDate <= request.SearchDateTimePeriod.End) - .Where(record => record.Type == BalanceRecordTypeEnumType.Out && record.Status == BalanceRecordStatusEnumType.Valid) - .Where(record => myCodes.Contains(record.BusinessPlaceCode)) - .WhereIF(request.ShiftTypes.IsPresent(), record => request.ShiftTypes.Contains(record.ShiftType)) - .WhereIF(request.Search.IsPresent(), record => record.UserCode == request.Search || record.Name == request.Search); - - var page = await queryable + var page = await GetBaseQuery() .OrderBy(record => new { CostDate = SqlFunc.Desc(record.CostDate), CostDateTime = SqlFunc.Desc(record.CostDateTime) }) .Select((record, department, bPlace) => new BalanceRecordDetailPageResponse { @@ -339,16 +330,28 @@ public class BalanceService : IBalanceService //ignore } - - var amount = await queryable.SumAsync(record => SqlFunc.Abs(record.Amount)); - var total = await queryable.Select(record => record.UserCode).Distinct().CountAsync(); + var amount = await GetBaseQuery().SumAsync(record => SqlFunc.Abs(record.Amount)); + var userCount = await GetBaseQuery().Select(record => record.UserCode).Distinct().CountAsync(); return new BalanceRecordByBusinessPlaceResponse { Amount = amount, - Total = total, + Total = userCount, Pagination = page, }; + + + ISugarQueryable GetBaseQuery() + { + return _dbContext.Queryable() + .LeftJoin((record, department) => record.DepartmentNo == department.No) + .LeftJoin((record, department, bPlace) => record.BusinessPlaceCode == bPlace.Code) + .WhereIF(request.SearchDateTimePeriod.HasValue(), record => record.CostDate >= request.SearchDateTimePeriod.Start && record.CostDate <= request.SearchDateTimePeriod.End) + .Where(record => record.Type == BalanceRecordTypeEnumType.Out && record.Status == BalanceRecordStatusEnumType.Valid) + .Where(record => myCodes.Contains(record.BusinessPlaceCode)) + .WhereIF(request.ShiftTypes.IsPresent(), record => request.ShiftTypes.Contains(record.ShiftType)) + .WhereIF(request.Search.IsPresent(), record => record.UserCode == request.Search || record.Name == request.Search); + } } @@ -362,16 +365,14 @@ public class BalanceService : IBalanceService //var myCodes = request.BusinessplaceCodes; - var queryable = _dbContext.Queryable() + var rows = await _dbContext.Queryable() .LeftJoin((record, department) => record.DepartmentNo == department.No) .LeftJoin((record, department, bPlace) => record.BusinessPlaceCode == bPlace.Code) .WhereIF(request.SearchDateTimePeriod.HasValue(), record => record.CostDate >= request.SearchDateTimePeriod.Start && record.CostDate <= request.SearchDateTimePeriod.End) .Where(record => record.Type == BalanceRecordTypeEnumType.Out && record.Status == BalanceRecordStatusEnumType.Valid) .Where(record => myCodes.Contains(record.BusinessPlaceCode)) .WhereIF(request.ShiftTypes.IsPresent(), record => request.ShiftTypes.Contains(record.ShiftType)) - .WhereIF(request.Search.IsPresent(), record => record.UserCode == request.Search || record.Name == request.Search); - - var rows = await queryable + .WhereIF(request.Search.IsPresent(), record => record.UserCode == request.Search || record.Name == request.Search) .OrderBy(record => new { CostDate = SqlFunc.Desc(record.CostDate), CostDateTime = SqlFunc.Desc(record.CostDateTime) }) .Select((record, department, bPlace) => new BalanceRecordDetailPageResponse { diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceSummaryService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceSummaryService.cs index 0282fb22..2a62c518 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceSummaryService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceSummaryService.cs @@ -12,6 +12,7 @@ using Kurisu.AspNetCore.DataAccess.Dto; using Kurisu.AspNetCore.DataAccess.Extensions; using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions; using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; +using Kurisu.AspNetCore.Utils.Extensions; using SqlSugar; namespace Dlhis.Canteen.Order.Services.Implements; @@ -34,8 +35,7 @@ public class BalanceSummaryService : IBalanceSummaryService request.BusinessPlaceCodes = new List { request.BusinessPlaceCode.Value }; } - var queryable = GetQueryable(request); - var list = await queryable.ToListAsync(); + var list = await GetQueryable(request).ToListAsync(); var sum = list.Sum(x => Math.Abs(x.Amount)); @@ -96,13 +96,11 @@ public class BalanceSummaryService : IBalanceSummaryService public async Task BalanceRecordShiftAnalysisAmountAsync(BalanceRecordAnalysisByShiftRequest request) { - var queryable = GetQueryable(request); - - var amount = await queryable.SumAsync(x => SqlFunc.Abs(x.Amount)); + var amount = await GetQueryable(request).SumAsync(x => SqlFunc.Abs(x.Amount)); var count = typeof(ShiftEnumType).GetFields(BindingFlags.Public | BindingFlags.Static).Length; - var result = await queryable.GroupBy(x => new { x.CostDate, x.ShiftType }) + var result = await GetQueryable(request).GroupBy(x => new { x.CostDate, x.ShiftType }) .Select(x => new { x.CostDate, x.ShiftType, Amount = SqlFunc.AggregateSum(SqlFunc.Abs(x.Amount)) }) .ToPageListAsync(request.PageIndex, count * request.PageSize); @@ -129,11 +127,9 @@ public class BalanceSummaryService : IBalanceSummaryService public async Task BalanceRecordShiftAnalysisAmountAndCountAsync(BalanceRecordAnalysisByShiftRequest request) { - var queryable = GetQueryable(request); + var amount = await GetQueryable(request).SumAsync(x => SqlFunc.Abs(x.Amount)); - var amount = await queryable.SumAsync(x => SqlFunc.Abs(x.Amount)); - - var result = await queryable.GroupBy(x => new { x.ShiftType }) + var result = await GetQueryable(request).GroupBy(x => new { x.ShiftType }) .Select(x => new { x.ShiftType, Amount = SqlFunc.AggregateSum(SqlFunc.Abs(x.Amount)), Count = SqlFunc.AggregateDistinctCount(x.UserCode) }) .ToListAsync(); @@ -151,9 +147,7 @@ public class BalanceSummaryService : IBalanceSummaryService public async Task> BalanceRecordAnalysisByFactoryAsync(SummaryCommonDto request) { - var queryable = GetQueryable(request); - - var page = await queryable + var page = await GetQueryable(request) .GroupBy(x => new { x.TenantId }) .Select(x => new BalanceRecordAnalysisFactoryAmountAndCountResponse { @@ -176,6 +170,45 @@ public class BalanceSummaryService : IBalanceSummaryService return page; } + + public async Task ShiftAndBusinessPlaceAnalysisAsync(BalanceRecordPageDetailRequest request) + { + var page = await QueryableShiftAndBusinessPlaceAnalysis(request) + .GroupBy((record, bPlace) => new { record.ShiftType, record.BusinessPlaceCode, bPlace.Name }) + .Select((record, bPlace) => new ShiftAndBusinessPlaceAnalysisItemResponse + { + ShiftType = record.ShiftType, + BusinessPlaceName = bPlace.Name, + UserCount = SqlFunc.AggregateDistinctCount(record.UserCode), + CostCount = SqlFunc.AggregateCount(record.Id), + CurrentAmount = SqlFunc.AggregateSum(record.Amount), + }) + .ToPageListAsync(request); + + var amount = await QueryableShiftAndBusinessPlaceAnalysis(request).SumAsync(record => SqlFunc.Abs(record.Amount)); + var userCount = await QueryableShiftAndBusinessPlaceAnalysis(request).Select(record => record.UserCode).Distinct().CountAsync(); + + return new ShiftAndBusinessPlaceAnalysisResponse + { + Amount = amount, + Total = userCount, + Pagination = page, + }; + + ISugarQueryable QueryableShiftAndBusinessPlaceAnalysis(BalanceRecordPageDetailRequest internalRequest) + { + return _dbContext.Queryable() + .LeftJoin((record, bPlace) => record.BusinessPlaceCode == bPlace.Code) + .WhereIF(internalRequest.SearchDateTimePeriod.HasValue(), record => record.CostDate >= internalRequest.SearchDateTimePeriod.Start && record.CostDate <= internalRequest.SearchDateTimePeriod.End) + .WhereIF(internalRequest.ShiftTypes.IsPresent(), record => internalRequest.ShiftTypes.Contains(record.ShiftType)) + .Where(record => record.Type == BalanceRecordTypeEnumType.Out && record.Status == BalanceRecordStatusEnumType.Valid) + .WhereIF(internalRequest.Search.IsPresent(), (record, bPlace) => bPlace.Name.Contains(internalRequest.Search)) + .Where(record => record.BusinessPlaceCode.HasValue) + ; + } + } + + //**************************************************************help method*********************************************************************** /// diff --git a/Src/Dlhis.Canteen/appsettings.Development.json b/Src/Dlhis.Canteen/appsettings.Development.json index 57cbead6..3f4e96cf 100644 --- a/Src/Dlhis.Canteen/appsettings.Development.json +++ b/Src/Dlhis.Canteen/appsettings.Development.json @@ -19,7 +19,7 @@ }, "SwaggerOptions": { "Enable": true, - "Authority": "http://localhost:5000", + "Authority": "https://park.yaens.com/oauth2", "ClientId": "98958aa485d38412", "ClientSecret": "52589e011f02fe19", "Scopes": { @@ -29,7 +29,7 @@ } }, "IdentityServerOptions": { - "Authority": "http://localhost:5000", + "Authority": "https://park.yaens.com/oauth2", "RequireHttpsMetadata": false, "Issuer": "identity.isawesome.cn", "Audience": "",