刚刚做了几个政府项目,说说我的一些经验:
政府通常分级管理,划分为:州、县、市等,划分为部门,每一级政府单位负责不同的任务,可称为“角色”,其工作人员属于一个行政区划,拥有一个或多个角色。
一般政府部门,上级单位可以管理下级数据,所以,使用增量编码器比较简单,比如330102,33(州),01(县),02(市),用:xxx like '3301%'访问到3301个县(含街道)的数据;每个角色都有多个菜单项,非常简单的权限系统,不再赘述。
另外,关于自定义字段,需要添加一个元数据字典,里面存储了每个报表字段,每个字段都有一个指定属性属于哪个行政区划,当用户登录时,根据用户所在行政区划检索对应的Fields列表. 由于不同的部分查看不同的报表,所以不需要额外的字段。
以上是我遇到的情况,可能不符合你的情况,仅供参考。
补充:
我使用Asp.net 2.0技术,数据库使用Oracle(客户要求)。使用WebForm生成用户界面,不使用任何其他框架。因为其他框架有学习成本,需求变化大都需要Coding。我想实现当需求有变化时,客户可以调整,不依赖任何其他工具和环境。
Asp.net,我用得最多的是它的WebUserControl(ascx)。我把用户界面定义存储在数据库中,当用户打开文档(报告)时,生成用户控件,然后组合成WebForm。
//public class Common_CustomBill:Page
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//User Interface Definition retrieved from the database
LoadBillItems();
foreach(DataRow ARow in BillItems.Rows)
{
HtmlTableCell ACell = new HtmlTableCell();
HtmlTableRow ATableRow = new HtmlTableRow();
ATableRow.Cells.Add(ACell);
//Depending on the type load control
NovaNet.WebBase.BillItem AItem = LoadControl("BillItem/" + ARow["type"].ToString() + ".ascx") as NovaNet.WebBase.BillItem;
AItem.OrderId = ARow["OrderId"].ToString();
AItem.ID = string.Format("C{0:X}{1}", Session.SessionID.GetHashCode(), ARow["OrderId"]);
if(P.OftenFunction.SafeToString(ARow["Border"]) == "none")
{
ACell.Controls.Add(AItem);
}
else
{
HtmlGenericControl FIELDSET = new HtmlGenericControl("FIELDSET");
HtmlGenericControl Legend = new HtmlGenericControl("legend");
FIELDSET.Controls.Add(Legend);
Legend.InnerHtml = ARow["label"].ToString();
FIELDSET.Controls.Add(AItem);
ACell.Controls.Add(FIELDSET);
}
tabMain.Rows.Add(ATableRow);
AItem.BillData = Data;
//initialize the control
AItem.InitiData(ARow["content"] as byte[],ModuleName);
}
}
用户控件初始化后,不同类型的用户控件表现不同。例如,多选控件初始化 CheckBoxList Items 属性。特殊的自定义类型控件,初始化生成并加载到单独的 ascx 文件中。
public partial class Common_BillItem_CustomControl:NovaNet.WebBase.BillItem
{
public override void OnInitiData()
{
base.OnInitiData();
//FData is incoming "initialization data"
string Value = FData["code"].ToString();
//Disk file generated
string AFileName = "~/Temp/" + ModuleName +"_"+ Value.GetHashCode().ToString("X") + ".ascx";
if(!Directory.Exists(Path.GetDirectoryName(Server.MapPath(AFileName))))
Directory.CreateDirectory(Path.GetDirectoryName(Server.MapPath(AFileName)));
if(!File.Exists(Server.MapPath(AFileName)))
{
using (StreamWriter AWriter = new StreamWriter(Server.MapPath(AFileName),false, System.Text.Encoding.UTF8))
{
AWriter.Write(Value);
AWriter.Close();
}
}
//Loaded into the interface
Controls.Add(LoadControl(AFileName));
}
}
IIS动态编译很棒。加载“ascx文件”生成“dll文件”,按照直接加载“dll文件”。