业务开发(二)

权限设计

 

基本上解释两个问题即可解释权限的运行逻辑:(1)何时触发权限检查(2)触发哪些权限检查(3)为了实现前两个逻辑而设计的逻辑。

(1)何时触发权限检查:在做界面设计,如果此设计属于“点击”且需要判断是否有权点击时,“检查权限”打上勾触发权限检查。这类设计主要有三类:菜单的点击、工具按钮的点击,界面按钮的点击。

(2)触发哪些权限检查:完成第一步设计后,通过菜单“编辑”--“权限配置文件”可以自动提取当前界面需要做权限检查的动作(并自动生成权限配置文件,在代码编译时自动生成权限代码,这个机制由底层完成),此时可以给每个动作分配权限参数,指令点击动作做哪些检查。比如成本中心主数据的查询操作,要求检查用户是否有成本范围和公司代码的权限。

“执行:检查输入值”:指权限检查的执行者(比如菜单、工具按钮、界面按钮)执行本身要求的权限检查。比如“显示”成本中心主数据的菜单,分配了权限参数P_CONCOD和P_COMCOD,那么点击此菜单时,自动检查用户是否有这两个参数的权限。这里有两头比较,用户分配的权限(后点介绍)和当前界面的参数值。当前界面的参数值由“参数值搜索于”的设置确定,可以输入固定值,可以输入SQL语句动态确定(比如根据输入的成本中心编码取得其所属公司),可以从系统参数(系统运行环境变量)确定,也可以从当前界面按数据源和值字段自动搜索。

 

“要求:检查输入值”:指界面字段本身不会触发权限检查,但又要求对此字段的输入值检查权限。比如查询界面的“工厂”字段,其自身不会触发权限检查,但查询的结果要求限定有权限的工厂数据才能出现,此时此控件要打上这个勾。当权限检查的执行者,在完成其自身的权限检查后,自动附带执行当前界面“要求:检查输入值”打上勾的字段输入值是否有权限。

 

(3)为了实现前两个逻辑而设计的逻辑

(3.1)维护权限参数,指明权限检查的具体点

实现此功能的业务代码

public class AU0002
{
    private string FileName = "";
    private EAS.Controls.TreeNode SelNode=null;
    
    public void AuthPara_SizeChanged(Form sender, Event e)
    {
        Rectangle Client=ClientRectangle;
        View1.Height=Client.Height-15;
    }

    public void AuthPara_Load(Form sender, Event e)
    {
        string FilePath=EAS.Comm.ServerDir;
        FileName=FilePath + "\\SysAdmin\\AuthPro\\AuthPro.eas";
        View1.LoadEas(FileName,"AuthPro");
    }
    public void View1_AfterSelectChanged(TreeView sender, Event e)
    {   
        SelNode = null;
        EAS.Controls.TreeNode Node=View1.SelectedNode;
        if(Node.KeyCode1!="ParamID") return;
        
        SelNode=Node;
        tbName.Text=Node.KeyCode;
        tbText.Text=Node.Text;
        tbSource.Text=Node.KeyCode2;
        tbField.Text=Node.KeyCode3;
        tbSysPara.Text=Node.KeyCode4;
        tbHelpID.Text=Node.KeyCode5;
        Box1.ReadOnly=true;
    }        
    public void AuthPara_MenuItemClick(Form sender, ItemClickEvent e)
    {
        switch(e.KeyCode)
        {
            case "New":
                NewData();
                break;
            case "Edit":
                EditData();
                break;
            case "Delete":
                DeleteData();
                break;
            case "Save":
                SaveData();
                break;
        }
        AuthMode = e.Item.AuthMode;       
    }
    private void NewData()
    {
        //EAS.Controls.TreeNode Node=View1.SelectedNode
        //if(Node==null) return;
        //if(Node.KeyCode1!="Folder")
        //    return;
        
        Box1.Clear(true);
        Box1.ReadOnly=false;
        SelNode=null;
    }
    private void EditData()
    {
        if(SelNode==null)
        {
            string Message="未选择要编辑的权限参数";
            EAS.Comm.ShowMessage("删除数据",Message,AnswerStyle.OKOnly);
            return;
        }
        Box1.ReadOnly=false;
    }
    private void DeleteData()
    {
        string Message="未选择要删除的权限参数";
        if(SelNode==null)
        { 
            EAS.Comm.ShowMessage("删除数据",Message,AnswerStyle.OKOnly);
            return;
        }
        tbName.Text=tbName.Text.Trim();
        if(tbName.Text=="")
        {
            EAS.Comm.ShowMessage("删除数据",Message,AnswerStyle.OKOnly);
            return;
        }
        
        Message="确实要删除权限参数“"+tbName.Text + "”吗?";
        AnswerResult Result=EAS.Comm.ShowMessage("删除数据",Message,AnswerStyle.YesNo);
        if(Result==AnswerResult.No) return;
        
        View1.Delete(SelNode,true);
        View1.SaveEas(FileName,"eas","AuthPro");
        SelNode=null;
        Box1.Clear(false);
        EAS.Comm.ShowMessage(this,"数据已删除",MessageType.Normal);
    }
    private void SaveData()
    {
        if(!CheckData()) return;
    
        if(AuthMode==AuthMode.New)
        {
            EAS.Controls.TreeNode Node=View1.SelectedNode;
            bool Result = true;
            if(Node==null) Result=false;
            if(Result && Node.KeyCode1!="Folder")
                Result=false;
            if(Result && Node==View1.Root) //定位在模块上,且不能为ROOT
                Result=false;
            if(!Result)
            {
                string Message="请选择权限参数所属模块";
                EAS.Comm.ShowMessage("保存数据",Message,AnswerStyle.OKOnly);
                return;
            }
            CreateNode();
        }
        else
        {
            if(!IsModified())
            {
                string Message="没有权限参数被修改,无需更新";
                EAS.Comm.ShowMessage("保存数据",Message,AnswerStyle.OKOnly);
                return;
            }
            SelNode.KeyCode=tbName.Text;
            SelNode.Text=tbText.Text;
            SelNode.KeyCode2=tbSource.Text;
            SelNode.KeyCode3=tbField.Text;
            SelNode.KeyCode4=tbSysPara.Text;
            SelNode.KeyCode5=tbHelpID.Text;
        }
        
        View1.Update();
        View1.SaveEas(FileName,"eas","AuthPro");
        Box1.ReadOnly=true;
        EAS.Comm.ShowMessage(this,"数据已保存",MessageType.Normal);            
    }
    private bool CheckData()
    {
        if(tbName.Text.Trim()=="") 
            return false;
        if(tbText.Text.Trim()=="") 
            return false;
     
        return true;
    }
    private bool IsModified()
    {
        if(SelNode==null) return false;
        if(tbName.Modified || tbText.Modified || tbSource.Modified ||
            tbField.Modified || tbSysPara.Modified)
            return true;
        
        return false;
    }
    private void CreateNode()
    {
        EAS.Controls.TreeNode Parent = View1.SelectedNode;
        if(Parent==View1.Root) return;
        if(Parent.KeyCode1!="Folder") return;
        
        EAS.Controls.TreeNode Child = new EAS.Controls.TreeNode();
        Child.KeyCode=tbName.Text;
        Child.Text=tbText.Text;
        Child.KeyCode2=tbSource.Text;
        Child.KeyCode3=tbField.Text;
        Child.KeyCode4=tbSysPara.Text;
        Child.KeyCode5=tbHelpID.Text;
        Child.KeyCode1="ParamID";
        Child.DisplayAll=true;
        View1.Add(Child,Parent,false);
    }
}

(3.2)角色维护:即定义角色拥有的具体参数值,其值由下面的颗粒度确定:用户+事务代码+动作的KEYCOD+权限参数。比如用户A可以查询成本范围1000、2000的成本中心主数据,但其只能新增成本范围1000的成本中心主数据。在输入事务码时,系统自动提取界面设计时分配的权限配置文件并解析。

(3.3)维护岗位角色

(3.4)用户维护

业务代码

using \SysAdmin\API\UserAuth\Users\IFX002;

public class X00002
{
    public void X00002_Load(Form sender, Event e)
    {
        string FileName = SourceFile;
        if(FileName=="")
        {
            Enabled=false;
            EAS.Comm.ShowMessage(this,"无效的数据结构文件",MessageType.Error);
            return;
        }            
        XarrayTree.LoadSchema(FileName);  //加载数据源结构
    }
    public void X00002_MenuItemClick(Form sender, ItemClickEvent e)
    {
        switch(e.KeyCode)
        {
            case "Load":
                LoadData();
                break;
            case "New":
                NewData();
                break;
            case "Edit":
                EditData();
                break;
            case "Save":
                SaveData();
                break;
            case "Delete":
                DeleteData();
                break;
        }
        AuthMode = e.Item.AuthMode;             
    }
    private bool LoadData()
    {
        if(!CheckData()) return false;
        IFX002 API = new IFX002(XarrayTree);
        if(!API.Exists(USRCOD.Text))
        {  //用户没有创建
            EAS.ResultInfo.Throw(this);
            return false;
        }
            
        EAS.ResultInfo.Clear(this); //重置消息清单
        List<string> Filters=GetFilters();
        XarrayTree.LoadData(Filters,1);  //根据过滤条件加载第一数据源及下级
        if(!EAS.ResultInfo.Check())  //检查是否存在错误消息
        {
            EAS.ResultInfo.Throw(this);  //抛出消息清单
            return false;
        }
        XarrayAll();  //把取回的数据显示到界面
        ReadOnly=true;
        USRCOD.ReadOnly=false;
        return true;
    }
    private bool CheckData()
    {  //显示数据时必须的检查
        EAS.ResultInfo.Clear(this);
        if(USRCOD.Text == "")
            EAS.ResultInfo.Add("","用户名不能为空",MessageType.Error,"");
        
        if(!EAS.ResultInfo.Check())
        {
            EAS.ResultInfo.Throw(this);
            return false;
        }
            
        return true;
    }
    private List<string> GetFilters()
    {  //根据界面数据生成第一级数据源的过滤条件
        List<string> Filters=new List<string>();
        string FilterSQL="USRCOD='" + USRCOD.Text + "'";
        Filters.Add(FilterSQL);
        return Filters;
    }        
    private void NewData()
    {
        EAS.ResultInfo.Clear(this);
        ReadOnly=false;  //界面设置为可编辑
        Clear(true);  //清空界面上的所有数据
        if(!XarrayTree.Clear())  //清空数据源的所有层级的数据
        {
            EAS.ResultInfo.Throw(this);
            return;
        }
        XarrayTree.New("X00002",1);  //数据源增加一空行
        if(!EAS.ResultInfo.Check())
        {  //增加空行失败
            EAS.ResultInfo.Throw(this);
            return;
        }
    }
    private void EditData()
    {
        if(!LoadData()) return;
        
        ReadOnly=false;
        USRCOD.ReadOnly=true;
    }        
    private void DeleteData()
    {
        EAS.ResultInfo.Clear(this); //重置消息清单
        if(!CheckData()) return;
        IFX002 API = new IFX002(XarrayTree);
        if(!API.Exists(USRCOD.Text))
        {  //用户没有创建
            EAS.ResultInfo.Throw(this);
            return;
        }
        if(!API.Check(USRCOD.Text)) //删除前的检查
        {
            EAS.ResultInfo.Throw(this);
            return;
        }
        
        List<string> Filters = GetFilters();
        XarrayTree.LoadData(Filters);  //加载删除的数据
        XarrayAll();
        string Message = "确实要删除用户“"+USRCOD.Text+"”吗?";
        AnswerResult Result = EAS.Comm.ShowMessage("删除数据",Message,AnswerStyle.YesNo);
        if(Result==AnswerResult.No)
            return;
        
        if(API.Delete())
        {
            Clear(false);  //清空界面数据
            ReadOnly = true;
            USRCOD.ReadOnly=false;
            EAS.Comm.ShowMessage(this, "数据已被删除", MessageType.Normal);
        }
        else
            EAS.ResultInfo.Throw(this);
    }
    private void SaveData()
    {
        if(AuthMode == AuthMode.Display || AuthMode == AuthMode.None)
        {
            EAS.Comm.ShowMessage(this,"非编辑状态,无数据更新",MessageType.Error);
            return;
        }
        if(AuthMode==AuthMode.New)  //新增时检查用户是否已存在
        {
            Xarray Array = new Xarray();
            string FilterSQL = "USRCOD='" + USRCOD.Text + "'";
            if(Array.LoadData("X00002",FilterSQL))
            {
                string Message = "用户“"+USRCOD.Text+"”已存在";
                EAS.Comm.ShowMessage(this,Message,MessageType.Error);
                return;
            }
        }
        if(!Check()) return; //检查必输字段是否已输
        
        if(AuthMode!=AuthMode.New)
            XarrayTree.Clone("X00002"); //保存旧数据
        UpdateAll();  //把界面数据更新到数据源
        EAS.ResultInfo.Clear(this);  //重置消息清单
        IFX002 API = new IFX002(XarrayTree);  //开始调用API
        if(API.SaveData())
        {
            AuthMode=AuthMode.None; //重置操作状态
            ReadOnly=true; //字段变为只读
            USRCOD.ReadOnly=false;
            XarrayTree.AcceptChanges();  //所有数据置为未更改状态
            EAS.Comm.ShowMessage(this, "数据保存成功", MessageType.Normal);
        }
        else
            EAS.ResultInfo.Throw(this);
    }            
}

(3.5)给用户分配岗位角色

业务代码

public class AU0006
{
    public void AU0006_Load(Form sender, Event e)
    {
        string FileName = SourceFile;
        if(FileName=="")
        {
            Enabled=false;
            EAS.Comm.ShowMessage(this,"无效的数据结构文件",MessageType.Error);
            return;
        }
        XarrayTree.LoadSchema(FileName);
    }
    public void USRCOD_Enter(TextBox sender, Event e)
    {  //回车时显示关联文本
        if(USRCOD.Text=="")
        {
            USRCOD.SetBrother("");  //清空关联文本
            return;
        }    
        Xarray Array = new Xarray();
        string FilterSQL="USRCOD='" + USRCOD.Text + "'";
        string Text=Array.GetValue("X00002","USRNAM",FilterSQL);
        USRCOD.SetBrother(Text);
    }
    public void P00001_MenuItemClick(Form sender, ItemClickEvent e)
    {
        switch(e.KeyCode)
        {
            case "Load":
                LoadData();
                break;
            case "New":
                NewData();
                break;
            case "Edit":
                EditData();
                break;
            case "Save":
                SaveData();
                break;
            case "Delete":
                DelData();
                break;
            case "NewRows":
                NewRows();
                break;
            case "DelRow":
                DelRow();
                break;
        }
        AuthMode = e.Item.AuthMode;             
    }
    private bool LoadData()
    {   
        if(!CheckData())
        {
            EAS.ResultInfo.Throw(this);
            return false;
        }
                    
        EAS.ResultInfo.Clear(this); //重置消息清单
        List<string> Filters=GetFilters();
        XarrayTree.LoadData(Filters);
        if(!EAS.ResultInfo.Check())  //检查是否存在错误消息
        {
            EAS.ResultInfo.Throw(this);  //抛出消息清单
            return false;
        }
        Box1.XarrayAll();  //把取回的数据显示到界面
        ReadOnly=true;
        USRCOD.ReadOnly=false;
        return true;
    }
    private bool CheckData()
    {  //显示数据时必须的检查
        EAS.ResultInfo.Clear(this);
        if(USRCOD.Text == "")
        {
            EAS.ResultInfo.Add("","用户不能为空",MessageType.Error,"");
            return false;
         }

        string UsrCod = USRCOD.Text.Trim();
        Xarray Array = new Xarray();
        Array.LoadData("SELECT USRNAM FROM X00002 WHERE USRCOD ='" + UsrCod + "'");
        if (Array.Rows.Count(XarrayType.Edited) == 0)
        {
            EAS.ResultInfo.Add("", "无效的用户", MessageType.Error, "");
            return false;
        }
            
        return true;
    }
    private List<string> GetFilters()
    {
        List<string> Filters=new List<string>();
        string FilterSQL="USRCOD='" + USRCOD.Text + "'";
        Filters.Add(FilterSQL);
        return Filters;
    }
    private void NewData()
    {
        EAS.ResultInfo.Clear(this);
        ReadOnly=false;  //界面设置为可编辑
        Clear(true);  //清空界面上的所有数据
        if(!XarrayTree.Clear())  //清空数据源的所有层级的数据
        {
            EAS.ResultInfo.Throw(this);
            return;
        }
        XarrayTree.New("V00007",10);
        Box1.XarrayAll();
    }
    private void EditData()
    {
        if(!LoadData()) return;
        
        XarrayTree.New("V00007",10);
        Box1.XarrayAll();
        USRCOD.ReadOnly=true;
        Box1.ReadOnly=false;
    }
    private void SaveData()
    {
        if(!CheckData())
        {
            EAS.ResultInfo.Throw(this);
            return;
        }
        EAS.ResultInfo.Clear(this);
        Xarray Array=XarrayTree.GetXarray("V00007");
        int Count=Array.Rows.Count(XarrayType.Edited);
        for (int Index = 0; Index < Count; Index++)
        {  //把用户推送入数据源
            if(Array.IsEmpty(Index)) break;
            Array.SetValue(USRCOD.Text,Index,"USRCOD",false);
            string Name=Array.GetValue(Index,"AUCOD2");
            Name=GetName(Name);
            Array.SetValue(Name,Index,"AUCOD0",false);
        }
        XarrayTree.Submit();
        if(EAS.ResultInfo.Check())
        {
            EAS.Comm.ShowMessage(this, "数据保存成功", MessageType.Normal);
            Box1.XarrayAll();
        }
        else
            EAS.ResultInfo.Throw(this);
    }
    public void Grid1_BeforeUpdate(EditGrid sender, CancelEvent e)
    {
        Xarray Array = XarrayTree.GetXarray("V00007");
        int Count=Array.Rows.Count(XarrayType.Edited);
        for (int Index = 0; Index < Count; Index++)
        {
            if (Array.GetValue(Index, "AUCOD2") == e.NewValue)
            {
                e.Canceled = true;
                EAS.ResultInfo.Throw(this,"角色“" + e.NewValue + "”已存在", MessageType.Error);
                return;
            }
        }
        string Name = GetName(e.NewValue);
        Array = new Xarray();
        Array.LoadData("AU0001", "AUCOD0='" + Name + "' AND AUTYP0='2'");
        if (Array.Rows.Count(XarrayType.Edited) == 0)
        {
            e.Canceled = true;
            EAS.ResultInfo.Throw(this, "无效的角色名称", MessageType.Error);
        }        
    }     
    private string GetName(string Name)
    {
        Name = Name.Replace(":", "");
        return Name;
    }
    public void Grid1_AfterUpdated(EditGrid sender, Event e)
    {
        string Name = GetName(e.Value);
        Xarray Array = new Xarray();
        string Text = Array.GetValue("AU001T", "NAME00", "AUCOD0='" + Name + "' AND LANG00='ZH'");
        Array = XarrayTree.GetXarray("V00007");
        Array.SetValue(Text, e.RowIndex, "NAME00",false);
        Grid1.Update();
    }
    private void NewRows()
    {
        if (Grid1.ReadOnly) return;
        
        XarrayTree.New("V00007",10);
        Box1.XarrayAll();    
    }
    private void DelRow()
    {
        if (Grid1.ReadOnly) return;
        
        int RowIndex = Grid1.SelectedRowIndex;
        string Name = XarrayTree.GetValue("V00007",RowIndex, "AUCOD2");
        string Message = "确定要移除角色“" + Name + "”?";
        AnswerResult Result = EAS.Comm.ShowMessage("移除数据", Message, AnswerStyle.YesNo);
        if (Result == AnswerResult.No) return;

        XarrayTree.Delete("V00007",RowIndex);
        Box1.XarrayAll();
    }
    private void DelData()
    {
        if (!CheckData())
        {
            EAS.ResultInfo.Throw(this);
            return;
        }
        if(!LoadData()) return;
        
        string Message = "确定要删除用户“" + USRCOD.Text + "”分配的角色?";
        AnswerResult Result = EAS.Comm.ShowMessage("删除数据", Message, AnswerStyle.YesNo);
        if (Result == AnswerResult.No) return;

        if(!XarrayTree.Delete("V00007"))
        {
            EAS.ResultInfo.Throw(this);
            return;        
        }
        XarrayTree.Submit();
        if(EAS.ResultInfo.Check())
            EAS.ResultInfo.Throw(this,"用户分配的角色已删除",MessageType.Normal);
        else 
            EAS.ResultInfo.Throw(this);            
        Clear(false);
        ReadOnly = true;
        USRCOD.ReadOnly = false;
    }
}

(3.6)在此之外还有一个大框架,发布程序时必须指定是显示、新增还是修改等。

 

 

动面演示

 

下一篇:调试业务代码

上一篇:业务实现的基本逻辑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值