zoukankan      html  css  js  c++  java
  • 通用弹出选择页面业务过滤示例

    背景

      目前系统中,使用较多的通用选择包括:人员选择,品类选择,供应商选择等。采用的模式,基本上是点击按钮或者不可写的文本框。类似图:

    其基本实现,主要是通过调用dialog加载人员选择/品类选择/供应商选择页面。

    缺点分析

    采用此方法可以满足大多数的应用场景,但是如果当对弹出里的数据进行初始过滤就会变得很麻烦,拿上图弹出页面“人员选择”举例:如果有个按钮,它的功能是弹出人员选择页面,但是它想要的数据源不是默认的数据源,现有页面的数据源是所有的人员,虽然提供了部分查询语句进行过滤,但是一旦业务需求只展示内部用户或者只显示某个特殊的人员,再或者这个页面是外部和内部都使用的页面,外面人员使用时看不到所有的用户,那么此页面会变得不使用。当然也有人说我们可以在取数据加上这些逻辑就可以了呀。但是随着需求越来越多,程序就会变成很难维护,并且臃肿不堪。更有甚至,光人员选择页面需要提供多个页面,或者多个数据源来维护。

    解决办法

    图解:

    1. 创建一个获取所有用户的方法
    2. 创建一个补充方法
    3. 取交集

    要求:1和3是不可以变动的,不然就少了通用性,2是可以随时变动,2的变动会影响最终的结果

    代码实现:

    获取用户的代码

            /// <summary>
            /// 获取用户
            /// </summary>
            /// <param name="conditon"></param>
            /// <returns></returns>
            public string GetUserList(SelectUserParamDto conditon)
            {
                using (var dbContext = new Context())
                {
                    var users = (from j in dbContext.T_User
                                 where
                                     j.IsAdmin == conditon.IsAdmin &&
                                     j.IsSupplier == conditon.IsSupplier
                                 select new SelectUserDto
                                 {
                                     UserID = c.UserID,
                                     UserCode = c.UserCode,
                                     Name = c.Name,
                                     Mail = c.Mail,
                                     OrgName = IsCN ? b.OrgCName : b.OrgEName,
                                     PositionName = IsCN ? b.PositionCName : b.PositionEName,
                                     CreateTime = c.CreateTime,
                                     EnableDes = c.Enable == true ? Resource.PMOrg.PMOrg.Enable : Resource.PMOrg.PMOrg.Disabled
                                 });
    
                    if (!string.IsNullOrEmpty(conditon.Method))
                    {
                        var otherMethod = Call(dbContext, conditon);
                        //关联新的人员
                        users = from a in users
                                join b in otherMethod on a.UserID equals b.UserId
                                select a;
                    }
                    return users
                }
            }

    2.增加补充方法

    public class CommonForCall
        {
            /// <summary>
            /// 获取跟供应商相关的发布人
            /// </summary>
            /// <param name="dbContext"></param>
            /// <param name="conditon"></param>
            /// <returns></returns>
            public IQueryable<QueryResultDto> GetUsers(SMS_V40Context dbContext, SelectUserParamDto conditon)
            {
                if (conditon.CurrentUser.IsSupplier == true)
                {
                    var currentUser = dbContext.T_User.FirstOrDefault(j => j.UserID == conditon.CurrentUser.UserID);
                    if (currentUser == null) throw new Exception("非法用户");
                    var info = from a in dbContext.T_SC_Scar
                        join b in dbContext.T_PM_User on a.Publisher equals b.UserID
                        where a.SupplierId == currentUser.SupplierID
                        select new QueryResultDto
                        {
                            UserId = b.UserID,
                            UserCode = b.UserCode
                        };
                    return info;
                }
                else
                {
                    var info = from a in dbContext.T_PM_User.Where(j => j.IsSupplier != true)
                        select new QueryResultDto
                        {
                            UserId = a.UserID,
                            UserCode = a.UserCode
                        };
                    return info;
                }
            }
        }

    3.通用方法调用

    public class CommonCall
        {
            /// <summary>
            /// 动态调用传递的方法
            /// </summary>
            /// <param name="dbContext"></param>
            /// <param name="condition"></param>
            /// <returns></returns>
            public static IQueryable<T1> Call<T1>(SMS_V40Context dbContext, ConditionDto condition)
            {
                var instance = new CommonForCall();
                var instType = instance.GetType();
                var dynamicMethod = new DynamicMethod("", typeof(IQueryable<T1>), new Type[] { instType, typeof(SMS_V40Context), typeof(ConditionDto) }, true);
                var stringMethod = instType.GetMethod(condition.Method, new Type[] { typeof(SMS_V40Context), typeof(ConditionDto) });
                if (stringMethod == null) throw new Exception("未发现需要调用的方法方法");
                var ilGen = dynamicMethod.GetILGenerator();//IL生成器
                //压参数到堆栈上
                ilGen.Emit(OpCodes.Ldarg_0);
                ilGen.Emit(OpCodes.Ldarg_1);
                ilGen.Emit(OpCodes.Ldarg_2);
    
                //调用方法
                ilGen.Emit(OpCodes.Callvirt, stringMethod);
                ilGen.Emit(OpCodes.Ret);//结束并返回值
                //生成委托
                var gan = (Func<SMS_V40Context, ConditionDto, IQueryable<T1>>)dynamicMethod.CreateDelegate(typeof(Func<SMS_V40Context, ConditionDto, IQueryable<T1>>), instance);
                //调用委托返回结果
                return gan(dbContext, condition);
            }
        }

     4.前台调用页面的时候需要传递一个Method的参数,用于告诉后端方法,此次调用的补充方法是哪个。所有的补充方法放入类CommonForCall中。

    以上是整个实现,每次需要有特殊业务的时候,只需要在CommonForCall中创建一个特殊业务的方法,然后前台的Method参数置为创建的特殊业务方法名即可

  • 相关阅读:
    Visual Studio中的键盘快捷键自动添加所需的使用声明
    Workflow异常
    理解Javascript_03_javascript全局观
    jquery插件开发方法
    JS在IE和FireFox之间的区别汇总
    IE与FireFox的js和css (杂记)
    CSS:IE与Firefox的CSS兼容大全
    CSS网页设计解决方案(Hacks & Issues)
    什么是标准站点(W3C标准)
    12个针对网页设计师的非常便利的CSS框架、模板和摘录网站
  • 原文地址:https://www.cnblogs.com/creater/p/13280065.html
Copyright © 2011-2022 走看看