`

Flex4之DataGrid示例【客户端和服务器端]

阅读更多

由于我的DataGrid与JAVA后台交互需要返回JSON格式的字符串,所以需要在客户端来解析JSON串,用到JSON相关类,所以Flex4还缺少一个文件corelib.swc
将corelib.swc拷贝到Flex安装目录的sdks\4.0.0\frameworks\libs下

这个文件导入后重启MyEclipse就可以使用JSON类了

 

1,客户端、服务端

  (1)客户端分页:将数据一次性取到客户端,客户要看哪一页的数据,显示哪一页的数据。

  (2)服务端分页:客户要看哪一页的数据,向服务端请求哪一页的数据,客户端将请求到的数据显示给用户(可以在客户端、服务端分别做缓存,加快数据的读取),由于flex本身不具有数据库访问能力,可以考虑通过 WebServices向服务器传递数据,数据的表示形式可以是XML、JSON(本文采用XML的形式)

2,分页表示层的设计

  (1)页码条中4个按钮;这四个按钮分别为转到第一页,前一页,后一页,最后一页;当这四个按钮中的任意一点被点击时,页码要重绘,当前页码变化;且还要考虑当页码中有第一页时,前两个按钮要隐藏起来;当页码中有最后一页时,后两个按钮要隐藏起来。

  (2)页码条中页码;当点击页码条中的页码时,DataGrid中更新显示数据即可,当前页码变化。
 (3)显示总页数,总记录数;

  (4)每页记录数,让用户通过下拉框选择;当用户选择新的每页显示记录数时,页码要重绘,总页数发生变化,当前页码变化。

  (5)页码输入框,让用户输入任意页码(要检查输入数据是否合法),DataGrid显示页码中的数据,页码要重绘,总页数变化。

  (6)查看所有;分页中的特殊情况,将每页记数置为记录总数即可达到要求!页码要重绘,总页数发生变化,当前页码变化

代码说明
(1)分页功能条,做一个自定义组件
(2)页码条绘制方法,传参数为页码中的第一个页码
3.分页触发的方法,组件中有一个属性为pagingFunction,为向服务端请求数据的函数;当该函数为空时,调用客户端分页;反之调用该方法进行服务端分页。

 

首先说明下:以下的四个例子中每一个都含有客户端获取DataGrid数据的代码

下面的每个mxml中都涉及用到的组件mxml,位于com/control目录下

<?xml version="1.0" encoding="utf-8"?>
<s:HGroup 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="400" height="300">
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;  
			import mx.events.ItemClickEvent;  
			import flash.events.KeyboardEvent;  
			import mx.controls.DataGrid;  
			import mx.validators.NumberValidator;  
			
			[Bindable]  
			/* [Embed(source='assets/first.gif',mimeType='image/gif')] */
			private var firstIcon:Class;                  
			private var firstPage:uint;   
			
			[Bindable]  
			/* [Embed(source='assets/pre.gif',mimeType='image/gif')] */
			private var preIcon:Class;  
			private var prePage:uint;   
			
			[Bindable]  
			/* [Embed(source='assets/next.gif',mimeType='image/gif')] */
			private var nextIcon:Class;  
			private var nextPage:uint;   
			
			[Bindable]  
			/* [Embed(source='assets/last.gif',mimeType='image/gif')]   */
			private var lastIcon:Class;  
			private var lastPage:uint;  
			
			//页码条数据,绑定  
			[Bindable]  
			private var nav:ArrayCollection = new ArrayCollection();  
			
			//默认起始页码,第1页  
			private var currentPageIndex:uint = 0;  
			
			//是否已初始化  
			private var isInit:Boolean=true;                    
			
			//总页数  
			private var totalPages:uint = 0;  
			
			//是否重绘页码条,当使用服务端分页时使用  
			private var isCreateNavBar:Boolean = true;  
			
			/************************************************************/  
			
			//显示到Grid的数据  
			[Bindable]  
			public var viewData:ArrayCollection=null;  
			
			//所有的数据  
			public var orgData:ArrayCollection=null;  
			
			//每页记录数下拉框  
			public var pageSizeDropDownListData:ArrayCollection=null;  
			
			// 每页记录数   
			public var pageSize:uint = 5;   
			
			// 页码条上显示页码的个数  
			public var navSize:uint = 5;  
			
			//记录总数,调用服务端发页时使用  
			public var totalRecord:int=0;  
			
			//分页函数  
			public var pagingFunction:Function=null;  
			
			//分页条对应的Grid  
			public var dataGrid:DataGrid=null;  
			
			/***************************************************************/  
			
			public function dataBind(isServerSide:Boolean=false):void{  
				//是否初始化  
				if(isInit){  
					if(pageSizeDropDownListData==null){  
						pageSizeDropDownListData = new ArrayCollection();  
						pageSizeDropDownListData.addItem({label:5,data:5});  
						pageSizeDropDownListData.addItem({label:10,data:10});  
						pageSizeDropDownListData.addItem({label:20,data:20});  
						pageSizeDropDownListData.addItem({label:30,data:30});                             
					}  
					pageSizeComobox.dataProvider=pageSizeDropDownListData;  
					isInit=false;  
				}  
				//                                                                
				refreshDataProvider(currentPageIndex,isCreateNavBar,pageSize,isServerSide);  
			}  
			
			
			
			/**  
			 * 构建页码条  
			 * pages:总页数  
			 * pageIndex:当前页(注意,从0开始)  
			 *  
			 */  
			private function createNavBar(pageIndex:uint = 0):void{  
				nav.removeAll();  
				//向前图标操作,first,Pre  
				if( pageIndex > 1 ){  
					firstPage=0;  
					firstNavBtn.visible=true;  
					//  
					var intLFive:int = pageIndex-navSize; // calculate start of last 5;  
					//  
					prePage=intLFive;  
					preNavBtn.visible=true;  
				}  
				else{  
					firstNavBtn.visible=false;  
					preNavBtn.visible=false;  
				}  
				//页码条          
				for( var x:uint = 0; x < navSize; x++){  
					var pg:uint = x + pageIndex;  
					nav.addItem({label: pg + 1,data: pg});  
					//    
					var pgg:uint = pg+1;  
					if(pgg>=totalPages){ //搜索到最后一个页码,停止添加到navbar  
						x=navSize;   
					}  
				}  
				//计算最后一组页码条中第一个页码的页码编号  
				var lastpage:Number = 0;  
				for( var y:uint = navSize; y <= totalPages-1;y = y + navSize ){ //lets calculate the lastpage button  
					if(y+5 > navSize){  
						lastpage = y;  
					}  
				}                     
				//向后图标  
				if( pg < totalPages - 1 ){  
					nextPage=pg + 1;  
					nextNavBtn.visible=true;  
					lastPage=lastpage;  
					lastNavBtn.visible=true;  
				}  
				else{                                
					nextNavBtn.visible=false;  
					lastNavBtn.visible=false;  
				}  
			}  
			
			/**  
			 * 页码按钮按下(页码条点击)  
			 */   
			private function navigatePage(event:ItemClickEvent):void  
			{  
				refreshDataProvider(event.item.data,false);     
			}  
			
			/**  
			 * 页码按钮按下,first,pre,next,last  
			 */   
			private function navigateButtonClick(pageString:String):void{  
				var pageIndex:uint=0;  
				switch(pageString){  
					case "firstPage":  
						pageIndex=firstPage;  
						break;  
					case "prePage":  
						pageIndex=prePage;  
						break;  
					case "nextPage":  
						pageIndex=nextPage;  
						break;  
					default:    //lastPage  
						pageIndex=lastPage;  
				}  
				//  
				refreshDataProvider(pageIndex);  
			}  
			
			/**  
			 * 更新数据源,更新表格显示数据  
			 */   
			private function refreshDataProvider(pageIndex:uint,isCreateNavBar:Boolean=true,pageSize:uint=0,resultReturn:Boolean=false):void{  
				//分页函数  
				if(dataGrid==null) return;  
				currentPageIndex=pageIndex;  
				if(pageSize==0){  
					pageSize=this.pageSize;   
				}else{  
					this.pageSize=pageSize;  
					if(!resultReturn) totalPages = Math.ceil(orgData.length/pageSize);  
				}                     
				if(!resultReturn){                                                                                  
					if(this.pagingFunction!=null){  
						pagingFunction(pageIndex,pageSize);  
						this.isCreateNavBar=isCreateNavBar;   
					}  
					else{  
						viewData = new ArrayCollection( orgData.source.slice((pageIndex * pageSize),(pageIndex * pageSize) + pageSize) );                     
						dataGrid.dataProvider=viewData;  
						pageNumber.text=(pageIndex+1).toString();  
						
						totalRecordLabel.text = '总记录数:' + orgData.length.toString();                                                            
					}  
				}  
				else{  
					dataGrid.dataProvider=orgData;  
					totalPages = Math.ceil(totalRecord/pageSize);  
					pageNumber.text=(pageIndex+1).toString();  
					totalRecordLabel.text = '总记录数:' + totalRecord.toString()              
				}  
				totalPagesLabel.text = '总页数:' + totalPages;  
				if(isCreateNavBar) createNavBar(pageIndex);  
			}  
			//  
			/**  
			 * 每页记录数变更(下拉框选择)  
			 */   
			private function pageSizeSelectChange():void{  
				refreshDataProvider(0,true,uint(pageSizeComobox.value));  
			}                  
			/**  
			 * 页码变更(直接输入)  
			 */   
			private function pageIndexInsertChange(event:Event):void{  
				var keyboardEvent:KeyboardEvent=event as KeyboardEvent;  
				if(keyboardEvent!=null&&keyboardEvent.keyCode== Keyboard.ENTER){  
					var pageIndex:uint=uint(pageNumber.text)-1;  
					if(pageIndex>0&&pageIndex<totalPages&&pageIndex!=currentPageIndex){  
						refreshDataProvider(pageIndex);  
					}  
					else{                                 
						pageNumber.text = (currentPageIndex+1).toString();  
					}  
				}  
			}       
			/**  
			 * 查看所有  
			 */   
			private function viewAll():void{  
				var tempTotalRecord:uint=0;                 
				if(pagingFunction!=null) tempTotalRecord=totalRecord;  
				else tempTotalRecord=orgData.length;  
				//  
				pageSizeComobox.text=tempTotalRecord.toString();  
				pageSizeComobox.selectedIndex=-1;  
				refreshDataProvider(0,true,tempTotalRecord);  
			}
		]]>
	</fx:Script>
	<mx:HBox paddingTop="8">  
		<mx:Button id="firstNavBtn" icon="{firstIcon}" width="10" height="10" click="navigateButtonClick('firstPage');" />  
		<mx:Button id="preNavBtn" icon="{preIcon}" width="7" height="10" click="navigateButtonClick('prePage');"/>  
	</mx:HBox>  
	<mx:LinkBar id="pageNav" itemClick="navigatePage(event)" dataProvider="{nav}"/>  
	<mx:HBox paddingTop="8">  
		<mx:Button id="nextNavBtn" icon="{nextIcon}" width="7" height="10" click="navigateButtonClick('nextPage');"/>  
		<mx:Button id="lastNavBtn" icon="{lastIcon}" width="10" height="10" click="navigateButtonClick('lastPage');"/>  
	</mx:HBox>  
	<mx:VRule height="25"/>  
	<mx:Label paddingTop="3" id="totalPagesLabel" text=""/>  
	<mx:Label paddingTop="3" id="totalRecordLabel" text=""/>  
	<mx:Label paddingTop="3" text="每页记录:"/>  
	<mx:ComboBox id="pageSizeComobox" cornerRadius="0" paddingLeft="0" fontWeight="normal" width="50" arrowButtonWidth="10" change="pageSizeSelectChange()"/>  
	<mx:Label paddingTop="3" text="页码:"/>  
	<mx:TextInput id="pageNumber" width="40" keyDown="pageIndexInsertChange(event);"/>  
	<mx:LinkButton id="viewAllLinkBtn" label="查看所有" click="viewAll();"/> 
</s:HGroup>

 第一:  HTTPService获取服务器端数据显示DataGrid

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:control="com.control.*" 
			   creationComplete="creationCompleteHandle();myservice.send()"
			   minWidth="955" minHeight="900" width="1000" height="900">
	<fx:Style>
		Application{
			fontSize:12;
		}
	</fx:Style>
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 这个HTTPService使用时一定要提前调用send方法-->
		<s:HTTPService id="myservice" url="http://localhost/Flex_04_DataGird_Paging/servlet/FindDataServlet" result="myservice_resultHandler(event)" />
	</fx:Declarations>
	
	<fx:Script>
		<![CDATA[
			import com.adobe.serialization.json.JSON;
			
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			
			private var pageIndex:int=0;			
			private var pageSize:int=5;
			
			private function creationCompleteHandle():void{
				var orgData:ArrayCollection = new ArrayCollection();
				for( var x:uint = 1; x <= 555; x++ )
				{
					var obj:Object = new Object();
					obj.ID = "id " + x.toString();
					obj.Code="order "+x;
					obj.Total=x*1000;
					obj.Customer= "customer "+x;
					obj.Register = "employee";
					obj.Memo="memo "+x;	            	
					obj.State="auditing state";	            	
					orgData.addItem(obj);
				}
				clientPagingBar1.dataGrid=DataGrid1;
				clientPagingBar1.orgData=orgData;
				clientPagingBar1.dataBind();				
			}
			
			protected function myservice_resultHandler(event:ResultEvent):void
			{
				var rawData:String = String(event.result);  
				//decode the data to ActionScript using the JSON API  
				//in this case, the JSON data is a serialize Array of Objects.
				
				var arr:Array = (JSON.decode(rawData) as Array);  
				var dataArray:ArrayCollection = new ArrayCollection(arr); 
				//Alert.show(dataArray.getItemAt(0).id);
				clientPagingBar2.dataGrid=DataGrid2;
				clientPagingBar2.orgData=dataArray;
				clientPagingBar2.dataBind();
			} 
			
		]]>
	</fx:Script>
	
	<mx:VBox width="100%" height="50%">		
		<mx:Label text="客户端分页" />
		<mx:Canvas backgroundColor="white">
			<mx:VBox width="100%" height="50%" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10" verticalScrollPolicy="off" horizontalScrollPolicy="off">
				<mx:DataGrid id="DataGrid1" verticalScrollPolicy="on" horizontalScrollPolicy="off">
					<mx:columns>
						<mx:DataGridColumn headerText="订单ID" dataField="ID" />
						<mx:DataGridColumn headerText="订单编码" dataField="Code" />
						<mx:DataGridColumn headerText="金额" dataField="Total" />
						<mx:DataGridColumn headerText="客户" dataField="Customer" />
						<mx:DataGridColumn headerText="销售员" dataField="Register" />
						<mx:DataGridColumn headerText="备注说明" dataField="Memo" />
						<mx:DataGridColumn headerText="状态" dataField="State" />		    	
					</mx:columns>
				</mx:DataGrid>
				<control:PagingBar id="clientPagingBar1" />
			</mx:VBox>
		</mx:Canvas>
		
		<mx:Label text="服务器端分页" />
		<mx:Canvas backgroundColor="white">
			<mx:VBox width="100%" height="50%" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10" verticalScrollPolicy="off" horizontalScrollPolicy="off">
				<mx:DataGrid id="DataGrid2" verticalScrollPolicy="on" horizontalScrollPolicy="off">
					<mx:columns>
						<mx:DataGridColumn headerText="订单ID" dataField="id" />
						<mx:DataGridColumn headerText="订单编码" dataField="code" />
						<mx:DataGridColumn headerText="金额" dataField="total" />
						<mx:DataGridColumn headerText="客户" dataField="customer" />
						<mx:DataGridColumn headerText="销售员" dataField="register" />
						<mx:DataGridColumn headerText="备注说明" dataField="memo" />
						<mx:DataGridColumn headerText="状态" dataField="state" />		    	
					</mx:columns>
				</mx:DataGrid>
				<control:PagingBar id="clientPagingBar2" />
			</mx:VBox>
		</mx:Canvas>
	</mx:VBox>
	
</s:Application>

 servlet处理类为

package com.test;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.beans.MyObject;

import net.sf.json.JSONArray;

public class FindDataServlet extends HttpServlet {

	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
             this.doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("执行Servlet了哦。。。。。。。。。。。。");
		List<MyObject> orgData=new ArrayList<MyObject>();
		for(int x= 1; x <= 555; x++ )
		{
			MyObject ob=new MyObject();
			ob.setId("CHENEY"+x);
	        ob.setCode("HENAN"+x);
			ob.setTotal(x*10);
			ob.setCustomer("CUS"+x);
			ob.setRegister("EMP"+x);
            ob.setMemo("MEMO"+x);
			ob.setState("STATE"+x);
			orgData.add(ob);
		}
	   JSONArray json=JSONArray.fromObject(orgData);
	   String datas=json.toString();
	   System.out.println(datas);
	   response.getWriter().write(datas);
	}

}

 当然这里JAVA程序也用到JSON相关类,一般要使用JSON的话要使用到六个包

 

 

 


RemoteObject 获取方式

   mxml内容

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:control="com.control.*" 
			   creationComplete="creationCompleteHandle()"
			   minWidth="955" minHeight="600" height="900">
	<fx:Style>
		Application{
			fontSize:12;
		}
	</fx:Style>
	<fx:Declarations>
		<s:RemoteObject id="findData" destination="findData" result="findDate_resultHandler(event)"/>
	</fx:Declarations>
	
	<fx:Script>
		<![CDATA[
			import com.adobe.serialization.json.JSON;
			
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			
			private var pageIndex:int=0;
			
			private var pageSize:int=5;
			
			private function creationCompleteHandle():void{
				var orgData:ArrayCollection = new ArrayCollection();
				for( var x:uint = 1; x <= 555; x++ )
				{
					var obj:Object = new Object();
					obj.ID = "id " + x.toString();
					obj.Code="order "+x;
					obj.Total=x*1000;
					obj.Customer= "customer "+x;
					obj.Register = "employee";
					obj.Memo="memo "+x;	            	
					obj.State="auditing state";	            	
					orgData.addItem(obj);
				}
				clientPagingBar1.dataGrid=DataGrid1;
				clientPagingBar1.orgData=orgData;
				clientPagingBar1.dataBind();
				
				
				findData.findData();
			}
			
			protected function findDate_resultHandler(event:ResultEvent):void
			{
				var rawData:String = String(event.result);  
				//decode the data to ActionScript using the JSON API  
				//in this case, the JSON data is a serialize Array of Objects.
				
				var arr:Array = (JSON.decode(rawData) as Array);  
				var dataArray:ArrayCollection = new ArrayCollection(arr); 
				//Alert.show(dataArray.getItemAt(0).id);
				clientPagingBar2.dataGrid=DataGrid2;
				clientPagingBar2.orgData=dataArray;
				clientPagingBar2.dataBind();
			} 
			
			
			
			
		]]>
	</fx:Script>
	
	<mx:VBox>		
		<mx:Label text="客户端分页" />
		<mx:Canvas backgroundColor="white">
			<mx:VBox width="100%" height="100%" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10" verticalScrollPolicy="off" horizontalScrollPolicy="off">
				<mx:DataGrid id="DataGrid1" verticalScrollPolicy="on" horizontalScrollPolicy="off">
					<mx:columns>
						<mx:DataGridColumn headerText="订单ID" dataField="ID" />
						<mx:DataGridColumn headerText="订单编码" dataField="Code" />
						<mx:DataGridColumn headerText="金额" dataField="Total" />
						<mx:DataGridColumn headerText="客户" dataField="Customer" />
						<mx:DataGridColumn headerText="销售员" dataField="Register" />
						<mx:DataGridColumn headerText="备注说明" dataField="Memo" />
						<mx:DataGridColumn headerText="状态" dataField="State" />		    	
					</mx:columns>
				</mx:DataGrid>
				<control:PagingBar id="clientPagingBar1" />
			</mx:VBox>
		</mx:Canvas>
		
		<mx:Label text="服务器端分页" />
		<mx:Canvas backgroundColor="white">
			<mx:VBox width="100%" height="100%" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10" verticalScrollPolicy="off" horizontalScrollPolicy="off">
				<mx:DataGrid id="DataGrid2" verticalScrollPolicy="on" horizontalScrollPolicy="off">
					<mx:columns>
						<mx:DataGridColumn headerText="订单ID" dataField="id" />
						<mx:DataGridColumn headerText="订单编码" dataField="code" />
						<mx:DataGridColumn headerText="金额" dataField="total" />
						<mx:DataGridColumn headerText="客户" dataField="customer" />
						<mx:DataGridColumn headerText="销售员" dataField="register" />
						<mx:DataGridColumn headerText="备注说明" dataField="memo" />
						<mx:DataGridColumn headerText="状态" dataField="state" />		    	
					</mx:columns>
				</mx:DataGrid>
				<control:PagingBar id="clientPagingBar2" />
			</mx:VBox>
		</mx:Canvas>
	</mx:VBox>
	
</s:Application>

 处理类

package com.test;

import java.util.ArrayList;
import java.util.List;

import com.beans.MyObject;

import net.sf.json.JSONArray;

public class FindGridData {

	public String findData(){
		System.out.println("执行我了。。。。。。。。。。。。。。。");
		List<MyObject> orgData=new ArrayList<MyObject>();
		for(int x= 1; x <= 555; x++ )
		{
			MyObject ob=new MyObject();
			ob.setId("CHENEY"+x);
	        ob.setCode("HENAN"+x);
			ob.setTotal(x*10);
			ob.setCustomer("CUS"+x);
			ob.setRegister("EMP");
            ob.setMemo("MEMO"+x);
			ob.setState("STATE");
			orgData.add(ob);
		}
		 JSONArray json=JSONArray.fromObject(orgData);
		   String datas=json.toString();
		   System.out.println(datas);
	  return datas;
	}
	
}

 JavaBean

MyObject.java

 

 

package com.beans;

public class MyObject {
	private String id ;
	private String code ;
	private int total ;
	private String customer ;
	private String register ;
	private String memo ;
	private String state ;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public int getTotal() {
		return total;
	}
	public void setTotal(int total) {
		this.total = total;
	}
	public String getCustomer() {
		return customer;
	}
	public void setCustomer(String customer) {
		this.customer = customer;
	}
	public String getRegister() {
		return register;
	}
	public void setRegister(String register) {
		this.register = register;
	}
	public String getMeno() {
		return memo;
	}
	public void setMemo(String memo) {
		this.memo = memo;
	}
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	
}

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics