您的位置:首页 > 编程语言

使用 flex4 开发通用统计系统,发布源代码至github

2016-11-24 17:59 609 查看

1,关于flex4 

很老的技术,我居然还再研究使用这个东西,自己想想都不敢相信。
技术存在总是有他的理由的。之所以想用flex4 开发一个通用统计系统,还是有几个有点的:
a,组件比较全,比较全,基本上省去了自己开发
b,在局域网下一次获取大量json数据并解析展示到flex里面速度比html快,图标效果比较好
c,开发系统一个人就够了,浏览器兼容比较好,只要安装flash就行,尤其要做成产品给xp系统的使用那个IE兼容性痛苦啊
当然也有缺点,技术学习成本不低,属于不流行的没落的技术。
但这个不影响做项目,项目的技术选型要合理,维护成本低,综合考虑,而不是所有的全部用新技术,把自己玩死。
存在就有他的意义,不影响做项目,不影响挣钱。

2,系统设计原理

统计系统,设计的不是解决某一个统计问题,而是做一个统计的展示界面,把统计的sql都做xml配置起来。

系统展示界面展示效果:

其中系统的左侧菜单是menu.xml进行控制的
 

Html代码  
<?xml version="1.0" encoding="utf-8"?>  
<!-- 定义左侧菜单: -->  
<menus>  
    <menu label="用户数据统计">  
        <menu label="用户注册统计" module="/assets/flex/DataGrid.swf" id="stat-demo"/>  
        <menu label="用户登陆统计" module="/assets/flex/DataGrid.swf" id="stat-user-reg"/>  
    </menu>  
    <menu label="系统设置">  
        <menu label="菜单管理" module="/assets/flex/DataMenu.swf" />  
        <menu label="数据管理" module="/assets/flex/DataCRUD.swf" />  
    </menu>  
</menus>  

通过配置不同的flash文件可以展示不同的配置显示。
 
通过扩展module可以扩展展示效果。
stat-user-reg.xml配置,显示查询数据
 

Html代码  
<?xml version="1.0" encoding="UTF-8"?>  
<stats>  
    <!-- 统计数据xml 按照id进行查找。-->  
    <stat id="stat-demo-1">  
        <!-- 展示数据 -->  
        <list>  
            <column field="id" text="id"/>  
            <column field="name" text="注册姓名"/>  
            <column field="sex" text="注册性别"/>  
            <column field="city" text="注册城市"/>  
            <column field="phone" text="注册电话"/>  
        </list>  
        <sql><![CDATA[ 
            select id,`name`,sex,city,phone,address,qq,email from stat_demo_01 limit 10 
        ]]></sql>  
    </stat>  
</stats>  

 
显示效果如下:

目前已经完成数据显示。但没有数据查询和分页配置,继续开发。

3,服务端代码

服务端,读取xml中的sql语句和配置,拼接成json数据。
 

Java代码  
/** 
 * User: freewebsys.com 
 */  
@Service("statBaseService")  
public class StatBaseServiceImpl implements StatBaseService {  
  
    @Autowired  
    private StatBaseDao statBaseDao;  
  
    //读取xml文件返回Document。  
    private Document xmlReader(String confXml) {  
        try {  
            SAXReader reader = new SAXReader();  
            return reader.read(IOUtils.toInputStream(confXml));  
        } catch (DocumentException e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
  
    //主函数,负责循环处理节点。  
    public String findStat(String confXml) {  
  
        Document document = xmlReader(confXml);  
        System.out.println(document);  
        List<DefaultElement> list = document.selectNodes("/stats/stat");  
        for (DefaultElement element : list) {  
            mergeStatElement(element);  
        }  
        return document.asXML();  
    }  
  
    private DefaultElement mergeStatElement(DefaultElement element) {  
        System.out.println(element);  
        //处理查询出所有列表显示的元素。  
        List<DefaultElement> columnList = element.selectNodes("list/column");  
  
        //找到查询sql。  
        Node sqlNode = element.selectSingleNode("sql");  
        String sql = sqlNode.getText();  
        //获取数据后将节点删除。在客户端不显示。  
        element.remove(sqlNode);  
        System.out.println(sql);  
  
        List<Map<String, Object>> list = statBaseDao.findStat(sql, null);  
        JSONArray jsonArray = new JSONArray();  
        for (Map<String, Object> tmpData : list) {  
            JSONObject jsonObject = new JSONObject();  
            for (DefaultElement column : columnList) {  
                System.out.println(column);  
                String columnName = column.attributeValue("field");  
                Object objValue = tmpData.get(columnName);  
                jsonObject.put(columnName, objValue);  
                //将一行数据组织成对象,放到数组里面。  
            }  
            jsonArray.add(jsonObject);  
        }  
        DefaultElement elementData = new DefaultElement("data");  
        elementData.add(new DefaultCDATA(jsonArray.toJSONString()));  
        //增加data字段,保存json数据。  
        element.add(elementData);  
        return element;  
    }  
  
    //读取配置文件。  
    public String readConfFile(String configName) {  
        String basePath = StatBaseServiceImpl.class.getResource("/")  
                .toString().replace("file:", "");  
        try {  
            return FileUtils.readFileToString(new File(basePath + configName), "utf-8");  
        } catch (IOException e) {  
            e.printStackTrace();  
            return "";  
        }  
    }  
}  

通过读取xml配置文件,将数据返回
 
 

Html代码  
<?xml version="1.0" encoding="UTF-8"?>  
<stats>  
    <!-- 统计数据xml 按照id进行查找。-->  
    <stat id="stat-demo-1">  
  
        <!-- 展示数据 -->  
        <list>  
            <column field="id" text="id"/>  
            <column field="name" text="注册姓名"/>  
            <column field="sex" text="注册性别"/>  
            <column field="city" text="注册城市"/>  
            <column field="phone" text="注册电话"/>  
        </list>  
          
    <data><![CDATA[[{"city":"city_222","id":1,"name":"222","phone":"1222","sex":"1"}, 
    {"city":"city_33","id":2,"name":"33","phone":"233","sex":"0"}, 
    {"city":"city_33","id":3,"name":"33","phone":"333","sex":"1"}, 
    {"city":"city_45","id":4,"name":"45","phone":"445","sex":"0"}, 
    {"city":"city_6","id":5,"name":"6","phone":"56","sex":"1"}, 
    {"city":"city_7","id":6,"name":"7","phone":"67","sex":"0"}, 
    {"city":"city_8","id":7,"name":"8","phone":"78","sex":"1"}, 
    {"city":"city_9","id":8,"name":"9","phone":"89","sex":"0"}, 
    {"city":"city_9","id":9,"name":"9","phone":"99","sex":"1"}, 
    {"city":"city_11","id":10,"name":"11","phone":"1011","sex":"0"}]]]></data></stat>  
</stats>  

数据包括配置的xml和返回的数据。
 

4,客户端flex4代码

跟新xml返回的数据,动态生成AdvancedDataGridColumn,并添加到 AdvancedDataGrid里面。
 

Html代码  
<?xml version="1.0" encoding="utf-8"?>  
<mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009"   
          xmlns:s="library://ns.adobe.com/flex/spark"   
          xmlns:mx="library://ns.adobe.com/flex/mx"   
          width="100%" height="100%"  initialize="initApp();">  
    <fx:Style source="./assets/main.css" />  
    <fx:Declarations>  
        <mx:HTTPService id="moduleService" method="GET"  
                        resultFormat="e4x" result="resultHandler();"/>  
    </fx:Declarations>  
    <fx:Style>  
        @namespace s "library://ns.adobe.com/flex/spark";  
        @namespace mx "library://ns.adobe.com/flex/mx";  
        mx|Text.headLabelStyle{fontSize:20;fontWeight:bold;}  
    </fx:Style>  
    <fx:Script>  
        <![CDATA[     
            import mx.collections.*; 
            import mx.controls.*; 
            import mx.controls.advancedDataGridClasses.*; 
            import mx.utils.*; 
             
            import spark.components.*; 
             
            private function initApp():void{ 
                try {  
                    /* 删除问号前面的所有内容,包括问号。 */  
                    var myPattern:RegExp = /.*\?/;  
                    var url:String = this.loaderInfo.url.toString(); 
                    //Alert.show(this.loaderInfo.height+","+this.loaderInfo.width); 
                     
                    dataGridGroup.width = this.loaderInfo.width; 
                    //dataGridGroup.height = this.loaderInfo.height; 
                     
                    url = url.replace(myPattern, "");  
                     
                    /* 创建一个形如name=value字符串数组 */  
                    var params:Array = url.split("&");  
                     
                    /* 输出数组中的参数,找到moduleId,这个参数,其他参数类似。 */  
                    var moduleId:String = ""; 
                    for (var key:String in params) {  
                        var value:String = String(params[key]); 
                        if(value.indexOf("moduleId=") >= 0){ 
                            moduleId = value.replace("moduleId=",""); 
                            break; 
                        }  
                    } 
                    //Alert.show(moduleId); 
                    //设置请求地址获取模块参数配置。 
                    moduleService.url = "/stat/module/data.do?moduleId="+moduleId; 
                    moduleService.send(); 
                     
                } catch (e:Error) {  
                    trace(e);  
                }  
                 
                /* 显示loaderInfo的一些有用的信息 */  
                trace("AS version: " + this.loaderInfo.actionScriptVersion);  
                //trace("App height: " + this.loaderIno.height);  
                //trace("App width: " + this.loaderInffo.width);  
                trace("App bytes: " + this.loaderInfo.bytesTotal);  
            } 
             
            private function genWhere(dataXml:XML):HGroup{ 
                var hgroup:HGroup = new HGroup(); 
                //保证居中和左对齐。 
                hgroup.verticalAlign="middle" 
                hgroup.horizontalAlign = "left"; 
                 
                //Alert.show(dataXml.where.column); 
                for each(var objWhere:Object in dataXml.where.column){ 
                    var field:String = objWhere.@field; 
                    var text:String = objWhere.@text; 
                     
                    var inputLabel:spark.components.Label = new spark.components.Label(); 
                    inputLabel.text = text; 
                    hgroup.addElement(inputLabel); 
                    var input:spark.components.TextInput = new spark.components.TextInput(); 
                    input.id = field; 
                    hgroup.addElement(input); 
                    var sp:Spacer = new Spacer(); 
                    sp.width = 10; 
                    hgroup.addElement(sp); 
                } 
                //如果存在where数据则增加查询按钮。 
                if(dataXml.where.column.length() > 0){ 
                    var search:spark.components.Button = new spark.components.Button(); 
                    search.label = "查询"; 
                    hgroup.addElement(search); 
                } 
                return hgroup; 
            } 
             
            //动态生成 AdvancedDataGrid 数据表单. 
            private function genAdvancedDataGrid(dataXml:XML):AdvancedDataGrid{ 
                //Alert.show(menuList.source.columns.column); 
                //Alert.show(menuList.source.data); 
                //格式化json数据。将数据转换成数组。放到DataGrid里面。 
                var tmpArray:Array = (JSON.parse(dataXml.data) as Array); 
                //Alert.show(array.length()); 
                var dataArray:ArrayCollection = new ArrayCollection(tmpArray); 
                 
                //#######################设置列表显示顶部标题. 
                var columnArray:Array = new Array(); 
                for each(var objColumn:Object in dataXml.list.column){ 
                    var dataField:String = objColumn.@field; 
                    var headerText:String = objColumn.@text; 
                    var width:String = objColumn.@width; 
                    //设置DataGridColun标题,和显示属性。 
                    var adColumn:AdvancedDataGridColumn  = new AdvancedDataGridColumn(dataField); 
                    adColumn.headerText = headerText; 
                    if(width){ 
                        adColumn.width = Number(width); 
                    } 
                    columnArray.push(adColumn); 
                } 
                //adg1.columns(); 
                //adg1.columnCount(); 
                //adg1.columns(columnArray); 
                 
                var adg:AdvancedDataGrid = new AdvancedDataGrid(); 
                adg.id = "adg-"+id; 
                 
                adg.dataProvider = dataArray; 
                adg.columns = columnArray; 
                adg.rowCount = tmpArray.length + 1; 
                return adg; 
            } 
             
            //请求数据成功之后处理动态生成表格。 
            private function resultHandler():void{ 
                 
                for each(var obj:Object in moduleService.lastResult.stat){ 
                    var dataXml:XML = obj as XML; 
                    //获得模板id,标题. 
                    var id:String = dataXml.@id; 
                    var title:String = dataXml.@title; 
                     
                    //设置 
                    var vgroup:VGroup = new VGroup(); 
                    //设置内边距15。                       
                    vgroup.paddingTop = 15; 
                    vgroup.paddingLeft = 15; 
                    vgroup.paddingRight = 15; 
                    vgroup.paddingBottom =  15; 
                    //设置标题。 
                    var titleText:Text = new Text(); 
                    titleText.text = title; 
                    titleText.styleName = "headLabelStyle"; 
                    vgroup.addElement(titleText); 
                     
                    var hgroup:HGroup = genWhere(dataXml); 
                    vgroup.addElement(hgroup); 
                    //生成高级表格。 
                    var adg:AdvancedDataGrid = genAdvancedDataGrid(dataXml); 
                    vgroup.addElement(adg); 
                     
                    dataGridGroup.addElement(vgroup); 
                } 
                 
                 
            } 
        ]]>  
    </fx:Script>  
    <!-- 设置如果超过高度滚动. -->  
    <s:VGroup id="dataGridGroup" height="100%"/>  
      
</mx:Module>  

 

5,后续&代码

 
这只是最简单的应用,功能还需要完善。
代码已经放到github上面了。  https://github.com/freewebsys/flex4-stat
工程需要使用flahs builder 打开。

 
这个也发布到csdn上面了: http://blog.csdn.net/freewebsys/article/details/39137035  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐