使用 flex4 開發通用統計系統,釋出原始碼至github

心靈小公寓發表於2016-11-24

1,關於flex4 

很老的技術,我居然還再研究使用這個東西,自己想想都不敢相信。

技術存在總是有他的理由的。之所以想用flex4 開發一個通用統計系統,還是有幾個有點的:

a,元件比較全,比較全,基本上省去了自己開發

b,在區域網下一次獲取大量json資料並解析展示到flex裡面速度比html快,圖示效果比較好

c,開發系統一個人就夠了,瀏覽器相容比較好,只要安裝flash就行,尤其要做成產品給xp系統的使用那個IE相容性痛苦啊

當然也有缺點,技術學習成本不低,屬於不流行的沒落的技術。

但這個不影響做專案,專案的技術選型要合理,維護成本低,綜合考慮,而不是所有的全部用新技術,把自己玩死。

存在就有他的意義,不影響做專案,不影響掙錢。

2,系統設計原理

統計系統,設計的不是解決某一個統計問題,而是做一個統計的展示介面,把統計的sql都做xml配置起來。

系統展示介面展示效果:

其中系統的左側選單是menu.xml進行控制的

 

Html程式碼  
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!-- 定義左側選單: -->  
  3. <menus>  
  4.     <menu label="使用者資料統計">  
  5.         <menu label="使用者註冊統計" module="/assets/flex/DataGrid.swf" id="stat-demo"/>  
  6.         <menu label="使用者登陸統計" module="/assets/flex/DataGrid.swf" id="stat-user-reg"/>  
  7.     </menu>  
  8.     <menu label="系統設定">  
  9.         <menu label="選單管理" module="/assets/flex/DataMenu.swf" />  
  10.         <menu label="資料管理" module="/assets/flex/DataCRUD.swf" />  
  11.     </menu>  
  12. </menus>  


通過配置不同的flash檔案可以展示不同的配置顯示。

 

通過擴充套件module可以擴充套件展示效果。

stat-user-reg.xml配置,顯示查詢資料

 

Html程式碼  
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <stats>  
  3.     <!-- 統計資料xml 按照id進行查詢。-->  
  4.     <stat id="stat-demo-1">  
  5.         <!-- 展示資料 -->  
  6.         <list>  
  7.             <column field="id" text="id"/>  
  8.             <column field="name" text="註冊姓名"/>  
  9.             <column field="sex" text="註冊性別"/>  
  10.             <column field="city" text="註冊城市"/>  
  11.             <column field="phone" text="註冊電話"/>  
  12.         </list>  
  13.         <sql><![CDATA[ 
  14.             select id,`name`,sex,city,phone,address,qq,email from stat_demo_01 limit 10 
  15.         ]]></sql>  
  16.     </stat>  
  17. </stats>  

 

顯示效果如下:

目前已經完成資料顯示。但沒有資料查詢和分頁配置,繼續開發。

3,服務端程式碼

服務端,讀取xml中的sql語句和配置,拼接成json資料。

 

Java程式碼  
  1. /** 
  2.  * User: freewebsys.com 
  3.  */  
  4. @Service("statBaseService")  
  5. public class StatBaseServiceImpl implements StatBaseService {  
  6.   
  7.     @Autowired  
  8.     private StatBaseDao statBaseDao;  
  9.   
  10.     //讀取xml檔案返回Document。  
  11.     private Document xmlReader(String confXml) {  
  12.         try {  
  13.             SAXReader reader = new SAXReader();  
  14.             return reader.read(IOUtils.toInputStream(confXml));  
  15.         } catch (DocumentException e) {  
  16.             e.printStackTrace();  
  17.             return null;  
  18.         }  
  19.     }  
  20.   
  21.     //主函式,負責迴圈處理節點。  
  22.     public String findStat(String confXml) {  
  23.   
  24.         Document document = xmlReader(confXml);  
  25.         System.out.println(document);  
  26.         List<DefaultElement> list = document.selectNodes("/stats/stat");  
  27.         for (DefaultElement element : list) {  
  28.             mergeStatElement(element);  
  29.         }  
  30.         return document.asXML();  
  31.     }  
  32.   
  33.     private DefaultElement mergeStatElement(DefaultElement element) {  
  34.         System.out.println(element);  
  35.         //處理查詢出所有列表顯示的元素。  
  36.         List<DefaultElement> columnList = element.selectNodes("list/column");  
  37.   
  38.         //找到查詢sql。  
  39.         Node sqlNode = element.selectSingleNode("sql");  
  40.         String sql = sqlNode.getText();  
  41.         //獲取資料後將節點刪除。在客戶端不顯示。  
  42.         element.remove(sqlNode);  
  43.         System.out.println(sql);  
  44.   
  45.         List<Map<String, Object>> list = statBaseDao.findStat(sql, null);  
  46.         JSONArray jsonArray = new JSONArray();  
  47.         for (Map<String, Object> tmpData : list) {  
  48.             JSONObject jsonObject = new JSONObject();  
  49.             for (DefaultElement column : columnList) {  
  50.                 System.out.println(column);  
  51.                 String columnName = column.attributeValue("field");  
  52.                 Object objValue = tmpData.get(columnName);  
  53.                 jsonObject.put(columnName, objValue);  
  54.                 //將一行資料組織成物件,放到陣列裡面。  
  55.             }  
  56.             jsonArray.add(jsonObject);  
  57.         }  
  58.         DefaultElement elementData = new DefaultElement("data");  
  59.         elementData.add(new DefaultCDATA(jsonArray.toJSONString()));  
  60.         //增加data欄位,儲存json資料。  
  61.         element.add(elementData);  
  62.         return element;  
  63.     }  
  64.   
  65.     //讀取配置檔案。  
  66.     public String readConfFile(String configName) {  
  67.         String basePath = StatBaseServiceImpl.class.getResource("/")  
  68.                 .toString().replace("file:""");  
  69.         try {  
  70.             return FileUtils.readFileToString(new File(basePath + configName), "utf-8");  
  71.         } catch (IOException e) {  
  72.             e.printStackTrace();  
  73.             return "";  
  74.         }  
  75.     }  
  76. }  


通過讀取xml配置檔案,將資料返回

 

 

Html程式碼  
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <stats>  
  3.     <!-- 統計資料xml 按照id進行查詢。-->  
  4.     <stat id="stat-demo-1">  
  5.   
  6.         <!-- 展示資料 -->  
  7.         <list>  
  8.             <column field="id" text="id"/>  
  9.             <column field="name" text="註冊姓名"/>  
  10.             <column field="sex" text="註冊性別"/>  
  11.             <column field="city" text="註冊城市"/>  
  12.             <column field="phone" text="註冊電話"/>  
  13.         </list>  
  14.           
  15.     <data><![CDATA[[{"city":"city_222","id":1,"name":"222","phone":"1222","sex":"1"}, 
  16.     {"city":"city_33","id":2,"name":"33","phone":"233","sex":"0"}, 
  17.     {"city":"city_33","id":3,"name":"33","phone":"333","sex":"1"}, 
  18.     {"city":"city_45","id":4,"name":"45","phone":"445","sex":"0"}, 
  19.     {"city":"city_6","id":5,"name":"6","phone":"56","sex":"1"}, 
  20.     {"city":"city_7","id":6,"name":"7","phone":"67","sex":"0"}, 
  21.     {"city":"city_8","id":7,"name":"8","phone":"78","sex":"1"}, 
  22.     {"city":"city_9","id":8,"name":"9","phone":"89","sex":"0"}, 
  23.     {"city":"city_9","id":9,"name":"9","phone":"99","sex":"1"}, 
  24.     {"city":"city_11","id":10,"name":"11","phone":"1011","sex":"0"}]]]></data></stat>  
  25. </stats>  


資料包括配置的xml和返回的資料。

 

4,客戶端flex4程式碼

跟新xml返回的資料,動態生成AdvancedDataGridColumn,並新增到 AdvancedDataGrid裡面。

 

Html程式碼  
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009"   
  3.           xmlns:s="library://ns.adobe.com/flex/spark"   
  4.           xmlns:mx="library://ns.adobe.com/flex/mx"   
  5.           width="100%" height="100%"  initialize="initApp();">  
  6.     <fx:Style source="./assets/main.css" />  
  7.     <fx:Declarations>  
  8.         <mx:HTTPService id="moduleService" method="GET"  
  9.                         resultFormat="e4x" result="resultHandler();"/>  
  10.     </fx:Declarations>  
  11.     <fx:Style>  
  12.         @namespace s "library://ns.adobe.com/flex/spark";  
  13.         @namespace mx "library://ns.adobe.com/flex/mx";  
  14.         mx|Text.headLabelStyle{fontSize:20;fontWeight:bold;}  
  15.     </fx:Style>  
  16.     <fx:Script>  
  17.         <![CDATA[     
  18.             import mx.collections.*; 
  19.             import mx.controls.*; 
  20.             import mx.controls.advancedDataGridClasses.*; 
  21.             import mx.utils.*; 
  22.              
  23.             import spark.components.*; 
  24.              
  25.             private function initApp():void{ 
  26.                 try {  
  27.                     /* 刪除問號前面的所有內容,包括問號。 */  
  28.                     var myPattern:RegExp = /.*\?/;  
  29.                     var url:String = this.loaderInfo.url.toString(); 
  30.                     //Alert.show(this.loaderInfo.height+","+this.loaderInfo.width); 
  31.                      
  32.                     dataGridGroup.width = this.loaderInfo.width; 
  33.                     //dataGridGroup.height = this.loaderInfo.height; 
  34.                      
  35.                     url = url.replace(myPattern, "");  
  36.                      
  37.                     /* 建立一個形如name=value字串陣列 */  
  38.                     var params:Array = url.split("&");  
  39.                      
  40.                     /* 輸出陣列中的引數,找到moduleId,這個引數,其他引數類似。 */  
  41.                     var moduleId:String = ""; 
  42.                     for (var key:String in params) {  
  43.                         var value:String = String(params[key]); 
  44.                         if(value.indexOf("moduleId=") >= 0){ 
  45.                             moduleId = value.replace("moduleId=",""); 
  46.                             break; 
  47.                         }  
  48.                     } 
  49.                     //Alert.show(moduleId); 
  50.                     //設定請求地址獲取模組引數配置。 
  51.                     moduleService.url = "/stat/module/data.do?moduleId="+moduleId; 
  52.                     moduleService.send(); 
  53.                      
  54.                 } catch (e:Error) {  
  55.                     trace(e);  
  56.                 }  
  57.                  
  58.                 /* 顯示loaderInfo的一些有用的資訊 */  
  59.                 trace("AS version: " + this.loaderInfo.actionScriptVersion);  
  60.                 //trace("App height: " + this.loaderIno.height);  
  61.                 //trace("App width: " + this.loaderInffo.width);  
  62.                 trace("App bytes: " + this.loaderInfo.bytesTotal);  
  63.             } 
  64.              
  65.             private function genWhere(dataXml:XML):HGroup{ 
  66.                 var hgroup:HGroup = new HGroup(); 
  67.                 //保證居中和左對齊。 
  68.                 hgroup.verticalAlign="middle" 
  69.                 hgroup.horizontalAlign = "left"; 
  70.                  
  71.                 //Alert.show(dataXml.where.column); 
  72.                 for each(var objWhere:Object in dataXml.where.column){ 
  73.                     var field:String = objWhere.@field; 
  74.                     var text:String = objWhere.@text; 
  75.                      
  76.                     var inputLabel:spark.components.Label = new spark.components.Label(); 
  77.                     inputLabel.text = text; 
  78.                     hgroup.addElement(inputLabel); 
  79.                     var input:spark.components.TextInput = new spark.components.TextInput(); 
  80.                     input.id = field; 
  81.                     hgroup.addElement(input); 
  82.                     var sp:Spacer = new Spacer(); 
  83.                     sp.width = 10; 
  84.                     hgroup.addElement(sp); 
  85.                 } 
  86.                 //如果存在where資料則增加查詢按鈕。 
  87.                 if(dataXml.where.column.length() > 0){ 
  88.                     var search:spark.components.Button = new spark.components.Button(); 
  89.                     search.label = "查詢"; 
  90.                     hgroup.addElement(search); 
  91.                 } 
  92.                 return hgroup; 
  93.             } 
  94.              
  95.             //動態生成 AdvancedDataGrid 資料表單. 
  96.             private function genAdvancedDataGrid(dataXml:XML):AdvancedDataGrid{ 
  97.                 //Alert.show(menuList.source.columns.column); 
  98.                 //Alert.show(menuList.source.data); 
  99.                 //格式化json資料。將資料轉換成陣列。放到DataGrid裡面。 
  100.                 var tmpArray:Array = (JSON.parse(dataXml.data) as Array); 
  101.                 //Alert.show(array.length()); 
  102.                 var dataArray:ArrayCollection = new ArrayCollection(tmpArray); 
  103.                  
  104.                 //#######################設定列表顯示頂部標題. 
  105.                 var columnArray:Array = new Array(); 
  106.                 for each(var objColumn:Object in dataXml.list.column){ 
  107.                     var dataField:String = objColumn.@field; 
  108.                     var headerText:String = objColumn.@text; 
  109.                     var width:String = objColumn.@width; 
  110.                     //設定DataGridColun標題,和顯示屬性。 
  111.                     var adColumn:AdvancedDataGridColumn  = new AdvancedDataGridColumn(dataField); 
  112.                     adColumn.headerText = headerText; 
  113.                     if(width){ 
  114.                         adColumn.width = Number(width); 
  115.                     } 
  116.                     columnArray.push(adColumn); 
  117.                 } 
  118.                 //adg1.columns(); 
  119.                 //adg1.columnCount(); 
  120.                 //adg1.columns(columnArray); 
  121.                  
  122.                 var adg:AdvancedDataGrid = new AdvancedDataGrid(); 
  123.                 adg.id = "adg-"+id; 
  124.                  
  125.                 adg.dataProvider = dataArray; 
  126.                 adg.columns = columnArray; 
  127.                 adg.rowCount = tmpArray.length + 1; 
  128.                 return adg; 
  129.             } 
  130.              
  131.             //請求資料成功之後處理動態生成表格。 
  132.             private function resultHandler():void{ 
  133.                  
  134.                 for each(var obj:Object in moduleService.lastResult.stat){ 
  135.                     var dataXml:XML = obj as XML; 
  136.                     //獲得模板id,標題. 
  137.                     var id:String = dataXml.@id; 
  138.                     var title:String = dataXml.@title; 
  139.                      
  140.                     //設定 
  141.                     var vgroup:VGroup = new VGroup(); 
  142.                     //設定內邊距15。                       
  143.                     vgroup.paddingTop = 15; 
  144.                     vgroup.paddingLeft = 15; 
  145.                     vgroup.paddingRight = 15; 
  146.                     vgroup.paddingBottom =  15; 
  147.                     //設定標題。 
  148.                     var titleText:Text = new Text(); 
  149.                     titleText.text = title; 
  150.                     titleText.styleName = "headLabelStyle"; 
  151.                     vgroup.addElement(titleText); 
  152.                      
  153.                     var hgroup:HGroup = genWhere(dataXml); 
  154.                     vgroup.addElement(hgroup); 
  155.                     //生成高階表格。 
  156.                     var adg:AdvancedDataGrid = genAdvancedDataGrid(dataXml); 
  157.                     vgroup.addElement(adg); 
  158.                      
  159.                     dataGridGroup.addElement(vgroup); 
  160.                 } 
  161.                  
  162.                  
  163.             } 
  164.         ]]>  
  165.     </fx:Script>  
  166.     <!-- 設定如果超過高度滾動. -->  
  167.     <s:VGroup id="dataGridGroup" height="100%"/>  
  168.       
  169. </mx:Module>  


 

5,後續&程式碼

 

這只是最簡單的應用,功能還需要完善。

程式碼已經放到github上面了。  https://github.com/freewebsys/flex4-stat

工程需要使用flahs builder 開啟。

 

這個也釋出到csdn上面了:

http://blog.csdn.net/freewebsys/article/details/39137035

 

相關文章