diff --git a/src/admin/api/Admin.Application/MultiTenancy/HostDashboard/HostDashboardAppService.cs b/src/admin/api/Admin.Application/MultiTenancy/HostDashboard/HostDashboardAppService.cs index 342dc38fac077a1157ff232616fedeba10d9768d..62a88f8016e16a0c4158c686d69a53f844f3098e 100644 --- a/src/admin/api/Admin.Application/MultiTenancy/HostDashboard/HostDashboardAppService.cs +++ b/src/admin/api/Admin.Application/MultiTenancy/HostDashboard/HostDashboardAppService.cs @@ -10,6 +10,7 @@ using Microsoft.EntityFrameworkCore; using Magicodes.Admin.Authorization; using Magicodes.Admin.MultiTenancy.HostDashboard.Dto; using Magicodes.Admin.MultiTenancy.Payments; +using Magicodes.Admin.Core.Custom.LogInfos; namespace Magicodes.Admin.MultiTenancy.HostDashboard { @@ -25,14 +26,17 @@ namespace Magicodes.Admin.MultiTenancy.HostDashboard private readonly IRepository _subscriptionPaymentRepository; private readonly IRepository _tenantRepository; private readonly IIncomeStatisticsService _incomeStatisticsService; + private readonly IRepository _transactionLogRepository; + public HostDashboardAppService(IRepository subscriptionPaymentRepository, IRepository tenantRepository, - IIncomeStatisticsService incomeStatisticsService) + IIncomeStatisticsService incomeStatisticsService, IRepository transactionLogRepository) { _subscriptionPaymentRepository = subscriptionPaymentRepository; _tenantRepository = tenantRepository; _incomeStatisticsService = incomeStatisticsService; + _transactionLogRepository = transactionLogRepository; } public async Task GetDashboardStatisticsData(GetDashboardDataInput input) @@ -43,10 +47,17 @@ namespace Magicodes.Admin.MultiTenancy.HostDashboard return new HostDashboardData { - DashboardPlaceholder1 = 125, - DashboardPlaceholder2 = 830, - NewTenantsCount = await GetTenantsCountByDate(input.StartDate, input.EndDate), - NewSubscriptionAmount = await GetNewSubscriptionAmount(input.StartDate, input.EndDate), + NewGoodsCount = await GetGoodsCountByDate(), + NewOrdersCount = await GetOrdersCountByDate(), + NewTenantsCount = await GetTenantsCountByDate(), + NewSubscriptionAmount = await GetSubscriptionAmount(), + NewGoodsratio = await GetGoodsCountByDate()!=0? await GetGoodsCountByDate(input.StartDate, input.EndDate) * 100 % await GetGoodsCountByDate():0, + NewOrdersratio = await GetOrdersCountByDate() != 0 ? await GetOrdersCountByDate(input.StartDate, input.EndDate) * 100 % await GetOrdersCountByDate() : 0, + SubscriptionAmountratio = await GetSubscriptionAmount() != 0 ? Convert.ToInt32(await GetNewSubscriptionAmount(input.StartDate, input.EndDate) * 100 % await GetSubscriptionAmount()) : 0, + NewTenantsratio =await GetTenantsCountByDate() != 0 ? await GetTenantsCountByDate(input.StartDate, input.EndDate) * 100 % await GetTenantsCountByDate() : 0, + + + IncomeStatistics = await _incomeStatisticsService.GetIncomeStatisticsData(input.StartDate, input.EndDate, input.IncomeStatisticsDateInterval), EditionStatistics = await GetEditionTenantStatisticsData(input.StartDate, input.EndDate), ExpiringTenants = await GetExpiringTenantsData(subscriptionEndDateStartUtc, subscriptionEndDateEndUtc, MaxExpiringTenantsShownCount), @@ -87,7 +98,12 @@ namespace Magicodes.Admin.MultiTenancy.HostDashboard .OrderBy(t => t.Label) .ToListAsync(); } - + /// + /// 新增交易金额 + /// + /// + /// + /// private async Task GetNewSubscriptionAmount(DateTime startDate, DateTime endDate) { return await _subscriptionPaymentRepository.GetAll() @@ -98,6 +114,24 @@ namespace Magicodes.Admin.MultiTenancy.HostDashboard .DefaultIfEmpty(0) .SumAsync(); } + /// + /// 交易总额 + /// + /// + private async Task GetSubscriptionAmount() + { + return await _subscriptionPaymentRepository.GetAll() + .Where(s => s.Status == SubscriptionPaymentStatus.Completed) + .Select(x => x.Amount) + .DefaultIfEmpty(0) + .SumAsync(); + } + /// + /// 新增租户数 + /// + /// + /// + /// private async Task GetTenantsCountByDate(DateTime startDate, DateTime endDate) { @@ -105,6 +139,144 @@ namespace Magicodes.Admin.MultiTenancy.HostDashboard .Where(t => t.CreationTime >= startDate && t.CreationTime <= endDate) .CountAsync(); } + /// + /// 总租户数 + /// + /// + private async Task GetTenantsCountByDate() + { + return await _tenantRepository.GetAll().CountAsync(); + } + /// + /// 获取新增订单数 + /// + /// + /// + /// + private async Task GetOrdersCountByDate(DateTime startDate, DateTime endDate) + { + return await _transactionLogRepository.GetAll() + .Where(t => t.CreationTime >= startDate && t.CreationTime <= endDate) + .CountAsync(); + } + /// + /// 总订单数 + /// + /// + private async Task GetOrdersCountByDate() + { + return await _transactionLogRepository.GetAll().CountAsync(); + } + + /// + /// 获取新增商品数 + /// + /// + /// + /// + private async Task GetGoodsCountByDate(DateTime startDate, DateTime endDate) + { + return await _tenantRepository.GetAll() + .Where(t => t.CreationTime >= startDate && t.CreationTime <= endDate) + .CountAsync(); + } + /// + /// 总商品数 + /// + /// + private async Task GetGoodsCountByDate() + { + return await _tenantRepository.GetAll().CountAsync(); + } + + /// + /// 获取待办事项 + /// + /// + public async Task GetPendsData() + { + GetPendsOutput getPendsOutput = new GetPendsOutput + { + Consult = 10, + Delivery =2, + Obligation = 598, + Rejectedgoods = 25, + Stock = 3, + }; + + return getPendsOutput; + } + + /// + /// 获取热销商品 + /// + /// + public async Task> GetHotGoodsData(DateTime startDate, DateTime endDate) + { + List getHotGoodsOutputs = new List(); + GetHotGoodsOutput GetHotGoodsOutput1 = new GetHotGoodsOutput() { + goodname="加多宝", + goodtype="饮料", + sales=520943, + }; + + GetHotGoodsOutput GetHotGoodsOutput2 = new GetHotGoodsOutput() + { + goodname = "韦德超音速粉色球鞋", + goodtype = "服饰", + sales = 20653, + }; + + GetHotGoodsOutput GetHotGoodsOutput3 = new GetHotGoodsOutput() + { + goodname = "韩版简约手链", + goodtype = "首饰", + sales = 93601, + }; + + GetHotGoodsOutput GetHotGoodsOutput4 = new GetHotGoodsOutput() + { + goodname = "小茗同学", + goodtype = "饮料", + sales = 867080, + }; + + GetHotGoodsOutput GetHotGoodsOutput5 = new GetHotGoodsOutput() + { + goodname = "oppo find5", + goodtype = "电子产品", + sales = 90825, + }; + + getHotGoodsOutputs.Add(GetHotGoodsOutput1); + getHotGoodsOutputs.Add(GetHotGoodsOutput2); + getHotGoodsOutputs.Add(GetHotGoodsOutput3); + getHotGoodsOutputs.Add(GetHotGoodsOutput4); + getHotGoodsOutputs.Add(GetHotGoodsOutput5); + + getHotGoodsOutputs.OrderBy(p=>p.sales); + return getHotGoodsOutputs; + } + + /// + /// 获取系统动态 + /// + /// + private async Task> GetDynamiclistData() + { + List getDynamiclistOutputs = new List(); + GetDynamiclistOutput getDynamiclistOutput1 = new GetDynamiclistOutput + { + Context="增加新用户流星", + Days="12", + Mothdate="2018/07", + + }; + return null; + + } + + private async Task> GetExpiringTenantsData(DateTime subscriptionEndDateStartUtc, DateTime subscriptionEndDateEndUtc, int? maxExpiringTenantsShownCount = null) { diff --git a/src/admin/api/Admin.Application/MultiTenancy/HostDashboard/IncomeStatisticsReporter.cs b/src/admin/api/Admin.Application/MultiTenancy/HostDashboard/IncomeStatisticsReporter.cs index 2c29426535d9a7d3e458047f44451a0a8b4b0d98..862c2bd355025c2e7d0c58772831f8199d3436fc 100644 --- a/src/admin/api/Admin.Application/MultiTenancy/HostDashboard/IncomeStatisticsReporter.cs +++ b/src/admin/api/Admin.Application/MultiTenancy/HostDashboard/IncomeStatisticsReporter.cs @@ -7,50 +7,32 @@ using Abp.Domain.Repositories; using Microsoft.EntityFrameworkCore; using Magicodes.Admin.MultiTenancy.HostDashboard.Dto; using Magicodes.Admin.MultiTenancy.Payments; +using Magicodes.Admin.Core.Custom.LogInfos; namespace Magicodes.Admin.MultiTenancy.HostDashboard { public class IncomeStatisticsService : AdminDomainServiceBase, IIncomeStatisticsService { private readonly IRepository _subscriptionPaymentRepository; + private readonly IRepository _tenantRepository; + private readonly IRepository _transactionLogRepository; - public IncomeStatisticsService(IRepository subscriptionPaymentRepository) - { - _subscriptionPaymentRepository = subscriptionPaymentRepository; - } - - private async Task> GetDailyIncomeStatisticsData(DateTime startDate, DateTime endDate) - { - var dailyRecords = await _subscriptionPaymentRepository.GetAll() - .Where(s => s.CreationTime >= startDate && - s.CreationTime <= endDate && - s.Status == SubscriptionPaymentStatus.Completed) - .GroupBy(s => new DateTime(s.CreationTime.Year, s.CreationTime.Month, s.CreationTime.Day)) - .Select(s => new IncomeStastistic - { - Date = s.First().CreationTime.Date, - Amount = s.Sum(c => c.Amount) - }) - .ToListAsync(); - - FillGapsInDailyIncomeStatistics(dailyRecords, startDate, endDate); - return dailyRecords.OrderBy(s => s.Date).ToList(); - } - private static void FillGapsInDailyIncomeStatistics(ICollection dailyRecords, DateTime startDate, DateTime endDate) + public IncomeStatisticsService(IRepository subscriptionPaymentRepository, + IRepository tenantRepository,IRepository transactionLogRepository) { - var currentDay = startDate; - while (currentDay <= endDate) - { - if (dailyRecords.All(d => d.Date != currentDay.Date)) - { - dailyRecords.Add(new IncomeStastistic(currentDay)); - } - - currentDay = currentDay.AddDays(1); - } + _subscriptionPaymentRepository = subscriptionPaymentRepository; + _tenantRepository = tenantRepository; + _transactionLogRepository = transactionLogRepository; } + /// + /// 获取图表数据 + /// + /// + /// + /// + /// public async Task> GetIncomeStatisticsData(DateTime startDate, DateTime endDate, ChartDateInterval dateInterval) { @@ -58,14 +40,14 @@ namespace Magicodes.Admin.MultiTenancy.HostDashboard switch (dateInterval) { - case ChartDateInterval.Daily: - incomeStastistics = await GetDailyIncomeStatisticsData(startDate, endDate); + case ChartDateInterval.Transaction: + incomeStastistics = await GetTransactionIncomeStatisticsData(startDate, endDate); break; - case ChartDateInterval.Weekly: - incomeStastistics = await GetWeeklyIncomeStatisticsData(startDate, endDate); + case ChartDateInterval.Consumer: + incomeStastistics = await GetConsumerIncomeStatisticsData(startDate, endDate); break; - case ChartDateInterval.Monthly: - incomeStastistics = await GetMonthlyIncomeStatisticsData(startDate, endDate); + case ChartDateInterval.Order: + incomeStastistics = await GetOrderIncomeStatisticsData(startDate, endDate); break; default: throw new ArgumentOutOfRangeException(nameof(dateInterval), dateInterval, null); @@ -79,64 +61,91 @@ namespace Magicodes.Admin.MultiTenancy.HostDashboard return incomeStastistics.OrderBy(i => i.Date).ToList(); } - private async Task> GetWeeklyIncomeStatisticsData(DateTime startDate, DateTime endDate) - { - var dailyRecords = await GetDailyIncomeStatisticsData(startDate, endDate); - var firstDayOfWeek = DateTimeFormatInfo.CurrentInfo == null - ? DayOfWeek.Sunday - : DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek; - - var incomeStastistics = new List(); - decimal weeklyAmount = 0; - var weekStart = dailyRecords.First().Date; - var isFirstWeek = weekStart.DayOfWeek == firstDayOfWeek; + /// + /// 获取交易额统计 + /// + /// + /// + /// + public async Task> GetTransactionIncomeStatisticsData(DateTime startDate, DateTime endDate){ - dailyRecords.ForEach(dailyRecord => + List incomeStastisticlist = new List(); + for (int i = 0; i <= endDate.Day - startDate.Day; i++) { - if (dailyRecord.Date.DayOfWeek == firstDayOfWeek) + IncomeStastistic incomeStastistic = new IncomeStastistic { - if (!isFirstWeek) - { - incomeStastistics.Add(new IncomeStastistic(weekStart, weeklyAmount)); - } - - isFirstWeek = false; - weekStart = dailyRecord.Date; - weeklyAmount = 0; - } - - weeklyAmount += dailyRecord.Amount; - }); - - incomeStastistics.Add(new IncomeStastistic(weekStart, weeklyAmount)); - return incomeStastistics; + Amount = await _subscriptionPaymentRepository.GetAll() + .Where(p => p.CreationTime == startDate.AddDays(i)) + .Select(t => t.Amount) + .SumAsync(), + + Date = startDate.AddDays(i), + }; + + incomeStastisticlist.Add(incomeStastistic); + + } + + + return incomeStastisticlist; } - private async Task> GetMonthlyIncomeStatisticsData(DateTime startDate, DateTime endDate) + /// + /// 获取用户统计 + /// + /// + /// + /// + public async Task> GetConsumerIncomeStatisticsData(DateTime startDate, DateTime endDate) { - var dailyRecords = await GetDailyIncomeStatisticsData(startDate, endDate); - var query = dailyRecords.GroupBy(d => new - { - d.Date.Year, - d.Date.Month - }) - .Select(grouping => new IncomeStastistic + List incomeStastisticlist = new List(); + for (int i = 0; i <= endDate.Day - startDate.Day; i++) { - Date = FindMonthlyDate(startDate, grouping.Key.Year, grouping.Key.Month), - Amount = grouping.DefaultIfEmpty().Sum(x => x.Amount) - }); + IncomeStastistic incomeStastistic = new IncomeStastistic + { + Amount = await _tenantRepository.GetAll() + .Where(p => p.CreationTime == startDate.AddDays(i)) + .CountAsync(), + + Date = startDate.AddDays(i), + }; + + incomeStastisticlist.Add(incomeStastistic); + } + - return query.ToList(); + return incomeStastisticlist; + } - private static DateTime FindMonthlyDate(DateTime startDate, int groupYear, int groupMonth) + /// + /// 获取订单统计 + /// + /// + /// + /// + public async Task> GetOrderIncomeStatisticsData(DateTime startDate, DateTime endDate) { - if (groupYear == startDate.Year && groupMonth == startDate.Month) + List incomeStastisticlist = new List(); + for (int i = 0; i <= endDate.Day - startDate.Day; i++) { - return new DateTime(groupYear, groupMonth, startDate.Day); + IncomeStastistic incomeStastistic = new IncomeStastistic + { + Amount = await _transactionLogRepository.GetAll() + .Where(p=>p.CreationTime==startDate.AddDays(i)) + .CountAsync(), + + Date = startDate.AddDays(i), + }; + + incomeStastisticlist.Add(incomeStastistic); } - return new DateTime(groupYear, groupMonth, 1); + + return incomeStastisticlist; } + + + } } \ No newline at end of file diff --git a/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.html b/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.html index e0a815c8f785d2eecf1bdc362ff635ad11620abc..7bb70a5cebf438d7570d132100b553691c897b48 100644 --- a/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.html +++ b/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.html @@ -31,117 +31,145 @@
-
+
+
+ 数据总计 +
-
-

- {{l("NewSubscriptionAmount")}} -

-
- - {{("Subscriptions")}} - - - $ - {{hostDashboardData != null ? hostDashboardData.newSubscriptionAmount : "..."}} - - -
-
-
-
- -
- {{selectedDateRange.startDate.format('L')}} - {{selectedDateRange.endDate.format('L')}} -
-
- - + -
-
-
-
-
+

{{l("NewTenants")}}


- - {{l("Tenants")}} - - - {{hostDashboardData != null ? hostDashboardData.newTenantsCount : "..."}} - -
-
-
-
- -
- {{selectedDateRange.startDate.format('L')}} - {{selectedDateRange.endDate.format('L')}} -
-
+

{{hostDashboardData != null ? hostDashboardData.newTenantsCount : "..."}}

+
-
-
+
-
+

- {{l("DashboardSampleStatistics")}} 1 + {{l("Orders")}}


- - {{l("DashboardSampleStatistics")}} - - - {{hostDashboardData != null ? hostDashboardData.dashboardPlaceholder1 : "..."}} - -
-
-
-
- - {{l("DashboardSampleStatisticsHelpText")}} - - - 45% - +

{{hostDashboardData != null ? hostDashboardData.newOrdersCount : "..."}}

+
-
-
-
-
-
+

- {{l("DashboardSampleStatistics")}} 2 + {{l("Goods")}}


- - {{l("DashboardSampleStatistics")}} - - - {{hostDashboardData != null ? hostDashboardData.dashboardPlaceholder2 : "..."}} - -
-
-
-
- - {{l("DashboardSampleStatisticsHelpText")}} - - - 65% - +

{{hostDashboardData != null ? hostDashboardData.newGoodsCount: "..."}}

+
+
+ +
+
+
+ 代办事项 +
+
+
    +
  • + +
    + {{l("Delivery")}} +
    +
    + {{pends!= null ? pends.delivery : "0"}} +
    +
  • +
  • + +
    + {{l("Obligation")}} +
    +
    + {{pends!= null ? pends.obligation : "0"}} +
    +
  • +
  • + +
    + {{l("Rejectedgoods")}} +
    +
    + {{pends!= null ? pends.rejectedgoods : "0"}} +
    +
  • + +
+
+ +
+
    +
  • + +
    + {{l("Stock")}} +
    +
    + {{pends!= null ? pends.stock : "0"}} +
    +
  • +
  • + +
    + {{l("Consult")}} +
    +
    + {{pends!= null ? pends.consult : "0"}} +
    +
  • +
  • + +
  • +
+
+ +
+
+
+
+ 版本信息
+ + + + + + + + + + + + + + + + + +
当前版本1.0.0历史版本
包名ceshi.apk
适用系统Android
下载链接www.baidu
+
-
+
@@ -159,194 +187,215 @@
-
+

{{charttitle}}

-
+
-
+
{{l("NoData")}}
+
+ +
-
+

- - {{l("EditionStatistics")}} - - - {{selectedDateRange.startDate.format('L')}} - {{selectedDateRange.endDate.format('L')}} - - + + 效果报告

+ +
+ +
+
+ {{selectedDateRange.startDate.format('L')}} - {{selectedDateRange.endDate.format('L')}}
-
-
-
- {{l("NoData")}} +
+
+

+ 新增交易额总占比 +

+
+

+ {{hostDashboardData != null ? hostDashboardData.subscriptionAmountratio: "0"}}% +

+
+
+
+
+
+ +
-
-
-
-
-
-
-
-
-
-
-

- - {{l("SubscriptionExpiringTenants")}}
- - - {{l("ExpiringTenantsHelpText", hostDashboardData.subscriptionEndAlertDayCount, hostDashboardData.maxExpiringTenantsShownCount)}} - - -

+
+
+

新增租户总占比

+
+ +

+ {{hostDashboardData != null ? hostDashboardData.newTenantsratio: "0"}}% +

+
+
+
+
+
+
-
-
-
-
- - - - {{l('TenantName')}} - {{l('RemainingDay')}} - - - - - - {{l('TenantName')}} - {{record.tenantName}} - - - {{l('RemainingDay')}} - {{record.remainingDayCount}} - - - - -
- {{l('NoData')}} +
+
+

新增订单总占比

+ +
+ +

+ {{hostDashboardData != null ? hostDashboardData.newOrdersratio: "0"}}% +

+
+
+
+
+ +
-
-
-
+
+ +
+ +
+

- - {{l("RecentTenants")}}
- - - {{l("RecentTenantsHelpText", hostDashboardData.recentTenantsDayCount, hostDashboardData.maxRecentTenantsShownCount)}} - - + + 热销商品

+ +
+
+
-
-
- - - - {{l('TenantName')}} - {{l('CreationTime')}} - - - - - - {{l('TenantName')}} - {{record.name}} - - - {{l('CreationTime')}} - {{ record.creationTime | momentFormat:'L LT'}} - - - - -
- {{l('NoData')}} -
-
-
- + + + + 商品名称 + 分类 + 销量 + + + + + {{hotGoods.goodname}} + {{hotGoods.goodtype}} + {{hotGoods.sales}} + + +
+
+
+
+
+
+

+ + 系统动态 +

+ + +
+ +
+
+
+
    +
  • +
    +
    20
    +
    2018/07
    +
    +
    +

    这是一条动态

    +

    这是一条动态

    +
    +
  • +
  • +
    +
    20
    +
    2018/07
    +
    +
    +

    这是一条动态

    +

    这是一条动态

    + +
    +
  • +
  • +
    +
    20
    +
    2018/07
    +
    +
    +

    这是一条动态

    +

    这是一条动态

    +
    +
  • + +
+
+
+
-
-
-
+
\ No newline at end of file diff --git a/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.less b/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.less index fc90f2441003cbaf90b6ee9a0f397338cd3bd66e..7656e8a9f80954eb4b22a9f7d0dd9aec114ec281 100644 --- a/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.less +++ b/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.less @@ -71,4 +71,145 @@ .portlet > .portlet-title > .caption > .caption-helper { font-size: 11px; } + .m-widget24 .m-widget24__item .progress{ + margin-top: 0!important + } + .sbox{ + width: 46%; + float: left; + background-color: #f8f8f8; + margin-top: 10px; + margin-left: 12px; + } + .layui-card-header{ + height: 42px; + line-height: 42px; + padding: 0 15px; + border-bottom: 1px solid #f6f6f6; + color: #333; + border-radius: 2px 2px 0 0; + font-size: 14px; + } + .fcol{ + color: #009688; + font-size: 20px; + margin: 0 25px; + } + .space{ + padding-bottom: 10px; + } + table { + width: 100%; + background-color: #fff; + color: #666; + border-collapse: collapse; + border-spacing: 0; + } + th,td{ + position: relative; + padding: 9px 15px; + min-height: 20px; + line-height: 20px; + font-size: 14px; + border-width: 1px; + border-style: solid; + border-color: #e6e6e6; + } + .versions{ + margin-left: 15px; + } + .box{ + display: flex; + justify-content: space-between; + padding: 0; + margin: 5px 0; + } + .item{ + cursor: pointer; + float: left; + text-align: center; + list-style: none; + width: 33.3%; + } + .item-name{ + margin-top: 3px; + height: 20px; + line-height: 20px; + font-size: 14px; + color: #999; + } + .item-num{ + margin-top: 8px; + font-size: 18px; + height: 22px; + line-height: 22px; + color: #353535; + } + .item-icon{ + margin: 0 auto; + width: 64px; + height: 64px; + border-radius: 4px; + text-align: center; + -ms-flex-pack: center; + justify-content: center; + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + margin-bottom: 6px; + } + .color1{ + background-color: #ffbe60 + } + .item-text{ + margin-top: 3px; + height: 20px; + line-height: 20px; + font-size: 14px; + color: #999; + } + + .textcla{ + float: right; + margin-top: 1.2rem; + margin-right: 1rem; + } + .dynamic li{ + padding-bottom: 5px; + margin-bottom: 10px; + border-bottom: dashed 1px #ddd; + display: block; + } + .dy_data{ + text-align: center; + display: inline-block; + width: 5rem; + height: 5rem; + float: left; + background: #f2f2f2; + } + .dy-date1{ + text-align: center; + color: #666666; + font-size: 1.5625rem; + margin-top: 0.6rem; + } + .dy-date2{ + text-align: center; + color: #999999; + font-size: 0.8rem; + } + .dy_body{ + padding: 0 0.875rem; + overflow: hidden; + zoom: 1; + } + .dy_body h3{ + font-size: 16px; + } + + .position{ + position: relative; + } } diff --git a/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.ts b/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.ts index fa9f39be36d966513229b3205e0c3a404e6d8627..be6e6dcd15288cb9f2974b532095d8c83a6571e9 100644 --- a/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.ts +++ b/src/admin/ui/src/app/admin/dashboard/host-dashboard.component.ts @@ -40,6 +40,10 @@ export class HostDashboardComponent extends AppComponentBase implements AfterVie private _$editionsTable: JQuery; expiringTenantsData = []; recentTenantsData = []; + hotGoods=[]; + pends:any; + charttitle:string="交易额统计"; + IncomeWithAmount:string="交易额 :"; constructor( injector: Injector, @@ -50,7 +54,7 @@ export class HostDashboardComponent extends AppComponentBase implements AfterVie } init(): void { - this.selectedIncomeStatisticsDateInterval = AppIncomeStatisticsDateInterval.Daily; + this.selectedIncomeStatisticsDateInterval = AppIncomeStatisticsDateInterval.Transaction; } ngOnInit(): void { @@ -62,6 +66,7 @@ export class HostDashboardComponent extends AppComponentBase implements AfterVie this.createDateRangePicker(); this.getDashboardStatisticsData(); this.bindToolTipForIncomeStatisticsChart($(this.incomeStatisticsChart.nativeElement)); + this.getpends(); mApp.initScroller($('.m-scrollable'), {}); }, 0); } @@ -91,10 +96,33 @@ export class HostDashboardComponent extends AppComponentBase implements AfterVie this.drawIncomeStatisticsChart(result.incomeStatistics); this.loadRecentTenantsTable(result.recentTenants); this.loadExpiringTenantsTable(result.expiringTenants); + this.GetHotGoodsData(); this.loading = false; }); } + getpends():void{ + this.loading = true; + this._hostDashboardService.getPendsData( + + ).subscribe(result => { + this.pends=result; + }); + } + + GetHotGoodsData(): void { + this.loading = true; + this._hostDashboardService + .getHotGoodsData + ( + this.selectedDateRange.startDate, + this.selectedDateRange.endDate + ) + .subscribe(result => { + this.hotGoods = result; + this.loading = false; + }); + } /* * Edition statistics pie chart */ @@ -129,7 +157,7 @@ export class HostDashboardComponent extends AppComponentBase implements AfterVie const self = this; const normalizedData = this.normalizeEditionStatisticsData(data); - ($ as any).plot($(self.editionStatisticsChart.nativeElement), normalizedData, { + ($ as any).plot($(self.editionStatisticsChart), normalizedData, { series: { pie: { show: true, @@ -254,6 +282,16 @@ export class HostDashboardComponent extends AppComponentBase implements AfterVie incomeStatisticsDateIntervalChange(interval: number) { this.selectedIncomeStatisticsDateInterval = interval; this.refreshIncomeStatisticsData(); + if (interval==1){ + this.charttitle="交易额统计"; + this.IncomeWithAmount="交易额 :"; + }else if(interval==2){ + this.charttitle="用户数统计"; + this.IncomeWithAmount="用户数 :"; + }else if(interval==3){ + this.charttitle="订单数统计"; + this.IncomeWithAmount="订单数 :"; + } } refreshIncomeStatisticsData(): void { @@ -301,10 +339,10 @@ export class HostDashboardComponent extends AppComponentBase implements AfterVie return; } - if (incomeStatisticsChartLastTooltipIndex !== item.dataIndex) { + if (incomeStatisticsChartLastTooltipIndex !== item.dataIndex) { let label = ''; const isSingleDaySelected = this.selectedDateRange.startDate.format('L') === this.selectedDateRange.endDate.format('L'); - if (this.selectedIncomeStatisticsDateInterval === AppIncomeStatisticsDateInterval.Daily || + if (this.selectedIncomeStatisticsDateInterval === AppIncomeStatisticsDateInterval.Transaction || isSingleDaySelected) { label = moment(item.datapoint[0]).format('dddd, DD MMMM YYYY'); } else { @@ -317,9 +355,9 @@ export class HostDashboardComponent extends AppComponentBase implements AfterVie label += ' - ' + moment(nextItem[0]).format('LL'); } } - + incomeStatisticsChartLastTooltipIndex = item.dataIndex; - const value = this.l('IncomeWithAmount', '' + item.datapoint[1] + this.currency + ''); + const value = this.l(this.IncomeWithAmount + item.datapoint[1]); showChartTooltip(item.pageX, item.pageY, label, value); } }); diff --git a/src/admin/ui/src/index.html b/src/admin/ui/src/index.html index ff7ed49151168506f5a522b3bcb026e0f14e797c..dcd720b63410d0de5cdd627c2c7f8a012a8b8d10 100644 --- a/src/admin/ui/src/index.html +++ b/src/admin/ui/src/index.html @@ -15,6 +15,7 @@ + diff --git a/src/admin/ui/src/shared/AppEnums.ts b/src/admin/ui/src/shared/AppEnums.ts index 3cb30b07a2c3c98f8bd4e2421a58a1666e6b5cc5..8bc9d3c6631b1c580e97c8649695bfe03badbb63 100644 --- a/src/admin/ui/src/shared/AppEnums.ts +++ b/src/admin/ui/src/shared/AppEnums.ts @@ -34,9 +34,9 @@ export class AppTenantAvailabilityState { } export class AppIncomeStatisticsDateInterval { - static Daily: number = IncomeStatisticsDateInterval._1; - static Weekly: number = IncomeStatisticsDateInterval._2; - static Monthly: number = IncomeStatisticsDateInterval._3; + static Transaction: number = IncomeStatisticsDateInterval._1; + static Consumer: number = IncomeStatisticsDateInterval._2; + static Order: number = IncomeStatisticsDateInterval._3; } export class SubscriptionStartType { diff --git a/src/admin/ui/src/shared/service-proxies/service-proxies.ts b/src/admin/ui/src/shared/service-proxies/service-proxies.ts index e3105321183b9c36c77c287399e6c39cdb3d8e71..ab99c6d455678090bdee69bc6525b9735e40b2b7 100644 --- a/src/admin/ui/src/shared/service-proxies/service-proxies.ts +++ b/src/admin/ui/src/shared/service-proxies/service-proxies.ts @@ -4933,6 +4933,120 @@ export class HostDashboardServiceProxy { } return _observableOf(null); } + + /** + * @return Success + */ + getPendsData(): Observable { + let url_ = this.baseUrl + "/api/services/app/HostDashboard/GetPendsData"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processGetPendsData(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processGetPendsData(response_); + } catch (e) { + return >_observableThrow(e); + } + } else + return >_observableThrow(response_); + })); + } + + protected processGetPendsData(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response).error instanceof Blob ? (response).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}; + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + result200 = resultData200 ? GetPendsOutput.fromJS(resultData200) : new GetPendsOutput(); + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null); + } + + /** + * @param startDate (optional) + * @param endDate (optional) + * @return Success + */ + getHotGoodsData(startDate: moment.Moment | null | undefined, endDate: moment.Moment | null | undefined): Observable { + let url_ = this.baseUrl + "/api/services/app/HostDashboard/GetHotGoodsData?"; + if (startDate !== undefined) + url_ += "startDate=" + encodeURIComponent(startDate ? "" + startDate.toJSON() : "") + "&"; + if (endDate !== undefined) + url_ += "endDate=" + encodeURIComponent(endDate ? "" + endDate.toJSON() : "") + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processGetHotGoodsData(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processGetHotGoodsData(response_); + } catch (e) { + return >_observableThrow(e); + } + } else + return >_observableThrow(response_); + })); + } + + protected processGetHotGoodsData(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response).error instanceof Blob ? (response).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}; + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => { + let result200: any = null; + let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + if (resultData200 && resultData200.constructor === Array) { + result200 = []; + for (let item of resultData200) + result200.push(GetHotGoodsOutput.fromJS(item)); + } + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null); + } } @Injectable() @@ -15276,9 +15390,13 @@ export interface IAcceptFriendshipRequestInput { export class HostDashboardData implements IHostDashboardData { newTenantsCount!: number | undefined; + newTenantsratio!: number | undefined; newSubscriptionAmount!: number | undefined; - dashboardPlaceholder1!: number | undefined; - dashboardPlaceholder2!: number | undefined; + subscriptionAmountratio!: number | undefined; + newOrdersCount!: number | undefined; + newOrdersratio!: number | undefined; + newGoodsCount!: number | undefined; + newGoodsratio!: number | undefined; incomeStatistics!: IncomeStastistic[] | undefined; editionStatistics!: TenantEdition[] | undefined; expiringTenants!: ExpiringTenant[] | undefined; @@ -15303,9 +15421,13 @@ export class HostDashboardData implements IHostDashboardData { init(data?: any) { if (data) { this.newTenantsCount = data["newTenantsCount"]; + this.newTenantsratio = data["newTenantsratio"]; this.newSubscriptionAmount = data["newSubscriptionAmount"]; - this.dashboardPlaceholder1 = data["dashboardPlaceholder1"]; - this.dashboardPlaceholder2 = data["dashboardPlaceholder2"]; + this.subscriptionAmountratio = data["subscriptionAmountratio"]; + this.newOrdersCount = data["newOrdersCount"]; + this.newOrdersratio = data["newOrdersratio"]; + this.newGoodsCount = data["newGoodsCount"]; + this.newGoodsratio = data["newGoodsratio"]; if (data["incomeStatistics"] && data["incomeStatistics"].constructor === Array) { this.incomeStatistics = []; for (let item of data["incomeStatistics"]) @@ -15346,9 +15468,13 @@ export class HostDashboardData implements IHostDashboardData { toJSON(data?: any) { data = typeof data === 'object' ? data : {}; data["newTenantsCount"] = this.newTenantsCount; + data["newTenantsratio"] = this.newTenantsratio; data["newSubscriptionAmount"] = this.newSubscriptionAmount; - data["dashboardPlaceholder1"] = this.dashboardPlaceholder1; - data["dashboardPlaceholder2"] = this.dashboardPlaceholder2; + data["subscriptionAmountratio"] = this.subscriptionAmountratio; + data["newOrdersCount"] = this.newOrdersCount; + data["newOrdersratio"] = this.newOrdersratio; + data["newGoodsCount"] = this.newGoodsCount; + data["newGoodsratio"] = this.newGoodsratio; if (this.incomeStatistics && this.incomeStatistics.constructor === Array) { data["incomeStatistics"] = []; for (let item of this.incomeStatistics) @@ -15382,9 +15508,13 @@ export class HostDashboardData implements IHostDashboardData { export interface IHostDashboardData { newTenantsCount: number | undefined; + newTenantsratio: number | undefined; newSubscriptionAmount: number | undefined; - dashboardPlaceholder1: number | undefined; - dashboardPlaceholder2: number | undefined; + subscriptionAmountratio: number | undefined; + newOrdersCount: number | undefined; + newOrdersratio: number | undefined; + newGoodsCount: number | undefined; + newGoodsratio: number | undefined; incomeStatistics: IncomeStastistic[] | undefined; editionStatistics: TenantEdition[] | undefined; expiringTenants: ExpiringTenant[] | undefined; @@ -15654,6 +15784,102 @@ export interface IGetEditionTenantStatisticsOutput { editionStatistics: TenantEdition[] | undefined; } +export class GetPendsOutput implements IGetPendsOutput { + delivery!: number | undefined; + obligation!: number | undefined; + rejectedgoods!: number | undefined; + stock!: number | undefined; + consult!: number | undefined; + + constructor(data?: IGetPendsOutput) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + (this)[property] = (data)[property]; + } + } + } + + init(data?: any) { + if (data) { + this.delivery = data["delivery"]; + this.obligation = data["obligation"]; + this.rejectedgoods = data["rejectedgoods"]; + this.stock = data["stock"]; + this.consult = data["consult"]; + } + } + + static fromJS(data: any): GetPendsOutput { + data = typeof data === 'object' ? data : {}; + let result = new GetPendsOutput(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data["delivery"] = this.delivery; + data["obligation"] = this.obligation; + data["rejectedgoods"] = this.rejectedgoods; + data["stock"] = this.stock; + data["consult"] = this.consult; + return data; + } +} + +export interface IGetPendsOutput { + delivery: number | undefined; + obligation: number | undefined; + rejectedgoods: number | undefined; + stock: number | undefined; + consult: number | undefined; +} + +export class GetHotGoodsOutput implements IGetHotGoodsOutput { + goodname!: string | undefined; + goodtype!: string | undefined; + sales!: number | undefined; + + constructor(data?: IGetHotGoodsOutput) { + if (data) { + for (var property in data) { + if (data.hasOwnProperty(property)) + (this)[property] = (data)[property]; + } + } + } + + init(data?: any) { + if (data) { + this.goodname = data["goodname"]; + this.goodtype = data["goodtype"]; + this.sales = data["sales"]; + } + } + + static fromJS(data: any): GetHotGoodsOutput { + data = typeof data === 'object' ? data : {}; + let result = new GetHotGoodsOutput(); + result.init(data); + return result; + } + + toJSON(data?: any) { + data = typeof data === 'object' ? data : {}; + data["goodname"] = this.goodname; + data["goodtype"] = this.goodtype; + data["sales"] = this.sales; + return data; + } +} + +export interface IGetHotGoodsOutput { + goodname: string | undefined; + goodtype: string | undefined; + sales: number | undefined; +} + export class HostSettingsEditDto implements IHostSettingsEditDto { general!: GeneralSettingsEditDto; userManagement!: HostUserManagementSettingsEditDto; diff --git a/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/ChartDateInterval.cs b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/ChartDateInterval.cs index a545eceaed00568d0c9aeafa9e224dea2bd59026..1e7345216c96efe5972505acbc76d87affa6f9e0 100644 --- a/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/ChartDateInterval.cs +++ b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/ChartDateInterval.cs @@ -2,8 +2,8 @@ { public enum ChartDateInterval { - Daily = 1, - Weekly = 2, - Monthly = 3 + Transaction = 1, //交易额统计类型 + Consumer = 2, //用户数统计类型 + Order = 3 //订单数统计类型 } } \ No newline at end of file diff --git a/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/GetDynamiclistOutput.cs b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/GetDynamiclistOutput.cs new file mode 100644 index 0000000000000000000000000000000000000000..83d24c76ff1df58e429b99ec27b1f478bb99ba71 --- /dev/null +++ b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/GetDynamiclistOutput.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Magicodes.Admin.MultiTenancy.HostDashboard.Dto +{ + public class GetDynamiclistOutput + { + /// + /// 动态创建时间 + /// + public string CreationTime { get; set; } + /// + /// 动态内容 + /// + public string Context { get; set; } + + /// + /// 创建的时间日 + /// + public string Days { get; set; } + /// + /// 创建时间年月 + /// + public string Mothdate { get; set; } + } +} diff --git a/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/GetHotGoodsOutput.cs b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/GetHotGoodsOutput.cs new file mode 100644 index 0000000000000000000000000000000000000000..7d06f14b22f63276dc4bb763dc7fc37c12736d09 --- /dev/null +++ b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/GetHotGoodsOutput.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Magicodes.Admin.MultiTenancy.HostDashboard.Dto +{ + /// + /// 热销商品输出Dto + /// + public class GetHotGoodsOutput + { + /// + /// 商品名称 + /// + public string goodname { get; set; } + /// + /// 商品类型 + /// + public string goodtype { get; set; } + /// + /// 销量 + /// + public int sales { get; set; } + } +} diff --git a/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/HostDashboardData.cs b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/HostDashboardData.cs index 17898b8cafad43ef0fcb0e47dbfb65f5055b019c..239076f4704b38a975329efe674fa1b367c8a14e 100644 --- a/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/HostDashboardData.cs +++ b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/HostDashboardData.cs @@ -5,10 +5,47 @@ namespace Magicodes.Admin.MultiTenancy.HostDashboard.Dto { public class HostDashboardData { + /// + /// 总租户数 + /// public int NewTenantsCount { get; set; } + /// + /// 租户新增比率 + /// + public int NewTenantsratio { get; set; } + + /// + /// 总交易金额 + /// public decimal NewSubscriptionAmount { get; set; } - public int DashboardPlaceholder1 { get; set; } - public int DashboardPlaceholder2 { get; set; } + /// + /// 交易额新增比率 + /// + public int SubscriptionAmountratio { get; set; } + /// + /// 总订单数 + /// + public int NewOrdersCount { get; set; } + /// + /// 订单数新增比率 + /// + public int NewOrdersratio { get; set; } + /// + /// 总商品数 + /// + public int NewGoodsCount { get; set; } + + /// + /// 商品数新增比率 + /// + public int NewGoodsratio { get; set; } + + /// + /// 系统动态数据 + /// + public GetDynamiclistOutput GetDynamiclistOutput { get; set; } + + public List IncomeStatistics { get; set; } public List EditionStatistics { get; set; } public List ExpiringTenants { get; set; } diff --git a/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/getPendsOutput.cs b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/getPendsOutput.cs new file mode 100644 index 0000000000000000000000000000000000000000..2105af7649881ba21090447f2de793b90598562d --- /dev/null +++ b/src/application/Application.Shared/MultiTenancy/HostDashboard/Dto/getPendsOutput.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Magicodes.Admin.MultiTenancy.HostDashboard.Dto +{ + /// + /// 待处理Dto + /// + public class GetPendsOutput + { + /// + /// 待发货 + /// + public int Delivery { get; set; } + /// + /// 待付款 + /// + public int Obligation { get; set; } + /// + /// 待退货 + /// + public int Rejectedgoods { get; set; } + /// + /// 库存预警 + /// + public int Stock { get; set; } + /// + /// 待回复咨询 + /// + public int Consult { get; set; } + + } +} diff --git a/src/core/Magicodes.Admin.Core/Localization/Admin/Admin-zh-CN.xml b/src/core/Magicodes.Admin.Core/Localization/Admin/Admin-zh-CN.xml index 587959439bfa068d0902b541a237536bc5fbdd09..d261002205391f4b12eac2c9d0ee38182165fc86 100644 --- a/src/core/Magicodes.Admin.Core/Localization/Admin/Admin-zh-CN.xml +++ b/src/core/Magicodes.Admin.Core/Localization/Admin/Admin-zh-CN.xml @@ -584,11 +584,12 @@ 每月 每年 - 新订购金额 - 新租户 - Demo + 总交易金额 + 总租户数 + 总订单数 + 总商品数 Demo - 收入统计 + 数据概览 每日 每周 每月 @@ -780,5 +781,18 @@ + + + + + + + + + + + + + %m/%d/%Y \ No newline at end of file