业务开发(一)

业务实现的基本逻辑

 

因为疫情,天天被围在屋里,前一段时间花了大半个月把几年前写的开发环境代码从头读了一遍,对设计理念不统一的地方做了修正。

接着考虑做业务开发,放年假过去几天了,唯一能做的事情就是敲代码应付无聊。写几篇文章纪念今年独自一个在外乡过年。

基本逻辑:数据设计-->界面设计-->数据结构设计及分配-->代码编写-->发布程序。这里我将由简单到复杂地呈现两种情形,但本质上是一样的。

(一)单纯数据更新的基本逻辑(以定义公司代码为例)。

数据设计:定义两个表X00003和X0003T,其中X00003仅包括一个字段,待实现后续功能时再添加。

业务开发(一)

业务开发(一)

界面设计:主界面使用了数据表格,双击出现辅界面,以对话框形式允许进一步编辑数据。

业务开发(一)

业务开发(一)

数据结构设计:把业务用到的数据表或视图封装在此结构中,可以上下层体现及上下层的关联关系,此结构保存为一个结构文件,代码中加载。业务数据部分的逻辑,比如数据提取、保存或校验,全部封装在此结构中。

完成数据结构设计后,直接拖动到设计界面字段即可完成数据绑定。

业务开发(一)

代码编写,基本套路是:数据加载,新增,删除和保存。从风格上来说,就是操作数据结构,更直白地说就是操作“表名”或“视图”名,看不到SELECT,INSERT等语句。

粘出来的代码中做了备注。

业务开发(一)

using \SysConfig\MyBusiness\Symbol\FI\X0003T;

public class X00003
{
    public void X00003_MenuItemClick(Form sender, ItemClickEvent e)
    {
        switch(e.KeyCode)
        {
            case "Load":
                LoadData();
                break;
            case "New":
                NewRow();
                break;
            case "Delete":
                DeleteRow();
                break;
            case "Save":
                SaveData();
                break;
        }
    }
    private void LoadData()
    {
        string FileName = SourceFile;
        if(FileName=="") return;  //无效的数据结构文件
        
        EAS.ResultInfo.Clear(this);  //初始化消息清单
        XarrayTree ArrayTree = XarrayTree;
        ArrayTree.LoadSchema(FileName);  //加载数据结构
        ArrayTree.LoadData();   //加载数据
        if(EAS.ResultInfo.Check())   //检查是否存在异常消息
        {
            XarrayAll();   //把数据显示在界面上
            EAS.Comm.ShowMessage(this, "数据加载成功", MessageType.Normal);
        }
        else 
            EAS.ResultInfo.Throw(this);  //抛出异常消息
     }
    private void NewRow()
    {
        if(ReadOnly) return;  //界面为只读时不可新增
        
        EAS.ResultInfo.Clear(this);
        if(XarrayTree.New("X0003T",1))  //特定的数据源新增一空行
            XarrayAll();
        else 
            EAS.ResultInfo.Throw(this);
    }
    private void DeleteRow()
    {
        if(ReadOnly) return;

        EAS.ResultInfo.Clear(this);
        int RowIndex = Grid1.SelectedRowIndex;
        XarrayTree.Delete("X0003T",RowIndex); //删除数据源的指定行
        if(EAS.ResultInfo.Check())
        {
            XarrayAll();
            EAS.Comm.ShowMessage(this, "数据行已临时删除", MessageType.Normal);
        }
        else 
            EAS.ResultInfo.Throw(this);
    }
    private void SaveData()
    {
        if(ReadOnly) return;
        
        EAS.ResultInfo.Clear(this);
        XarrayTree.UpXarray("X0003T");  //向上推送表间关联字段
        XarrayTree.Submit();  //最终提交数据
        if(EAS.ResultInfo.Check())
            EAS.Comm.ShowMessage(this,"数据保存成功",MessageType.Normal);
        else
            EAS.ResultInfo.Throw(this);
    }

    public void Grid1_DoubleClick(EditGrid sender, Event e)
    {
        int RowIndex = Grid1.SelectedRowIndex;
        if(RowIndex == - 1) return;
        
        Xarray Array = Grid1.Xarray;
        Array.RowIndex = RowIndex;
        
        X0003T Dialog = new X0003T();
        Dialog.ReadOnly = ReadOnly;
        Dialog.Xarray = Array;
        Dialog.ShowDialog();
    }
}
public class X0003T
{
    public void X0003T_Load(Form sender, Event e)
    {
        LoadValues();
        XarrayAll(Xarray);
        COMCOD.ReadOnly=true;        
    }
    private void LoadValues()
    {
        COUNTR.Values.LoadData();
        REGION.Values.LoadData();
        PRIV00.Values.LoadData();
        CITY00.Values.LoadData();        
    }

    public void COUNTR_Enter(TextBox sender, Event e)
    {
        string FilterSQL = "CNTCOD = '" + COUNTR.GetValue() + "'";
        REGION.Values.Filter(FilterSQL);
        PRIV00.Values.Filter(FilterSQL);
        CITY00.Values.Filter(FilterSQL);
    }

    public void CANCEL_Click(Button sender, Event e)
    {
        Close();
    }

    public void OK_Click(Button sender, Event e)
    {
        UpdateAll(Xarray);
        Close();
    }
}

程序发布:界面设计和代码的编写需要从服务器下载程序源文件,在本地完成修改,完成后发布,更新服务器上的代码。这样用户重新登录,或主动加载主界面时即可使用最新事务。因此过程文字不好表述,我将在动画演示中说明。

 

复杂业务的代码逻辑:相比于单纯的数据更新,需要考虑扩展性,比如被外部程序调用,使用界面设计+API的方式实现。以下以成本中心主数据的维护为例。

这里我不再贴图,直接粘出实现的代码,详细将在动画演示中说明。

设计界面代码:

using \CO\API\CCA\MD\IFP001;

public class P00001
{    
    public void P00001_Load(Form sender, Event e)
    {
        string FileName = SourceFile;
        if(FileName=="")
        {
            Enabled=false;
            EAS.Comm.ShowMessage(this,"无效的数据结构文件",MessageType.Error);
            return;
        }
            
        XarrayTree.LoadSchema(FileName);  //加载数据源结构
        CONCOD.Values.LoadData("LANG00='ZH'");  //加载下拉列表
        COMCOD.Values.LoadData("LANG00='ZH'");
        CCATYP.Values.LoadData("LANG00='ZH'");
        BUSARE.Values.LoadData("LANG00='ZH'");
        BUSUNT.Values.LoadData("LANG00='ZH'");
    }
    public void CONCOD_Enter(TextBox sender, Event e)
    {  //回车时显示关联文本
        if(CONCOD.Text=="")
        {
            CONCOD.SetBrother("");  //清空关联文本
            return;
        }    
        Xarray Array = new Xarray();
        string FilterSQL="CONCOD='" + CONCOD.Text + "'";
        FilterSQL+=" AND LANG00 = 'ZH'";
        string Text=Array.GetValue("X0007T","NAME00",FilterSQL);
        CONCOD.SetBrother(Text);
    }
    public void CCACOD_Enter(TextBox sender, Event e)
    {
        if(CCACOD.Text=="")
        {
            CCACOD.SetBrother("");  //清空关联文本
            return;
        }    
        Xarray Array = new Xarray();
        string FilterSQL="CCACOD='" + CCACOD.Text + "'";
        FilterSQL+=" AND LANG00 = 'ZH' AND DATTO0 >=" + Date.Now().ToString();
        string Text=Array.GetValue("P0001T","NAME00",FilterSQL);
        CCACOD.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":
                DeleteData();
                break;
            case "ValidFor":
                ValidFor();
                break;
        }
        AuthMode = e.Item.AuthMode;             
    }
    private bool LoadData()
    {   
        if(!CheckData()) return false;
        IFP001 API = new IFP001(XarrayTree);  //开始调用API
        if(!API.Exists(CONCOD.Text,CCACOD.Text))
        {  //成本中心没有创建
            EAS.ResultInfo.Throw(this);
            return false;
        }
                    
        EAS.ResultInfo.Clear(this); //重置消息清单
        List<string> Filters=GetFilters();
        XarrayTree.LoadData(Filters,1);  //根据过滤条件加载第一数据源及下级
        string FilterSQL = Filters[0];
        FilterSQL += ";" + FilterSQL;
        XarrayTree.LoadData("PV0000", FilterSQL); //加载虚拟数据源的数据
        XarrayTree.MoveTo("PV0000",0); //移到虚拟表的第一行
        if(!EAS.ResultInfo.Check())  //检查是否存在错误消息
        {
            EAS.ResultInfo.Throw(this);  //抛出消息清单
            return false;
        }
        XarrayAll();  //把取回的数据显示到界面
        ReadOnly=false;
        Pages1.ReadOnly=true;
        DATFRM.ReadOnly=true;
        DATTO0.ReadOnly=true;
        return true;
    }
    private bool CheckData()
    {  //显示数据时必须的检查
        EAS.ResultInfo.Clear(this);
        if(CONCOD.Text == "")
            EAS.ResultInfo.Add("","成本范围不能为空",MessageType.Error,"");
        if(CCACOD.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="CONCOD='" + CONCOD.Text + "'";
        FilterSQL+=" AND CCACOD='" + CCACOD.Text + "'";
        //FilterSQL+=" AND DATFRM <=" + DATFRM.GetValue();
        //FilterSQL+= " AND DATTO0 >=" + DATTO0.GetValue();
        Filters.Add(FilterSQL);
        return Filters;
    }
    private void NewData()
    {
        EAS.ResultInfo.Clear(this);
        ReadOnly=false;  //界面设置为可编辑
        Box1.ReadOnly=true;
        Clear(true);  //清空界面上的所有数据
        if(!XarrayTree.Clear())  //清空数据源的所有层级的数据
        {
            EAS.ResultInfo.Throw(this);
            return;
        }
        XarrayTree.New("P00001",1);  //数据源增加一空行
        XarrayTree.New("P0001T",1);
        if(!EAS.ResultInfo.Check())
        {  //增加空行失败
            EAS.ResultInfo.Throw(this);
            return;
        }
    }
    private void EditData()
    {
        if(!LoadData()) return;
        
        ReadOnly=true;
        Pages1.ReadOnly=false;
        Box1.ReadOnly=true;
    }
    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 = "CONCOD='" + CONCOD.Text + "'";
            FilterSQL+=" AND CCACOD='" + CCACOD.Text + "'";
            if(Array.LoadData("P00001",FilterSQL))
            {
                string Message = "成本中心“"+CCACOD.Text+"”已存在";
                EAS.Comm.ShowMessage(this,Message,MessageType.Error);
                return;
            }
        }
        if(!Check()) return; //检查必输字段是否已输
        
        if(AuthMode!=AuthMode.New)
        {
            XarrayTree.Clone("P00001"); //保存旧数据
            XarrayTree.Clone("P0001T");
        }
        UpdateAll();  //把界面数据更新到数据源
        EAS.ResultInfo.Clear(this);  //重置消息清单
        IFP001 API = new IFP001(XarrayTree);  //开始调用API
        if(!API.Check())
        {
            EAS.ResultInfo.Throw(this);
            return;
        }
        if(API.SaveData())
        {
            AuthMode=AuthMode.None; //重置操作状态
            ReadOnly=true; //字段变为只读
            CONCOD.ReadOnly=false;
            CCACOD.ReadOnly=false;
            CCACOD.SetBrother(NAME00.Text);
            XarrayTree.AcceptChanges();  //所有数据置为未更改状态
            EAS.Comm.ShowMessage(this, "数据保存成功", MessageType.Normal);
        }
        else
            EAS.ResultInfo.Throw(this);
    }
    private void DeleteData()
    {
        EAS.ResultInfo.Clear(this); //重置消息清单
        if(!CheckData()) return;
        IFP001 API = new IFP001(XarrayTree);
        if(!API.Exists(CONCOD.Text,CCACOD.Text))
        {  //成本中心没有创建
            EAS.ResultInfo.Throw(this);
            return;
        }
        if(!API.Check(CONCOD.Text, CCACOD.Text)) //删除前的检查
        {
            EAS.ResultInfo.Throw(this);
            return;
        }
        
        List<string> Filters = GetFilters();
        string FilterSQL = Filters[0];
        Filters.Add(FilterSQL);  //相同的过滤条件传送给历史表
        Filters.Add(FilterSQL);
        XarrayTree.LoadData(Filters);  //加载删除的数据
        XarrayAll();
        string Message = "确实要删除成本中心“"+CCACOD.Text+"”吗?";
        AnswerResult Result = EAS.Comm.ShowMessage("删除数据",Message,AnswerStyle.YesNo);
        if(Result==AnswerResult.No)
            return;
        
        if(API.Delete())
        {  //数据被临时删除
            Clear(false);  //清空界面数据
            Pages1.ReadOnly = true;
            EAS.Comm.ShowMessage(this, "数据已被删除", MessageType.Normal);
        }
        else
            EAS.ResultInfo.Throw(this);
    }
    public void CCATYP_Enter(TextBox sender, Event e)
    {
        if(CCATYP.Text=="")
        {
            CCATYP.SetBrother("");  //清空关联文本
            return;
        }    
        Xarray Array = new Xarray();
        string FilterSQL="CCATYP='" + CCATYP.Text + "'";
        FilterSQL+=" AND LANG00 = 'ZH'";
        string Text=Array.GetValue("X0009T","NAME00",FilterSQL);
        CCATYP.SetBrother(Text);
    }            
    public void COMCOD_Enter(TextBox sender, Event e)
    {
        if(COMCOD.Text=="")
        {
            COMCOD.SetBrother("");  //清空关联文本
            return;
        }    
        Xarray Array = new Xarray();
        string FilterSQL="COMCOD='" + COMCOD.Text + "'";
        FilterSQL+=" AND LANG00 = 'ZH'";
        string Text=Array.GetValue("X0003T","NAME00",FilterSQL);
        COMCOD.SetBrother(Text);
    }
    public void BUSARE_Enter(TextBox sender, Event e)
    {
        if(BUSARE.Text=="")
        {
            BUSARE.SetBrother("");  //清空关联文本
            return;
        }
        Xarray Array = new Xarray();
        string FilterSQL="BUSARE='" + BUSARE.Text + "'";
        FilterSQL+=" AND LANG00 = 'ZH'";
        string Text=Array.GetValue("X0004T","NAME00",FilterSQL);
        BUSARE.SetBrother(Text);
    }
    public void BUSUNT_Enter(TextBox sender, Event e)
    {
        if(BUSUNT.Text=="")
        {
            BUSUNT.SetBrother("");  //清空关联文本
            return;
        }    
        Xarray Array = new Xarray();
        string FilterSQL="BUSUNT='" + BUSUNT.Text + "'";
        FilterSQL+=" AND LANG00 = 'ZH'";
        string Text=Array.GetValue("X0005T","NAME00",FilterSQL);
        BUSUNT.SetBrother(Text);
    }
    public void SMCOD0_Enter(TextBox sender, Event e)
    {
        if(SMCOD0.Text=="")
        {
            SMCOD0.SetBrother("");  //清空关联文本
            return;
        }
        //专项管理待进一步完善;
    }
    public void PCACOD_Enter(TextBox sender, Event e)
    {
        if(PCACOD.Text=="")
        {
            PCACOD.SetBrother("");  //清空关联文本
            return;
        }
        //责任中心待进一步完善;
    }
    private void ValidFor()
    {  //检查期间的合法性
        if(!CheckData()) return;
        IFP001 API = new IFP001(XarrayTree);
        if(!API.Exists(CONCOD.Text,CCACOD.Text))
        {  //成本中心没有创建
            EAS.ResultInfo.Throw(this);
            return;
        }
        if(!LoadData()) return;
        
        ReadOnly=true;
        DATFRM.ReadOnly=false; //仅有效期字段可以修改
        DATTO0.ReadOnly=false;
    }
}

API代码:

public class IFP001
{
    private XarrayTree Tree;
    
    public IFP001(XarrayTree ArrayTree)
    {
        Tree=ArrayTree;
    }
    public bool Check()
    {  //检查保存的数据是否满足业务规范
        Xarray Array = new Xarray();
        string CONCOD = Tree.GetValue("P00001","CONCOD");
        string FilterSQL = "CONCOD='" + CONCOD + "'";
        if(!Array.LoadData("X00007",FilterSQL))
        {
            string Message  = "成本范围“"  + CONCOD + "”无效";
            EAS.ResultInfo.Add("",Message,MessageType.Error,"CCA");
            return false;
        }
            
        string PATTER = Array.GetValue("A00005","PATTER","KEYCD1='CCA'");
        if(PATTER=="")
        {
            EAS.ResultInfo.Add("","缺少成本中心命名规范配置",MessageType.Error,"CCA");
            return false;
        }
            
        string CCACOD = Tree.GetValue("P00001","CCACOD");
        if(!EAS.Comm.IsMatch(CCACOD,PATTER))
        {
            EAS.ResultInfo.Add("","成本中心命名不符合规范",MessageType.Error,"CCA");
            return false;        
        }
            
        if(!CheckDate()) //检查有效期
            return false;
        
        string CCATYP = Tree.GetValue("P00001","CCATYP");
        FilterSQL = "CCATYP='" + CCATYP + "'";    
        if(!Array.LoadData("X00009",FilterSQL))
        {
            string Message  = "成本中心类型“"  + CCATYP + "”无效";
            EAS.ResultInfo.Add("",Message,MessageType.Error,"CCA");
            return false;
        }
        //待完善层次结构范围的检查
        string COMCOD = Tree.GetValue("P00001","COMCOD");
        FilterSQL = "COMCOD='" + COMCOD + "'";    
        if(!Array.LoadData("X00003",FilterSQL))
        {
            string Message  = "公司代码“"  + COMCOD + "”无效";
            EAS.ResultInfo.Add("",Message,MessageType.Error,"CCA");
            return false;
        }
        
        string BUSARE = Tree.GetValue("P00001","BUSARE");
        if(BUSARE!="")
        {
            FilterSQL = "BUSARE = '" + BUSARE + "'";
            if(!Array.LoadData("X00004", FilterSQL))
            {
                string Message  = "业务范围“"  + BUSARE + "”无效";
                EAS.ResultInfo.Add("", Message, MessageType.Error, "CCA");
                return false;
            }
        }

        string BUSUNT = Tree.GetValue("P00001","BUSUNT");
        if(BUSUNT!="")
        {
            FilterSQL = "BUSUNT = '" + BUSUNT + "'";
            if(!Array.LoadData("X00005", FilterSQL))
            {
                string Message  = "事业部“"  + BUSUNT + "”无效";
                EAS.ResultInfo.Add("", Message, MessageType.Error, "CCA");
                return false;
            }
        }
        
        //待完善责任中心的检查
        string SMCOD0 = Tree.GetValue("P00001","SMCOD0");
        if(SMCOD0!="")
        {
            //待完善专项管理的检查
        }
        //待完善取消激活预算的检查
            
        return true;
    }
    private bool CheckDate()
    {  //检查有效期
        Date DATFRM = Tree.GetValue("P00001","DATFRM"); //新的有效期
        Date DATTO0 = Tree.GetValue("P00001","DATTO0");
        if(DATTO0-DATFRM<0)
        {
            EAS.ResultInfo.Add("","有效期结束日期不能小于开始日期",MessageType.Error,"CCA");
            return false;
        }
            
        Xarray Array = new Xarray();
        string FilterSQL = "CONCOD='" + Tree.GetValue("P00001","CONCOD") + "'";
        FilterSQL+=" AND CCACOD='" + Tree.GetValue("P00001","CCACOD") + "'";
        if(Array.LoadData("P00001",FilterSQL))
        { //此成本中心编码已存在
            Date FromDate = Array.GetValue(0,"DATFRM"); //旧的有效期
            Date ToDate = Array.GetValue(0,"DATTO0");
            if(DATTO0-FromDate<0)
            {
                string Message = "有效期结束日期不能小于" + FromDate.ToString();
                EAS.ResultInfo.Add("",Message,MessageType.Error,"CCA");
            }
            if(DATFRM-ToDate>0)
            {
                string Message = "有效期开始日期不能大于" + ToDate.ToString();
                EAS.ResultInfo.Add("",Message,MessageType.Error,"CCA");
            }
        }
            
        return true;
    }
    public bool SaveData()
    {
        if(!Tree.DownXarray("P00001"))
        {
            EAS.ResultInfo.Add("","数据结构关联同步失败",MessageType.Error,"CCA");
            return false;
        }
            
        if(!ValidDate()) return false; //校验有效期的合法性
        
        if(!CopyData(true,false))
        {
            EAS.ResultInfo.Add("","同步生成历史数据失败",MessageType.Error,"CCA");
            return false;        
        }
        
        Tree.SetValue("P001H1","1","USRMOD"); //历史记录标识为修改
        Tree.SetValue("P001H2","1","USRMOD");                
        Tree.SetValue("P0001T","ZH","LANG00"); //后续通过系统参数赋值
        Tree.Submit();
        if(!EAS.ResultInfo.Check())
            return false;
        
        return true;
    }
    private bool CopyData(bool ForBackUp,bool ForDelete)
    {  //生成历史数据
        Tree.Clear("P001H1");  //清空历史表数据
        Tree.Clear("P001H2");
        
        Xarray Array = new Xarray();
        string FilterSQL = "CONCOD='" + Tree.GetValue("P00001","CONCOD") + "'";
        FilterSQL+="AND CCACOD='" + Tree.GetValue("P00001","CCACOD") + "'";
        if(!Array.LoadData("P00001",FilterSQL))
            return true; //此成本中心未创建,不需要创建历史记录
        
        //Date DATFRM = Tree.GetValue("P00001","DATFRM"); //新的有效期
        //Date FromDate = Array.GetValue(0,"DATFRM"); //旧的从有效期
        //Date ToDate = Array.GetValue(0,"DATTO0");
        //if(DATFRM-FromDate!=0 || DATTO0-ToDate!=0)
        //{  //有效期发生了更改        
            //ToDate = DATFRM.AddDays(-1);  //计算新的历史到有效期
            //if(ToDate - FromDate<0)
            //{
                //EAS.ResultInfo.Add("","历史数据:有效期的开始日期不能大于结束日期",MessageType.Error,"CCA");
                //return false;
            //}
        //}    
        string CRTDAT = Date.Now().ToString();
        string CRTTME = Time.Now().ToString();
        bool Result=ForDelete;
        if(!Result)
            Result = Tree.IsModified("P00001");   //表的数据有更改
        if(Result)  //表的数据有更改;
        {
            Tree.New("P001H1", 1); //数据源增加一空行
            Tree.Copy("P00001", "P001H1",ForBackUp); //把数据复制进历史表
            //Tree.SetValue("P001H1",ToDate.ToString(),"DATTO0");  //历史记录新的有效结束日期
            Tree.SetValue("P001H1",CRTDAT,"CRTDAT");
            Tree.SetValue("P001H1",CRTTME,"CRTTME");
            Tree.SetValue("P001H1",SysInfo.UserName,"USRCOD");            
        }
            
        Result=ForDelete;
        if(!Result)
            Result = Tree.IsModified("P0001T");            
        if(Result)
        {
            Tree.New("P001H2",1);
            Tree.Copy("P0001T","P001H2",ForBackUp);
            //Tree.SetValue("P001H2",ToDate.ToString(),"DATTO0");
            Tree.SetValue("P001H2",CRTDAT,"CRTDAT");
            Tree.SetValue("P001H2",CRTTME,"CRTTME");
            Tree.SetValue("P001H2",SysInfo.UserName,"USRCOD");
            Tree.SetValue("P001H2","ZH","LANG00"); //后续通过系统参数赋值        
        }
        
        return true;
    }
    private bool ValidDate()
    {
        Xarray Array = new Xarray();
        string FilterSQL = "CONCOD='" + Tree.GetValue("P00001","CONCOD") + "'";
        FilterSQL+="AND CCACOD='" + Tree.GetValue("P00001","CCACOD") + "'";
        if(!Array.LoadData("P00001",FilterSQL))
            return true; //此成本中心未创建,不需要校验期间合法性    
        
        Date DATFRM = Tree.GetValue("P00001","DATFRM"); //新的有效期
        Date DATTO0 = Tree.GetValue("P00001","DATTO0");
        Date FromDate = Array.GetValue(0,"DATFRM"); //旧的有效期
        Date ToDate = Array.GetValue(0,"DATTO0");
        if(DATFRM-FromDate!=0 || DATTO0-ToDate!=0)
        {  //有效期发生了更改
            if(DATTO0-DATFRM<0)
            {
                EAS.ResultInfo.Add("","有效期的开始日期不能大于结束日期",MessageType.Error,"CCA");
                return false;                
            }
            if(DATFRM-FromDate<0)
            {
                EAS.ResultInfo.Add("","新的开始日期不能小于原开始日期",MessageType.Error,"CCA");
                return false;
            }
        }
        
        return true;
    }
    public bool Check(string CONCOD,string CCACOD)
    {  //检查是否允许删除成本中心
        Xarray Array = new Xarray();
        string FilterSQL = "CONCOD='" + CONCOD + "' AND CCACOD='" + CCACOD + "'";
        FilterSQL+=" AND DATTO0 >=" + Date.Now().ToString();
        if(!Array.LoadData("P00001",FilterSQL))
        {
            string Message = "有效期范围内的成本中心“" + CCACOD +"”没有创建";
            EAS.ResultInfo.Add("",Message,MessageType.Error,"CCA");
            return false;
        }
        //有过记账不允许删除
        //有过预算分配不允许删除
        //有过计划数据不允许删除
        return true;
    }
    public bool Delete()
    {
        if(!CopyData(false,true))  //生成历史记录
            return false;
        if(!Tree.Delete("P00001",0))  //临时删除数据,包括下层数据
            return false;
        
        Tree.SetValue("P001H1","2","USRMOD"); //历史记录标识为删除
        Tree.SetValue("P001H2","2","USRMOD");        
        Tree.Submit();  //提交数据
        if(!EAS.ResultInfo.Check())
            return false;
        
        return true;
    }
    public bool Exists(string CONCOD,string CCACOD)
    {  //检查成本中心编码已存在
        Xarray Array = new Xarray();
        string FilterSQL = "CONCOD='" + CONCOD + "' AND CCACOD='" + CCACOD + "'";
        if(Array.LoadData("P00001",FilterSQL))
            return true;
        else
        {
            string Message = "成本中心“" + CCACOD +"”没有创建";
            EAS.ResultInfo.Add("",Message,MessageType.Error,"CCA");        
            return false;
        }    
    }
}

以上就是使用自己开发的编程环境实现业务逻辑的两个例子。我的基本理念是:如果这是一个商业系统销售给客户,这些业务逻辑代码对客户公开,客户可以用这个开发环境编写自己的功能,甚至修改标准代码。

 

动画演示   基本业务开发逻辑1     基本业务开发逻辑2

 

下一篇:权限设计

上一篇:结束语

上一篇:Shiro整合Springboot缓存之EhCache实现


下一篇:大数据看出行 滴滴发布华北智能出行报告