系统中用户可以自己定义页面宽度,待办事项列表显示行数,是否自动弹出提醒窗口,审批意见默认项,下面我就这一需求实现思路进行描述。

一、在.config文件中定义“用户自定义属性”栏目的数据结构及默认值。

     <userSettings>
  <applications>
   <add name ="OAPortal" description="门户应用">
    <programs>
     <add name ="Portal" description="门户">
      <properties>
       <add name ="UnCompleteTaskListPageSize" description="待办事项单页显示条数" valueType="Integer" category="列表展示" defaultValue="10"  minValue="1" maxValue="100"/>
       <add name ="UnReadTaskListPageSize" description="通知单页显示条数" valueType="Integer" category="列表展示" defaultValue="10" minValue="1" maxValue="100"/>
       <add name ="CompletedTaskListPageSize" description="已办事项单页显示条数" valueType="Integer" category="列表展示" defaultValue="10" minValue="1" maxValue="100"/>
            <add name ="SearchPageSize" description="全文搜索单页显示条数" valueType="Integer" category="列表展示" defaultValue="10" minValue="1" maxValue="100"/>
       <add name ="CommonOpinion" description ="常用意见" valueType ="String" category="公共设置" defaultValue="同意 不同意 已阅"/>
       <add name ="AutoShowNotify" description ="是否自动弹出日程提醒窗口" valueType ="Boolean" category="公共设置" defaultValue="true"/>
      </properties>
     </add>
    </programs>
   </add>
  </applications>
 </userSettings>

配置信息中包含如下一些信息:

1、应用名称,applications,在大项目中,一个系统可能有多个应用。

2、程序名称,programs,一个应用可能有多个程序。

3、属性,properties,一个属性包含,name(名称),description(描述),valueType(值类型),category(属性类型),defaultValue(默认值)

二、在数据库建入相应表,用于存储用户的自定义设置信息,数据结构如下:

[USER_ID] [nvarchar](36) NOT NULL,
 [APPLICATION_NAME] [nvarchar](36) NOT NULL,
 [PROGRAM_NAME] [nvarchar](36) NOT NULL,
 [PROPERTY_NAME] [nvarchar](36) NOT NULL,
 [PROPERTY_VALUE] [nvarchar](512) NOT NULL

三、数据读取

    数据读取需要考虑如下方面:

    1、数据读取频繁(必须用缓存来解决)

    2、用户还没有设置“个人设置”(所以取用户的“个人设置”数据前,先要取.config文件中“个人设置”数据项及其默认值来初始化个人设置数据实体对象。

    3、取出数据库中“个人设置”项,更新当前“个人设置”数据实体对象,但更新之前需要判断数据库中某项设置,在定义项中是否还存在,或许某一项“个人设置”已经从.config文件中删除了。

public static UserSettings GetUserSettings(string userID)
        {
            ExceptionHelper.TrueThrow<ArgumentNullException>(userID == null, "userID");

UserSettings us;

//先从Cache中读取,若已过期,则重新构造,并写入Cache
            lock(thisLock)
            {
                if (UserSettingsCacheQueue.Instance.TryGetValue(userID, out us) == false)
                {
                    us = UserSettingsAdapter.Instance.Load(userID);

UserSettingsCacheItemDependency dependency = new UserSettingsCacheItemDependency();
           UdpNotifierCacheDependency fileDependency = new UdpNotifierCacheDependency();
                    MixedDependency mixedDependency = new MixedDependency(dependency, fileDependency);

UserSettingsCacheQueue.Instance.Add(userID, us, mixedDependency);
                }
            }

return us;
        }

internal UserSettings Load(string userID)
        {
            ExceptionHelper.TrueThrow<ArgumentNullException>(userID == null, "userID");

UserSettings us = new UserSettings(userID);
            string strSQL = string.Format("SELECT * FROM [USER_SETTING] WHERE [USER_ID] = {0}",
                            TSqlBuilder.Instance.CheckQuotationMark(userID, true));
            DataView dv = DbHelper.RunSqlReturnDS(strSQL, ConnectionDefine.UserRelativeInfoConnectionName).Tables[0].DefaultView;

foreach (DataRowView drv in dv)
            {
                if (UserSettings.CheckConfig(drv["APPLICATION_NAME"].ToString(), drv["PROGRAM_NAME"].ToString(), drv["PROPERTY_NAME"].ToString()))
                {
                    us.AppSettings[drv["APPLICATION_NAME"].ToString()]
                        .Programs[drv["PROGRAM_NAME"].ToString()]
                        .Properties[drv["PROPERTY_NAME"].ToString()]
                        .Value = drv["PROPERTY_VALUE"];
                }
            }

return us;
        }

#region 构造函数
        internal UserSettings(string userID)
        {
            this.userID = userID;
            this.appSettings = CreateSettingsByDescriptor();
        }
        #endregion

/// <summary>
        /// 由配置信息生成UserSettings的架构
        /// </summary>
        private static AppSettingCollection CreateSettingsByDescriptor()
        {
            AppSettingCollection appSettings = new AppSettingCollection();

foreach (AppSettingDespElement appDesp in UserSettingsConfig.GetConfig().Applications)
            {
                appSettings.Add(new AppSetting(appDesp));
            }

return appSettings;
        }

四、保存“个人设置”

保存“个人设置”需要执行如下步骤:

1、保存数据到数据库中(1.1 先删除该用户所有“个人设置”。1.2 用事务方式重新插入“用户设置”各个属性项,)。

2、清除缓存

/// <summary>
        /// 保存个人设置
        /// </summary>
        public void Save()
        {
            UserSettingsAdapter.Instance.Save(this);

CacheNotifyData data = new CacheNotifyData(typeof(UserSettingsCacheQueue), this.UserID, CacheNotifyType.Invalid);
   UdpCacheNotifier.Instance.SendNotify(data);
        }

internal void Save(UserSettings userSetting)
        {
            ExceptionHelper.TrueThrow<ArgumentNullException>(userSetting == null, "userSetting");

StringBuilder strSQL = new StringBuilder(255);

strSQL.Append("DELETE FROM USER_SETTING WHERE USER_ID = ");
            strSQL.Append(TSqlBuilder.Instance.CheckQuotationMark(userSetting.UserID, true));
            strSQL.Append(TSqlBuilder.Instance.DBStatementSeperator);

foreach (AppSetting app in userSetting.AppSettings)
            {
                foreach (ProgSetting prog in app.Programs)
                {
                    foreach (PropertySetting property in prog.Properties)
                    {
                        if (property.Value != null)
                        {
                            InsertSqlClauseBuilder objISCB = new InsertSqlClauseBuilder();
                            objISCB.AppendItem("USER_ID", userSetting.UserID);
                            objISCB.AppendItem("APPLICATION_NAME", app.Description.Name);
                            objISCB.AppendItem("PROGRAM_NAME", prog.Description.Name);
                            objISCB.AppendItem("PROPERTY_NAME", property.Description.Name);
                            objISCB.AppendItem("PROPERTY_VALUE", property.Value.ToString());

strSQL.Append("INSERT INTO USER_SETTING ");
                            strSQL.Append(objISCB.ToSqlString(TSqlBuilder.Instance));
                            strSQL.Append(TSqlBuilder.Instance.DBStatementSeperator);
                        }
                    }
                }
            }

DbHelper.RunSqlWithTransaction(strSQL.ToString(), ConnectionDefine.UserRelativeInfoConnectionName);
        }

“个人设置”设计思路相关推荐

  1. 亿级流量网关设计思路

    本文准备围绕七个点来讲网关,分别是网关的基本概念.网关设计思路.网关设计重点.流量网关.业务网关.常见网关对比,对基础概念熟悉的朋友可以根据目录查看自己感兴趣的部分. 什么是网关 网关,很多地方将网关 ...

  2. 传授“带权重的负载均衡实现算法”独家设计思路!

    作者|孙玄/陈东 分布式系统中,大部分系统调用都会涉及到负载均衡,例如:客户端发往服务端的请求首先到达反向代理,然后反向代理再通过负载均衡算法将请求转发到业务系统:或者后端业务系统各模块间的调用前,也 ...

  3. 总体设计和登陆服务器 [游戏服务器的设计思路 转]

    作者博客: http://blog.csdn.net/yahle 大纲: 项目的历史背景 服务器的设计思路 服务器的技术 服务器的设计 服务器的改进 图形引擎myhoho及UI库的设计 客户端与服务器 ...

  4. iOS 组件化 —— 路由设计思路分析

    原文 前言 随着用户的需求越来越多,对App的用户体验也变的要求越来越高.为了更好的应对各种需求,开发人员从软件工程的角度,将App架构由原来简单的MVC变成MVVM,VIPER等复杂架构.更换适合业 ...

  5. 订单系统:从0到1设计思路

    https://baijiahao.baidu.com/s?id=1611220684816408868&wfr=spider&for=pc 概述 本文主要讲述了在传统电商企业中,订单 ...

  6. 启动定时器t0的工作指令是_看门狗的工作原理、应用和设计思路

    看门狗(watchdog timer)是一个定时器电路.一般有一个输入叫喂狗,一个输出到MCU的RST端.MCU正常工作的时候,每隔一端时间输出一个信号到喂狗端,给WDT清零.如果超过规定的时间不喂狗 ...

  7. HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo

    26 集群使用初步 HDFS的设计思路 l 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: l 在大数据系统中作用: 为各类分布式 ...

  8. HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo...

    26 集群使用初步 HDFS的设计思路 l 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: l 在大数据系统中作用: 为各类分布式 ...

  9. FPGA串口(UART)通信协议制定与设计思路详解示例

    串口(UART)通信协议制定与设计思路详解 1 概述 本文用于描述规定的串口通信协议,以及传输内容. 2 项目关于串口的要求 a) 支持BIT自检,1路UART上报BIT信息: b) 1路UART接口 ...

最新文章

  1. python 装饰器中的@wraps
  2. javascript数据类型一览
  3. lintcode-415-有效回文串
  4. javafx阴影_JavaFX技巧23:节省内存! 属性的阴影场
  5. String类的构造与析构相关处理
  6. 创业者怎样掌握简便的创业机会
  7. our happy ending(状压dp)
  8. 阿里的Json解析包FastJson使用
  9. 笔记本装系服务器系统驱动,联想昭阳E4430A笔记本安装WINDOWS SERVER 2003 2008服务器版网卡驱动的问题...
  10. ArcGIS Server Flex API接入MapABC地图
  11. 写给没时间理财的上班族
  12. 芯片Timing sign-off Corner理解
  13. Nature子刊:使用纳米孔测序从微生物组中得到完整闭环的细菌基因组
  14. H5页面调用admob激励视频,用户获取奖励
  15. 【文末下载PPT】李中文:软件成分安全分析(SCA)能力的建设与演进
  16. 锐龙R3 2200G和Intel i3-8100选哪个好
  17. 啃光学论文的笔记(1)
  18. 微信小程序开发—引用公共js里的方法
  19. 最全MySQL面试题和答案
  20. 在Ubuntu上搭建DDNS动态域名解析服务

热门文章

  1. 先序序列和中序序列构造二叉树,中序序列和后序序列构造二叉树
  2. 重装系统 linux启动windows系统文件,重装Windows系统后,Linux系统启动引导失败
  3. UEA数据集和UCR数据集的处理
  4. Edge的收藏夹内容导出导入转移
  5. vue父子组件传值:详解父组件向子组件传值(props)
  6. 手写C语言之函数概念-函数分类-实参与形参-传值调用与传址调用介绍(11)
  7. 用幂法和反幂法分别计算矩阵按模最大和按模最小的特征值及其特征向量
  8. c语言象棋教程下载,C语言程序源代码中国象棋.doc-资源下载在线文库www.lddoc.cn...
  9. html/template
  10. SQLaichemy三种排序方式