第61章 在线用户统计的后端实现

1 Services.Customers.CustomerService.GetOnlineCustomersAsync

/// name="lastActivityDateTime">1个指定的用于排序操作的排序排序方式,默认值:null,即按照创建时间以倒序方式进行排序操作。

        /// name="pageIndex">当前页的页数值(与“pageSize”结合,设定需要跳过指定实体实例的个数值),默认值:0,即不需要执行跳过操作。

        /// name="pageSize">分页操作中每页最多显示实例的项(行)数值(与“pageIndex”结合,设定需要跳过指定实体实例的个数值),默认值:int.MaxValue=2147483647。

        ///

        /// 【异步获取所有在线用户】

        ///

        /// 摘要:

        ///     根据前端分页组件传递的参数实例,获取符合条件的用户表1指定页面内的持久化数据加载到1指定内存逻辑页面内。

        ///  说明:

        ///     该方法没有定义缓存操作,更没有定义缓存的移除操作。

        ///

        ///

        /// 返回:

        ///    1指定内存逻辑页面内的用户实体的所有实例。

        ///

        ///

        public async Task> GetOnlineCustomersAsync(DateTime lastActivityDateTime, long pageIndex = 0, int pageSize = int.MaxValue)

        {

            var query = _customerRepository.Table;

            query = query.Where(c =>c.LastActivityDateTime >= lastActivityDateTime);

            query = query.OrderByDescending(c => c.LastActivityDateTime);

            return await query.ToPagedListAsync(pageIndex, pageSize);

        }

2 Framework.Filters.SaveLastActivityAttribute

using System.Security.Claims;

using Core.Domain.Customers;

using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.Filters;

using Services.Customers;

namespace Framework.Filters

{

    ///

    /// 【在线用户统计横切过滤特性--类】

    ///

    /// 摘要:

    ///     通过该实体类中的方法成员来获取当前程序中网站中所有在线用户的数据信息。

    /// 说明:

    ///     1、在WebApi中只能通过被权限标记过的方法对用户实体1个指定实例最后一次操作的时间进行更新。

    ///     2、在默认情况下每间隔20分钟,通过被权限标记过的方法对置用户实体1个指定实例最后一次操作的时间进行更新。

    ///

    ///

    public sealed class SaveLastActivityAttribute : TypeFilterAttribute

    {

        #region 拷贝构造方法与变量

        public SaveLastActivityAttribute() : base(typeof(SaveLastActivityFilter))

        {

        }

        #endregion

        #region 嵌套类

        ///

        /// 【在线用户统计横切过滤--类】

        ///

        /// 摘要:

        ///     通过该实体类中的方法成员来获取当前程序中网站中所有在线用户的数据信息。

        /// 说明:

        ///     1、在WebApi中只能通过被权限标记过的方法对用户实体1个指定实例最后一次操作的时间进行更新。

        ///     2、在默认情况下每间隔20分钟,通过被权限标记过的方法对置用户实体1个指定实例最后一次操作的时间进行更新。

        ///

        ///

        private class SaveLastActivityFilter : IAsyncActionFilter

        {

            #region 拷贝构造方法与变量

            private readonly ICustomerService _customerService;

            public SaveLastActivityFilter(ICustomerService customerService)

            {

                _customerService = customerService;

            }

            #endregion

            #region 方法-私有/保护

            /// name="context">行为方法执行上下文实例。

            ///

            /// 【异步保存在线用户】

            ///

            /// 摘要:

            ///    在默认情况下每间隔20分钟,通过被权限标记过的方法对置用户实体1个指定实例最后一次操作的时间进行更新。

            ///

            ///

            private async Task SaveLastActivityAsync(ActionExecutingContext context)

            {

             

                if (context == null)

                    throw new ArgumentNullException(nameof(context));

                if (context.HttpContext.Request == null)

                    return;

               string _email = context.HttpContext.User.Claims?.SingleOrDefault(s => s.Type == ClaimTypes.Email)?.Value;

               if(!string.IsNullOrEmpty(_email))

               {

                    Customer  _customer = await _customerService.GetCustomerByEmailAsync(_email);

                    if (_customer.LastActivityDateTime.AddMinutes(20) < DateTime.Now)

                    {

                        _customer.LastActivityDateTime = DateTime.Now;

                        await _customerService.UpdateCustomerAsync(_customer);

                    }

                }

            }

            #endregion

            #region 方法--接口实现

            /// name="context">行为方法执行上下文实例。

            /// name="next">行为方法执行委托实例,如果同1个行为方法被多个过滤特性所标记,则该委托实例将负责调用下1个过滤特性。

            ///

            /// 【异步保存在线用户】

            ///

            /// 摘要:

            ///    当前过滤特性标记的入口。

            ///

            ///

            public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)

            {

                await SaveLastActivityAsync(context);

                if (context.Result == null)

                    await next();

            }

            #endregion

        }

        #endregion

    }

}

3 WebApi.Controllers.OnlineCustomerController

using Core;

using Core.Domain.Customers;

using Framework.Filters;

using Microsoft.AspNetCore.Authorization;

using Microsoft.AspNetCore.Mvc;

using Services.Customers;

using WebApi.Models;

namespace WebApi.Controllers

{

    [Route("[controller]/[action]")]

    [ApiController]

    [Authorize(PermissionsPolicy.Name)]

    [SaveLastActivity]

    public class OnlineCustomerController : ControllerBase

    {

        #region 拷贝构造方法与变量

        private readonly ICustomerService _customerService;

        ///

        /// 【拷贝构建方法】

        ///

        /// 摘要:

        ///     依赖注入容器通过拷贝构造方法,实例化该类中的变量成员。

        ///

        ///

        public OnlineCustomerController(

           ICustomerService customerService

         )

        {

            _customerService = customerService;

        }

        #endregion

        /// name="pagination">分页模型纪录的1个指定实例。

        ///

        /// 【在线用户表单单击提交分页--需权限】

        ///

        ///

        /// 摘要:

        ///     通过分页控件所传递的参数实例,获取符合条件的1指定页面内的所有数据,为指定页面的渲染显示提供数据支撑。

        /// 注意:

        ///     表单提交分页必须使用“[HttpPost]”进行标记。

        ///

        ///

        /// 返回:

        ///     消息模型纪录的1个指定实例,该实例存储当前“Api”方法的执行操作结果,为客户端页面的渲染提供数据支撑。

        ///

        [HttpPost]

        public async Task>> Index([FromBody] PaginationModel pagination)

        {

            DateTime _lastActivityDateTime = DateTime.Now.AddMinutes(-20);

            IPagedList _customerPageList = await _customerService.GetOnlineCustomersAsync(_lastActivityDateTime,

               (pagination.PageIndex - 1), pagination.PageSize);

            //实例化当前模型页(“物理页”),为当前页面的渲染显示提供数据支撑。

            PageModel _customerPageModel = new PageModel()

            {

                PageIndex = pagination.PageIndex,

                PageSize = pagination.PageSize,

                TotalCount = _customerPageList.TotalCount,

                Data = _customerPageList,

            };

            //实例化消息模型录,对当前“Api”控制器行方法的执行操作结果进行存储,为客户端页面的渲染提供数据支撑。

            return MessageModel>.GetSuccess($"成功获取第{pagination.PageIndex}页内的所有用户!", _customerPageModel);

        }

    }

}

对以上功能更为具体实现和注释见:230418_047shopDemo(在线用户统计的后端实现)。

你可能感兴趣的:(.net7,前后端分离,商城,后端)