Winform开发框架中实现信息阅读状态的显示和存储

简介:

在很多项目中,可能会有要求对一些数据的阅读状态进行记录,用户阅读过或者未阅读过,都做不同的标识,方便了解数据的状态。如在我的客户关系管理系统中,对于客户的状态进行跟踪,如果最近联系时间超过配置天数的,那么特别显示出来。类似的应用场景,还有很多地方应用到,如对于通知公告、流程记录、内部信息等状态查看都可能是这样的类型。那么如何解决这些通用的需求呢,是需要每个都设置一个表来记录这些状态吗?

1、应用需求场景

前面说了,我们可能在一些数据上需要记录不同用户的阅读状态,如下面是我客户关系管理系统里面,对于最近没有联系的客户列表,其中对他们的查看状态进行特别显示。

当然,在我们业务系统里面,可能还有其他类似的场景。

对于这些相似的需求我们把这些应用场景的状态,用一个表来存储它的数据变化就可以做到了,我们设计一个表TB_InformationStatus来存储这些数据的状态。

上面的Information_ID就是对应不同表数据的ID,Status为我们需要记录的状态,User_ID为对应使用人员,这样对于不同业务表,不同的人员都可以把他们的数据记录起来,供我们处理显示了。

2、功能实现

对于这个信息状态的记录表,我们需要定义几个接口来进行信息的处理。

        /// <summary>
        /// 设置状态
        /// </summary>
        /// <param name="UserID">用户ID</param>
        /// <param name="InfoType">信息类型</param>
        /// <param name="InfoID">信息主键ID</param>
        /// <param name="Status">状态:0未读 1已读 </param>
        void SetStatus(string UserID, InformationCategory InfoType, string InfoID, int Status);

        /// <summary>
        /// 匹配状态
        /// </summary>
        /// <param name="UserID">用户ID</param>
        /// <param name="InfoType">信息类型</param>
        /// <param name="InfoID">信息主键ID</param>
        /// <param name="Status">状态:0未读 1已读 </param>
        /// <returns></returns>
        bool CheckStatus(string UserID, InformationCategory InfoType, string InfoID, int Status);
                       
        /// <summary>
        /// 查看指定的记录是否已读
        /// </summary>
        /// <param name="UserID">用户ID</param>
        /// <param name="InfoType">信息类型</param>
        /// <param name="InfoID">信息主键ID</param>
        /// <returns></returns>
        bool IsReadedStatus(string UserID, InformationCategory InfoType, string InfoID);

我们设计了上面的辅助表TB_InformationStatus来存储这些数据的状态,但并没有改变主表的字段数据,但是我们在显示主表的数据的时候,联合处理一下就可以了。

以客户信息为例,我们联合处理,获得的数据,依旧是客户信息的列表,如下代码所示。

        /// <summary>
        /// 获取用户的最近未联系客户列表
        /// </summary>
        /// <returns></returns>
        private List<CustomerInfo> GetUnContactList()
        {
            string KeyName = "FollowExpireDays";
            int FollowExpireDays = config.AppConfigGet(KeyName).ToInt32();
            if (FollowExpireDays < 1)
            {
                FollowExpireDays = 1;
            }
            List<CustomerInfo> list = BLLFactory<Customer>.Instance.GetUnContactList(FollowExpireDays, LoginUserInfo.ID.ToString());
            return list;
        }

在业务层,我们只需要构造我们的过滤条件获取到用户的数据,并处理它状态就可以了。

                condition.AddCondition("LastContactDate", today.AddDays(-1 * FollowExpireDays), SqlOperator.LessThanOrEqual);
                condition.AddCondition("Deleted", 0, SqlOperator.Equal);//不显示删除的
                condition.AddCondition("Creator", userId, SqlOperator.Equal);//仅仅选择该用户的记录

                string where = condition.BuildConditionSql().Replace("Where", "");

                List<CustomerInfo> list = baseDal.Find(where);
                foreach (CustomerInfo info in list)
                {
                    bool readed = BLLFactory<InformationStatus>.Instance.IsReadedStatus(userId, InformationCategory.客户联系, info.ID);
                    info.Data1 = readed ? "已读" : "未读";
                }

上面代码的Data1是我们实体类基类的属性,这里我们很方面用它来记录状态,否则我们需要把实体类集合转换为DataTable类型了。

这样我们返回的数据就带有这个记录的阅读状态,我们只需要在显示的时候,把Data1属性的别名修改一下就可以了。

        /// <summary>
        /// 绑定列表数据
        /// </summary>
        private void BindData()
        {
            this.winGridViewPager1.DisplayColumns = displayColumns;
            this.winGridViewPager1.ColumnNameAlias = BLLFactory<Customer>.Instance.GetColumnNameAlias();//字段列显示名称转义
            this.winGridViewPager1.AddColumnAlias("Data1", "查看状态");

            List<CustomerInfo> list = GetUnContactList();
            this.winGridViewPager1.DataSource = new WHC.Pager.WinControl.SortableBindingList<CustomerInfo>(list);
            this.winGridViewPager1.PrintTitle = "未联系客户信息列表";
        }

3、功能扩展

为了更有效展示不同类型客户的记录,我们可能需要设置普通客户7天需要跟进,VIP客户5天跟进,高级VIP客户3天跟进的时效,也就是对于同一个记录,不同属性类型,可能要求不同。

我们如果要实现这个需求,那么就需要再另外一个表里面记录客户类型和间隔天数的数据了。

然后在业务逻辑层处理返回未联系客户的时候,对他们进行分别处理,获取数据后进行合并,如下代码所示。

        /// <summary>
        /// 获得指定间隔时间内未联系的客户列表
        /// </summary>
        /// <param name="unContactDays">和最后联系日期的间隔天数</param>
        /// <param name="userId">当前用户</param>
        /// <returns></returns>
        public List<CustomerInfo> GetUnContactList(int unContactDays, string userId)
        {
            List<CustomerInfo> listAll = new List<CustomerInfo>();

            //根据用户配置的信息进行逐条处理,然后合并记录
            List<CustomerAlarmInfo> alarmList = BLLFactory<CustomerAlarm>.Instance.FindByUser(userId);
            foreach (CustomerAlarmInfo alarmInfo in alarmList)
            {
                //如果存在高级查询对象信息,则使用高级查询条件,否则使用主表条件查询
                SearchCondition condition = new SearchCondition();
                DateTime today = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
                int FollowExpireDays = alarmInfo.Days;
                if (FollowExpireDays < 1)
                {
                    FollowExpireDays = 1;
                }

                condition.AddCondition("Grade", alarmInfo.Grade, SqlOperator.Equal);
                condition.AddCondition("LastContactDate", today.AddDays(-1 * FollowExpireDays), SqlOperator.LessThanOrEqual);
                condition.AddCondition("Deleted", 0, SqlOperator.Equal);//不显示删除的
                condition.AddCondition("Creator", userId, SqlOperator.Equal);//仅仅选择该用户的记录

                string where = condition.BuildConditionSql().Replace("Where", "");

                List<CustomerInfo> list = baseDal.Find(where);
                foreach (CustomerInfo info in list)
                {
                    bool readed = BLLFactory<InformationStatus>.Instance.IsReadedStatus(userId, InformationCategory.客户联系, info.ID);
                    info.Data1 = readed ? "已读" : "未读";
                }

                listAll.AddRange(list);
            }
            return listAll;
        }

对于混合架构上的应用,我们注意到接口的地方,需要使用一个枚举的参数(信息类别名称),我们在接口定义的时候,需要特别声明几个地方,否则容易出现错误。

枚举的对象需要声明一下的。

    /// <summary>
    /// 信息分类
    /// </summary>
    [DataContract]
    public enum InformationCategory 
    {
        [EnumMember]
        客户联系,

        [EnumMember]
        通知公告,

        [EnumMember]
        其他 
    };

定义的WCF接口,用到了枚举类型的参数,也需要特别声明枚举的类型

    [ServiceContract]
    [ServiceKnownType(typeof(InformationCategory))]
    public interface IInformationStatusService : IBaseService<InformationStatusInfo>
    {
        /// <summary>
        /// 设置状态
        /// </summary>
        /// <param name="UserID">用户ID</param>
        /// <param name="InfoType">信息类型</param>
        /// <param name="InfoID">信息主键ID</param>
        /// <param name="Status">状态:0未读 1已读 </param>
        [OperationContract]
        void SetStatus(string UserID, InformationCategory InfoType, string InfoID, int Status);

        /// <summary>
        /// 匹配状态
        /// </summary>
        /// <param name="UserID">用户ID</param>
        /// <param name="InfoType">信息类型</param>
        /// <param name="InfoID">信息主键ID</param>
        /// <param name="Status">状态:0未读 1已读 </param>
        /// <returns></returns>
        [OperationContract]
        bool CheckStatus(string UserID, InformationCategory InfoType, string InfoID, int Status);
                       
        /// <summary>
        /// 查看指定的记录是否已读
        /// </summary>
        /// <param name="UserID">用户ID</param>
        /// <param name="InfoType">信息类型</param>
        /// <param name="InfoID">信息主键ID</param>
        /// <returns></returns>
        [OperationContract]
        bool IsReadedStatus(string UserID, InformationCategory InfoType, string InfoID);
    }

注意上这些,使用枚举就一切都顺利了。

本文转自博客园伍华聪的博客,原文链接:Winform开发框架中实现信息阅读状态的显示和存储,如需转载请自行联系原博主。



目录
相关文章
|
6月前
|
Web App开发 JSON 前端开发
SAP UI5 进阶 - JSON 模型字段里的值,显示在最终 UI5 界面上的奥秘分析试读版
SAP UI5 进阶 - JSON 模型字段里的值,显示在最终 UI5 界面上的奥秘分析试读版
29 0
|
1月前
|
存储 小程序 数据库
零基础开发小程序第五课-修改数据
零基础开发小程序第五课-修改数据
|
2月前
|
前端开发
问题解答:SAP UI5 应用设置禁止被其他应用嵌入运行的工作原理解析试读版
问题解答:SAP UI5 应用设置禁止被其他应用嵌入运行的工作原理解析试读版
113 0
|
10月前
|
小程序
零基础开发小程序第五课-修改数据(二)
零基础开发小程序第五课-修改数据(二)
|
10月前
|
存储 小程序 数据库
零基础开发小程序第五课-修改数据(一)
零基础开发小程序第五课-修改数据(一)
|
数据采集 监控 数据可视化
功能介绍补充|学习笔记
快速学习功能介绍补充
65 0
功能介绍补充|学习笔记
|
JavaScript 前端开发 小程序
讲述小程序之组件基本内容
讲述小程序之组件基本内容
107 0
讲述小程序之组件基本内容
如何使用配置的方式修改SAP C4C UI的字段标签,以及背后的工作原理
I was asked by one partner that it is expected to adapt the label of “New” button into “Add”, and change the text of first menu item from “Add” to “From Contact”.
如何使用配置的方式修改SAP C4C UI的字段标签,以及背后的工作原理