业务系统设计之二:系统主控设计(上)

简介:
本系列文章目录:
     系统主控简单的理解就是一个系统的操作控制或者也可以叫住系统操作平台。一个良好的系统主控可以让系统更加灵活操作、应用。至于技术上的实现我们可以有很多中选择,所以这里不谈论什么技术好等话题。本文将接着上一篇《 业务系统设计之一:系统菜单设计 》介绍业务系统里的主控设计方法,以及怎么将系统的各部分(系统菜单、系统主控、业务操作等等)衔接在一起。 或许我这样说还所以很多朋友不能理解什么是系统主控,那好就请你仔细看看下图: 
 
      上图是我在126邮箱中的截图,它的这种主控方式我个人感觉就是很爽的一种方式。收件箱、百宝箱、写信等操作都以一个新的操作界面打开,然后将其挂在主控的菜单工具拦上,多任务之间可以相互切换操作,实现了多任务可以并行处理,每项功能操作都有自己的状态(比如写信提交了不会影响其他的界面),至于其他好处吧我这里就不多废话。
      通过上面的分析与了解,下面我们就来看看像这样的系统主控是怎么实现的。以上一篇文章《业务系统设计之系统菜单设计》为基础,通过点击菜单项目则打开菜单项对应的页面,菜单运行效果如下: 系统主控的开发其实和其他功能一样简单,只要弄清楚了功能需求就OK。
       功能需求大致如下:
      1、系统入口点(这肯定就是系统菜单--下拉菜单、树型菜单等)
      2、全局显示容器(既显示内嵌页面的容器)
      3、点击菜单项可以在容器上创建页签选项,如果当前菜单项所对应的页面已经打开则选中该项。
      4、在容器中选择页签项,被选择项突出显示。
      5、每一个页签下对应一个页面,可相互独立操作互不影响其他页签项。
      5、每一个页签带有关闭功能,点击指定关闭区域或图标既可实现关闭当前页签。
      6、双击可实现关闭页签。
      7、其他界面效果控制等。
      本文中的数据库结构借鉴于市场上主流ERP系统的菜单表结构,程序运行效果同上图一样,对菜单表有不清楚的朋友可留言提问,这里我不做详细解释。SQL代码如下:
SET  ANSI_NULLS  ON
GO
SET  QUOTED_IDENTIFIER  ON
GO
IF   NOT   EXISTS  ( SELECT   *   FROM  sys.objects  WHERE   object_id   =   OBJECT_ID (N ' [dbo].[Menu] ' AND  type  in  (N ' U ' ))
BEGIN
CREATE   TABLE   [ dbo ] . [ Menu ] (
    
[ AutoID ]   [ uniqueidentifier ]   ROWGUIDCOL    NOT   NULL   CONSTRAINT   [ DF_Menu_AutoID ]    DEFAULT  ( newid ()),
    
[ Code ]   [ varchar ] ( 50 NULL ,
    
[ Name ]   [ varchar ] ( 50 NULL ,
    
[ Grade ]   [ int ]   NULL ,
    
[ HasSub ]   [ bit ]   NULL ,
    
[ SupMenuCode ]   [ varchar ] ( 50 NULL ,
    
[ EndGrade ]   [ bit ]   NULL ,
    
[ Order ]   [ int ]   NULL ,
    
[ ReqeustUrl ]   [ varchar ] ( 100 NULL ,
    
[ IsItemGroup ]   [ bit ]   NULL ,
    
[ IsControl ]   [ bit ]   NULL ,
 
CONSTRAINT   [ PK_Menu ]   PRIMARY   KEY   CLUSTERED  
(
    
[ AutoID ]   ASC
)
WITH  (PAD_INDEX   =   OFF , STATISTICS_NORECOMPUTE   =   OFF , IGNORE_DUP_KEY  =   OFF , ALLOW_ROW_LOCKS   =   ON , ALLOW_PAGE_LOCKS   =   ON ON   [ PRIMARY ]
ON   [ PRIMARY ]
END
 
      建立好ASP.NET WEB应用程序,并将相关的资源(本文里的资源包括图片、样式、第三方控件等)整理好。数据操作使用Linq To Sql完成,整理好的解决方案如下图示:
            
      本文中系统主控的核心在于RadContrls控件RadMenu和RadTabstrip的组合,导航由RedMenu完成,主控端主要由RadTabstrip完成。要实现一个完美的系统主控,页面的控制和布局都很重要,这里我采用母版页技术将公共的部分放在母版页,通过该母版页建立的内容页来作为系统的主控页面。母版页完整html编码
 
<% @ Master Language = " C# "  AutoEventWireup = " true "  CodeBehind = " MasterPage.master.cs "  Inherits = " Web.MasterPage "   %>
<% @ Register Assembly = " RadMenu.Net2 "  Namespace = " Telerik.WebControls "  TagPrefix = " radM "   %>

< html  xmlns ="http://www.w3.org/1999/xhtml"   >
< head  runat ="server" >
    
< title > 系统主控母版 </ title >
    
< style  type ="text/css" >
        a,body,div,input,li,p,span,td 
{  font-size : 12px ; }
        #headDIV 
{ height : 60px ; width : 100% ; text-align : center ; }
        #contentCenter 
{ width : 100% ; height : 400px ; }
        #stateDIV 
{ width : 100% ; height : 20px ; background-image : url('Images/stateBg.gif') ; bottom : 0px ; }
    
</ style >
    
    
< script  type ="text/javascript" >
    
/*
    * 应用程序加载时根据用户浏览器初始化窗体大小
    
*/
    window.onload 
=   function ()
    {
       
if  (window.screen) 
       { 
          
var  aw  =  screen.width; 
          
var  ah  =  screen.height; 
          window.moveTo(
0 0 ); 
          window.resizeTo(aw, ah); 
       }
    }
    
</ script >
</ head >
< body  id ="Master"  style ="margin: 0px;margin-top:0px;margin-left:20px;margin-right:0px;" >
    
< form  id ="form1"  runat ="server" >
    
< br  />
    
<% -- 头部导航开始 -- %>
    
< div  id ="headDIV" >
        
< span  style ="line-height:30px;" >
            
< radM:RadMenu  ID ="ERPMenu"  runat ="server"
                OnClientMouseOver
="OnMouseOver"  
                OnClientItemClicked
="OnClientClick"  
                Skin
="Web20"  
                ExpandDelay
="100"  
                EnableAutoScroll
="True"   >
                
< CollapseAnimation  Duration ="100"  Type ="InQuint"   />
                
< ExpandAnimation  Duration ="250"   />
            
</ radM:RadMenu >
        
</ span >
    
</ div >
    
<% -- 头部导航结束 -- %>
    
    
<% -- 内容部分开始 -- %>
    
< div  id ="contentCenter" >
        
< div  id ="rightDIV"  style ="height:100%;width:98%;vertical-align:top;float:left;" >
            
< asp:ContentPlaceHolder  ID ="CPHERP"  runat ="server" >
            
</ asp:ContentPlaceHolder >
        
</ div >
    
</ div >
    
<% -- 内容部分结束 -- %>
    
    
<% -- 系统状态栏开始 -- %>
    
< div  id ="stateDIV" >
        
< span  id ="NowTime"  runat ="server"  style ="float:left;margin-left:20px;" ></ span >
        
< span  style ="float:right;margin-right:20px;" >
            当前操作员:admin 
&nbsp;&nbsp; | &nbsp;&nbsp;
            登录系统时间:
<%   =  DateTime.Now.ToString()  %>
        
</ span >
    
</ div >
    
<% -- 系统状态栏结束 -- %>
    
</ form >
</ body >
</ html >
< script  type ="text/javascript" >
// 设置主页的高度和宽度
SetContentHeight();  
SetContentWidth(); 
</ script >
 
      从上面代码中可以发现,里面调用了4个JavaScript方法:两个针对于RadMenu控件的OnMouseOver,OnClientClick,另外两个是设置页面布局效果的方法:SetContentHeight(), SetContentWidth()。他们的作用分别是设置鼠标移动的效果、点击菜单项时所触发的客户端方法,后面两个则是做页面的效果收缩用的,代码如下:
* 程序功能:RadMenu客户端单击事件
* 开发日期: 2008 - 11 - 08  Beniao
* 参数说明:
*           sender:执行请求的当前对象
*           eventArgs:当前对象的事件
*------------------------------------------------
*>>>>> 直接使用硬参数,Url值为相对路径(不加任何前缀修饰)
*/
function  OnClientClick(sender, eventArgs)
{
    
var  value  =  eventArgs.Item.Value;   // 隐藏Url
     var  text  =  eventArgs.Item.Text;      // 显示文本

    
// 设置容器高度
    SetContentHeight();
    
// 关闭菜单项
    CloseItem(sender, eventArgs);
    
    
// 是否为首节点
     if (IsFirstTab(value))
    {
        
// 显示当前页签    
        DisplayCurrentTab(text);
        
return ;
    }
    
    
if (value  !=   ' # ' )
    {
        
// 存在则直接显示(即实现选中)
         if (IsExsitTab(value))
        {
            DisplayCurrentTab(text);
            eventArgs.Item.Blur();
        }
        
else
        {
            
// 是否为动态创建的第一个Tab
            
            
// 不存在,创建新的
            CreateTabPage(value,text);
            eventArgs.Item.Blur();
        }
    }
}

/*
*程序功能:鼠标移入
*开发日期:2008-11-08 13:20 Beniao
*参数说明:
*          sender:执行请求的当前对象
*          eventArgs:当前对象的事件
*/
function  OnMouseOver(sender, eventArgs)
{
    
var  tabStrip  =   <%= RadTabStripMain.ClientID  %> ;
    
var  selectTab  =  tabStrip.SelectedTab;
    
    
// var id = eventArgs.Tab.ID;
     var  id  =  selectTab.ID;
    
var  className  =  document.getElementById(id).className;
    
if (className  ==   " selected " )
    {
        
//
    }
    
else
    {
        document.getElementById(id).firstChild.style.color
= ' #ffffff ' ;
        
// document.getElementById(id).firstChild.style.font-weight='bold';
    }
}
 
// Add by Beniao at 2008-11-07 16:05
//
判断屏幕的高度,然后设置内容的高度
function  SetContentHeight()
{
    
var  screenHeight  =  document.body.clientHeight  +  window.screenTop;
    
    
// 浏览器所支持的屏幕高度
     var  maxh  =  document.body.clientHeight;
    
    
// 获取页面上iframe,主页内容
     var  frame  =  document.getElementById( " frm0 " );
    
// 内容容器(包含页签)
     var  contentDiv  =  document.getElementById( " contentCenter " ); 
    
// 不包含页签
     var  divMain  =  document.getElementById( " divMain " );
    
// 头块
     var  headDiv  =  document.getElementById( " headDIV " );
    
    contentDiv.style.height 
=  maxh;
    
    
if (divMain)
    {
        divMain.style.height 
=  maxh;    
    }
    
    
if (headDiv.style.display  ==   "" )
    {
        divMain.style.height 
=  maxh;
    }
    
else
    {
        
// 隐藏块后,内容快高度增加
        divMain.style.height  =  maxh  +  headDiv.clientHeight;
    }
}

// Add by Beniao at 2008-11-07 16:05
//
判断屏幕的宽度,然后设置内容的宽度
function  SetContentWidth()
{
    
// 屏幕宽度
     var  scrrenWidth  =  document.body.offsetWidth  +  window.screenLeft;
    
var  maxWidth  =  document.body.clientWidth;
    
    
var  frame  =  document.getElementById( " frm0 " );
    
var  contentDiv  =  document.getElementById( " contentCenter " );
    
var  headDiv  =  document.getElementById( " headDIV " ); 
    
var  contentTab  =  document.getElementById( " ContentTab " );
    
    frame.style.width 
=  maxWidth;
    contentDiv.style.width 
=  maxWidth;
}
 
      本文就简单介绍这些,在后续文章里在做详细介绍如何去实现系统主控开发。主控设计最终效果如下图(数据库菜单配置和运行效果图)所示:            
      
      
 
      注:系统主控示例代码在后续文章里提供下载,有需要的朋友可关注后续文章。




本文转自 beniao 51CTO博客,原文链接:http://blog.51cto.com/beniao/253690,如需转载请自行联系原作者

目录
相关文章
|
7月前
|
存储 关系型数据库 MySQL
mysql数据库查询时用到的分页方法有哪些
【8月更文挑战第16天】在MySQL中,实现分页的主要方法包括:1)使用`LIMIT`子句,简单直接但随页数增加性能下降;2)通过子查询优化`LIMIT`分页,提高大页码时的查询效率;3)利用存储过程封装分页逻辑,便于复用但需额外维护;4)借助MySQL变量实现,可能提供更好的性能但实现较复杂。这些方法各有优缺点,可根据实际需求选择适用方案。
678 2
|
7月前
|
数据采集 数据可视化 关系型数据库
【python案例】基于Python 爬虫的房地产数据可视化分析设计与实现
本文设计并实现了一个基于Python爬虫的房地产数据可视化分析系统,通过BeautifulSoup框架采集房源信息,使用pandas进行数据处理,MySQL存储数据,并利用pyecharts进行数据可视化,以帮助用户更直观地了解房源信息并辅助选房购房。
954 4
|
6月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
从Java环境的搭建到实际代码的编写,从基本用法的讲解到底层原理的剖析,深度解析Java基础知识。本文是《Java学习路线》专栏的起始文章,旨在提供一套完整的Java学习路线,覆盖Java基础知识、数据库、SSM/SpringBoot等框架、Redis/MQ等中间件、设计模式、架构设计、性能调优、源码解读、核心面试题等全面的知识点,并在未来不断更新和完善,帮助Java从业者在更短的时间内成长为高级开发。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
|
10月前
|
算法 测试技术 程序员
CompassArena 司南大模型测评--代码编写
CompassArena 司南大模型测评--代码编写
122 1
|
7月前
|
安全 关系型数据库 MySQL
揭秘MySQL海量数据迁移终极秘籍:从逻辑备份到物理复制,解锁大数据迁移的高效与安全之道
【8月更文挑战第2天】MySQL数据量很大的数据库迁移最优方案
1055 17
|
9月前
|
Linux
Linux 系统日常巡检脚本 干货
Linux 系统日常巡检脚本 干货
268 0
|
8月前
|
弹性计算 网络协议 Linux
阿里云主机构建FRP内网穿透家用服务器避坑指南
详述了利用FRP工具搭建内网穿透的流程,包括阿里云ECS的配置、家用服务器的准备、FRP工具的下载与配置,以及通过SSH远程访问本地服务器的解决策略,确保了内外网间的稳定连接。
2055 1
阿里云主机构建FRP内网穿透家用服务器避坑指南
|
10月前
|
NoSQL Redis Windows
windows环境启动redis-server.exe出现闪退问题解决方案(亲测有效)
windows环境启动redis-server.exe出现闪退问题解决方案(亲测有效)
1033 0
|
XML Java 数据格式
自定义标签
自定义标签
|
存储 关系型数据库 MySQL
Mysql 用户管理(创建、删除、改密、授予权限、取消权限)
Mysql 用户管理(创建、删除、改密、授予权限、取消权限)
1016 0