DataTables JS表格组件使用

By admin at 2021-06-29 • 0人收藏 • 560人看过

Datatables是一款jquery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能.

1.分页,即时搜索和排序

2.几乎支持任何数据源:DOM, javascript, Ajax 和 服务器处理

3.支持不同主题 DataTables, jQuery UI, Bootstrap, Foundation

4.各式各样的扩展: Editor, TableTools, FixedColumns ……

5.丰富多样的option和强大的API

官方网站: https://datatables.net/examples/

GIF.gif

aardio工程8.zip

上面是一个非常简单的对一个html的table的重渲染. 渲染之后提供了很多的交互功能. 解析速度也很快.


22 个回复 | 最后更新于 2021-07-03
2021-06-29   #1

如果不想添加分页,排序功能

$(document).ready(function() {
    $('#example').DataTable( {
        "paging":   false,
        "ordering": false,
        "info":     false
    } );
} );


2021-06-29   #2

默认排序列设置, 列号是从0开始算, 以下第三个是age

$(document).ready(function() {
    $('#example').DataTable( {
        "order": [[ 3, "desc" ]]
    } );
} );

image.png

2021-06-29   #3

多重条件排序: 下面代码按照(3)age主排序, 而(4)日期为次排序

当然如果手动的话,  先点主排序那个列, 然后按住键盘上shift键,然后点击鼠标左键选择第二配许列

<script>
     $(document).ready(function() {
           $('#example').DataTable({
				   "order": [[ 3, "desc" ]],
					columnDefs: [ {
					targets: [ 3 ],
					orderData: [ 3, 4 ]
				}]
		   });
      });
</script>

image.png

2021-06-29   #4

隐藏某列, 下面把(2)office和(3)age隐藏掉

$(document).ready(function() {
    $('#example').DataTable( {
        "columnDefs": [
            {
                "targets": [ 2 ],
                "visible": false,
                "searchable": false
            },
            {
                "targets": [ 3 ],
                "visible": false
            }
        ]
    } );
} );

image.png

2021-06-29   #5

保存状态, 利用html的特性, 可以保存排序和当前页码

$(document).ready(function() {
    $('#example').DataTable( {
        stateSave: true
    } );
} );

GIF.gif

2021-06-29   #6

自定义渲染:  利用render , 因为我对js不熟, 下面的代码是我想要渲染age那一列 , 将年纪大于50的标注为红色显示. 看到前面的三个逗号 ,,, 这个意思是前面三个我都不管, 就渲染第四个age , 后面也有三个 ,,, 因为必须把所有的列都表示出来才行. 也许有更简单的办法, 但是我不会......

<script>
     $(document).ready(function() {
        $('#example').DataTable({
			columns: [
				,,,
			   {
				   render: function(data, type, row, meta) {
						return data>50?'<div style="color:#F00">' + data + '</div>':data;
					}
			   
			   },,,
			]
		});
      });
</script>

image.png

2021-06-29   #7

加个滚动条吧

$(document).ready(function() {
    $('#example').DataTable( {
        "scrollY":        "200px",
        "scrollCollapse": true,
        "paging":         false
    } );
} );

image.png

2021-06-29   #8

加个边框吧 , table的css里面用 class="cell-border" 

image.png

image.png

2021-06-29   #9

用js数组来提供数据

<!doctype html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="../html/datatables.min.css"/>
	<script type="text/javascript" src="../html/datatables.min.js"></script>
</head>
<body>
   <table id="example" class="display" width="100%"></table>
    <!--初始化代码-->
<script>
     var dataSet = [
    [ "Tiger Nixon", "System Architect", "Edinburgh", "5421", "2011/04/25", "$320,800" ],
    [ "Garrett Winters", "Accountant", "Tokyo", "8422", "2011/07/25", "$170,750" ],
    [ "Ashton Cox", "Junior Technical Author", "San Francisco", "1562", "2009/01/12", "$86,000" ],
    [ "Cedric Kelly", "Senior Javascript Developer", "Edinburgh", "6224", "2012/03/29", "$433,060" ],
    [ "Airi Satou", "Accountant", "Tokyo", "5407", "2008/11/28", "$162,700" ],
    [ "Brielle Williamson", "Integration Specialist", "New York", "4804", "2012/12/02", "$372,000" ],
    [ "Herrod Chandler", "Sales Assistant", "San Francisco", "9608", "2012/08/06", "$137,500" ],
    [ "Rhona Davidson", "Integration Specialist", "Tokyo", "6200", "2010/10/14", "$327,900" ],
    [ "Colleen Hurst", "Javascript Developer", "San Francisco", "2360", "2009/09/15", "$205,500" ],
    [ "Sonya Frost", "Software Engineer", "Edinburgh", "1667", "2008/12/13", "$103,600" ],
    [ "Jena Gaines", "Office Manager", "London", "3814", "2008/12/19", "$90,560" ],
    [ "Quinn Flynn", "Support Lead", "Edinburgh", "9497", "2013/03/03", "$342,000" ],
    [ "Charde Marshall", "Regional Director", "San Francisco", "6741", "2008/10/16", "$470,600" ],
    [ "Haley Kennedy", "Senior Marketing Designer", "London", "3597", "2012/12/18", "$313,500" ],
    [ "Tatyana Fitzpatrick", "Regional Director", "London", "1965", "2010/03/17", "$385,750" ],
    [ "Michael Silva", "Marketing Designer", "London", "1581", "2012/11/27", "$198,500" ],
    [ "Paul Byrd", "Chief Financial Officer (CFO)", "New York", "3059", "2010/06/09", "$725,000" ],
    [ "Gloria Little", "Systems Administrator", "New York", "1721", "2009/04/10", "$237,500" ],
    [ "Bradley Greer", "Software Engineer", "London", "2558", "2012/10/13", "$132,000" ],
    [ "Dai Rios", "Personnel Lead", "Edinburgh", "2290", "2012/09/26", "$217,500" ],
    [ "Jenette Caldwell", "Development Lead", "New York", "1937", "2011/09/03", "$345,000" ],
    [ "Yuri Berry", "Chief Marketing Officer (CMO)", "New York", "6154", "2009/06/25", "$675,000" ],
    [ "Caesar Vance", "Pre-Sales Support", "New York", "8330", "2011/12/12", "$106,450" ],
    [ "Doris Wilder", "Sales Assistant", "Sydney", "3023", "2010/09/20", "$85,600" ],
    [ "Angelica Ramos", "Chief Executive Officer (CEO)", "London", "5797", "2009/10/09", "$1,200,000" ],
    [ "Gavin Joyce", "Developer", "Edinburgh", "8822", "2010/12/22", "$92,575" ],
    [ "Jennifer Chang", "Regional Director", "Singapore", "9239", "2010/11/14", "$357,650" ],
    [ "Brenden Wagner", "Software Engineer", "San Francisco", "1314", "2011/06/07", "$206,850" ],
    [ "Fiona Green", "Chief Operating Officer (COO)", "San Francisco", "2947", "2010/03/11", "$850,000" ],
    [ "Shou Itou", "Regional Marketing", "Tokyo", "8899", "2011/08/14", "$163,000" ],
    [ "Michelle House", "Integration Specialist", "Sydney", "2769", "2011/06/02", "$95,400" ],
    [ "Suki Burks", "Developer", "London", "6832", "2009/10/22", "$114,500" ],
    [ "Prescott Bartlett", "Technical Author", "London", "3606", "2011/05/07", "$145,000" ],
    [ "Gavin Cortez", "Team Leader", "San Francisco", "2860", "2008/10/26", "$235,500" ],
    [ "Martena Mccray", "Post-Sales support", "Edinburgh", "8240", "2011/03/09", "$324,050" ],
    [ "Unity Butler", "Marketing Designer", "San Francisco", "5384", "2009/12/09", "$85,675" ]
];
 
$(document).ready(function() {
    $('#example').DataTable( {
        data: dataSet,
        columns: [
            { title: "Name" },
            { title: "Position" },
            { title: "Office" },
            { title: "Extn." },
            { title: "Start date" },
            { title: "Salary" }
        ]
    } );
} );
</script>
</body>
</html>


2021-06-29   #10

用ajax通过服务器返回数据

<!doctype html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="../html/datatables.min.css"/>
	<script type="text/javascript" src="../html/datatables.min.js"></script>
</head>
<body>
   <table id="example" class="display" style="width:100%">
        <thead>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </tfoot>
    </table>
    <!--初始化代码-->
<script>
$(document).ready(function() {
    $('#example').DataTable( {
        "processing": true,
        "serverSide": true,
        "ajax": "https://datatables.net/examples//server_side/scripts/server_processing.php"
    } );
} );
</script>
</body>
</html>

这种方式, 所有的排序啥的都需要服务器支持, 服务器来排序后返回给表格, 表格只是显示...

2021-06-29   #11

ajax方式, 一次读取全部数据

<!doctype html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="../html/datatables.min.css"/>
	<script type="text/javascript" src="../html/datatables.min.js"></script>
</head>
<body>
<table id="example" class="display" style="width:100%">
        <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Extn.</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Extn.</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </tfoot>
    </table>
    <!--初始化代码-->
<script>
$(document).ready(function() {
    $('#example').DataTable( {
        "processing": true,
        "ajax": "https://datatables.net/examples/ajax/data/arrays.txt"
    } );
} );
</script>
</body>
</html>

读取完成后, 排序啥的都是客户端操作.

2021-06-29   #12

用aardio来提供数据给它

这时候需要aardio特有的external来帮助了

import web.kit.form;
var wb = web.kit.form(mainForm);
var datastr = /****
[
    [
      "Tiger Nixon",
      "System Architect",
      "Edinburgh",
      "5421",
      "2011/04/25",
      "$320,800"
    ],
    [
      "Garrett Winters",
      "Accountant",
      "Tokyo",
      "8422",
      "2011/07/25",
      "$170,750"
    ]
  ]
****/;
wb.external = {
    getdata = function(){
    	return datastr;
    }
};
wb.go("/html/main.html")

html里面需要修改下获取方式为

<!doctype html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="../html/datatables.min.css"/>
	<script type="text/javascript" src="../html/datatables.min.js"></script>
</head>
<body>
 <table id="example" class="display" width="100%"></table>
    <!--初始化代码-->
<script>
$(document).ready(function() {
    $('#example').DataTable( {
        data: JSON.parse(external.getdata()),
		columns: [
            { title: "Name" },
            { title: "Position" },
            { title: "Office" },
            { title: "Extn." },
            { title: "Start date" },
            { title: "Salary" }
        ]
    } );
} );
</script>
</body>
</html>

image.png

可以接受到来自aardio发送来的数据le 

2021-06-29   #13

我知道上面的代码看起来好傻, 传递了个json格式字符串过去, 我们实际用的时候肯定不会是对字符串进行操作, 一般都是弄个table表来存储数据, 然后转换table为json字符串

那么,这时候用到web.json了

import web.kit.form;
var wb = web.kit.form(mainForm);

var demoTable = {
	{
      "Tiger Nixon",
      "System Architect",
      "Edinburgh",
      "5421",
      "2011/04/25",
      "$320,800"
     },
	{
      "Garrett Winters",
      "Accountant",
      "Tokyo",
      "8422",
      "2011/07/25",
      "$170,750"
     },
}

import web.json;

wb.external = {
    getdata = function(){
    	return web.json.stringify(demoTable);
    }
};
wb.go("/html/main.html")

上面定义了个 demoTable的aardio表, 初始化了两个数组, 然后调用web.json.stringify转换下, 这样就可以了, 同样的实现了上面的交互功能.

2021-06-29   #14

你也可以这样来玩, 随机下试试

import web.kit.form;
var wb = web.kit.form(mainForm);

var demoTable = {}
for(i=1;10000;1){
	demoTable[i]={
		string.random(7);
		string.random(7);
		string.random(7);
		math.round(math.random()*100);
		tostring(time.now(),"%Y-%m-%d","chs");
		"$"++math.round(math.random()*1000);
	}

}


import web.json;

wb.external = {
    getdata = function(){
    	return web.json.stringify(demoTable);
    }
};
wb.go("/html/main.html")

image.png



2021-06-30   #15

似乎这就是我想要的哈哈

2021-06-30   #16

手动添加一行数据:

需要用到dataTables的返回table对象 , 利用table.row.add( [1,2,3,4,5,6] ).draw();

所以我们首先去html里面把table对象弄出来.

<script>
$(document).ready(function() {
    table = $('#example').DataTable();
} );
</script>

然后就可以在aardio中利用web.doScript()来执行操作

//模拟随机行数据
var fun = function(){
    var tab={}
    table.push(tab,string.random(5));
    table.push(tab,string.random(5));
    table.push(tab,string.random(5));
    table.push(tab,math.round(math.random()*100));
    table.push(tab,tostring(time.now().addday(1),"%Y-%m-%d","chs"));
    table.push(tab,"$"++math.round(math.random()*1000));
    //注意, 这里要用array哦
	return web.json.stringifyArray(tab);
}

mainForm.button2.oncommand = function(id,event){
	wb.doScript("table.row.add( "++fun()++" ).draw();")
}

GIF.gif


还有一种办法, 在js代码里自己定义一个add函数, 在aardio里使用这个函数

<script>
$(document).ready(function() {
    table = $('#example').DataTable();
} );
function myAddFunc(p1,p2,p3,p4,p5,p6) {
    table.row.add( [p1,p2,p3,p4,p5,p6] ).draw();
}
</script>

使用

mainForm.button2.oncommand = function(id,event){
	wb.doScript(`myAddFunc("adf","fg","sfdf",234,"20210303","$66")`)
}

image.png

2021-06-30   #17

手动添加多行数据: table.rows.add(  ).draw();

同上 , 利用表来做容易一点

var fun = function(){
    var tab={}
    table.push(tab,string.random(5));
    table.push(tab,string.random(5));
    table.push(tab,string.random(5));
    table.push(tab,math.round(math.random()*100));
    table.push(tab,tostring(time.now().addday(1),"%Y-%m-%d","chs"));
    table.push(tab,"$"++math.round(math.random()*1000));
	return tab;
}
//模拟多行数据
var rowsList = function(index){
    var tab = {}
	for(i=1;index;1){
		tab[i]=fun();
	}
	return web.json.stringifyArray(tab);	
}


mainForm.button2.oncommand = function(id,event){
	wb.doScript("table.rows.add( "++rowsList(3)++" ).draw();")
}

image.png

2021-06-30   #18

多行选中 , aardio获取选中行数量

如果想要能多选行, 那么需要在js里修改 , 顺便我们在aardio里先定义一个函数用来传递数量

wb.external = {
    getLen = function(len){
    	console.log(len)
    }
};
<script>
$(document).ready(function() {
    table = $('#example').DataTable();
	$('#example tbody').on( 'click', 'tr', function () {
        $(this).toggleClass('selected');
    } );
} );
function getLength(){
	var len = table.rows('.selected').data().length;
	external.getLen(len);
};
</script>

image.png

8个, 这个表格组件是可以跨页码选中的, 这一页只是显示了3条 , 但是我总共点了8行, 正确的.

2021-06-30   #19

单行选中 并删除选中行

html代码中需添加个删除的函数

<script>
$(document).ready(function() {
    table = $('#example').DataTable();
	$('#example tbody').on( 'click', 'tr', function () {
        if ( $(this).hasClass('selected') ) {
            $(this).removeClass('selected');
        }
        else {
            table.$('tr.selected').removeClass('selected');
            $(this).addClass('selected');
        }
    } );
});
function delFunc(){
	table.row('.selected').remove().draw( false );
};
</script>

然后, 同样的去aardio里调用

wb.doScript("delFunc()")

GIF.gif

2021-06-30   #20

显示或隐藏某列

<script>
$(document).ready(function() {
    table = $('#example').DataTable();
});
function showHide(index){
	var column = table.column( index );
    column.visible( ! column.visible() );
};
</script>
wb.doScript("showHide(0)")

GIF.gif

2021-07-03   #21

所有可用属性:

功能参数(Features)

参数名

说明

参考值

默认值

autoWidth

定义是否由控件自动控制列宽

Boolean

true

deferRender

定义在render时是否仅仅render显示的dom,在显示大量数据的情况下强烈建议设为true,显示少量数据或者真翻页方案可以设为false,注意在设为true时无法通过函数获取所有行的dom对象—因为它们并不存在.

Boolean

false

info

控制总数信息(标准界面右下角显示总数和过滤条数的控件)的显隐

Boolean

true

lengthChange

控制是否能够调整每页的条数,如果设为false,标准的每页条数控制控件也会被隐藏.

Boolean

true

ordering

全局控制列表的所有排序功能.

Boolean

true

paging

全局控制列表的翻页功能,如果设为false,所有的默认翻页控件会被隐藏

Boolean

true

processing

控制是否在数据加载时出现”Processing”的提示,一般在远程加载并且比较慢的情况下才会出现. 样式需要定义,否则比较丑.

Boolean

false

scrollX

控制在列过多过宽是,是否出现水平滚动条.注意使用这个参数时最好关闭响应式设计

Boolean

false

scrollY

定义一个高度,当列表内容超过这个高度时,显示垂直滚动条,这个高度不算表头和翻页搜索等工具条的空间.支持数字或者css写法比如:

200或者’200px’

Number /   String

searching

控制控件的搜索功能,如果为false,控件的搜索功能被完全禁用,而且默认搜索组件会被隐藏.

Boolean

true

serverSide

当设为true时,列表的过滤,搜索和排序信息会传递到Server端进行处理,实现真翻页方案的必需属性.反之,所有的列表功能都在客户端计算并执行

Boolean

false


2021-07-03   #22

配置参数(Options)

参数名

说明

参考值

默认值

deferLoading

这个参数只有在ServerSide为Ture的时候才有作用,主要是针对列表已经通过HTML显示了一部分数据,而通知远程加载可以忽略这部分数据,在实际使用中这种情况并不常见.

Number   /Array

false

destroy

设为ture时通知dataTable函数完全重新建立一个新的控件实例,在一个页面内反复对同一个控件加载dataTable函数并且想重新建立控件时使用.

Boolean

false

displayStart

列表初始显示的行索引,根据给出的行索引会自动翻页,比如一个每页10个的列表,那么给出20可以让其翻到第二页

Number

dom

比较复杂的配置项,简言之就是通过一个自定义的字符串来定义DataTables里面所有组件的显示,位置和显隐.

具体请详见:

http://datatables.net/reference/option/dom

String

“lfrtip”

lengthMenu

定义页面长度组件里面的选项.

Array

[ 10, 25,   50]

orderCellsTop

当然表头有多层td组成的时候,必须定义哪一个td的数据用于排序,false表示底部td,true表示顶部td. 比如以下情况:

                       

   1      2.1      2.2   

 

true的时候排序会用2.1, false的时候排序会用2.2.

Boolean

false

orderClasses

定义是否排序的列进行高亮显示

Boolean

true

order

定义列表的初始排序设定,为一个2维数组,子数组包括2个值,列索引和排序方向(asc/desc): 例如

"order": [[ 0, 'asc' ], [ 1, 'asc' ]]

Array

[[0, 'asc']]

orderMulti

控制是否支持多重排序,如果为true,可以通过shift+点击列头实现多重排序,或者通过API实现,否则禁用该功能.

Boolean

true

orderFixed

自定义固定的排序策略,该策略在任何排序操作中总是起效.可以通过对一个列的固定排序(可以是隐藏的列)来定义列表默认的排序策略.

数组方式,定义优先排序策略,如:

"orderFixed": [ 0, 'asc' ]

该参数说明无论如何排序,永远先进行第一列的正向排序.

对象方式,可以利用关键字pre或post来定义这个规则是优先生效还是置后生效.

"orderFixed": {

          "pre": [ 0, 'asc' ],

          "post": [ 1, 'asc' ]

    }

Array/Object

pageLength

定义初始的页长

Number

10

pagingType

定义翻页组件的样式(有4个选择):

simple -  只有上一页和下一页2个按钮

simple_numbers   – 上一页,下一页和页码

full – 首页,末页,上一页,下一页4个按钮

full_numbers   – 全部按钮和页面

String

simple_numbers

scrollCollapse

在设置了一定的scrollY值后起效,为true时,当列表内容不足以撑满scrollY的设定值时,列表高度会自动适应内容.

Boolean

false

search

定义列表的初始搜索/过滤条件

Search对象可以有以下属性:

Object

search.search

过滤字符串,注意在默认设置下,所有列的数据都会参与过滤.比如当这个属性为”a”的时候,任何一个列只要包含”a”的行就会被显示.为空表示全部

String

search.caseInsensitive

搜索是是否忽略大小写,true为忽略

Boolean

true

search.regex

定义搜索字符串是否为一个正则表达式

Boolean

fasle

search.smart

禁用获取启用DataTables控件内置的只能过滤算法,这个算法会把搜索字符串进行分割并只能搜索,关闭这个算法仅仅实现简单的字符串查找,false为关闭

Boolean

true

searchCols

分别定义每个列的过滤条件.该参数是一个对象数组,每个对象有2个属性:

search: 搜索字符串

escapeRegex:   是否是正则表达式

注意不需要设置过滤的列也需要用null占位,比如:

"searchCols": [

    null,

    {   "search": "My filter" },

    null,

    {   "search": "^[0-9]", "escapeRegex": false }

  ]

Array

stripeClasses

定义一个字符串数组,在显示行的时候依次使用里面的字符串作为行的class

Array

‘odd’ & ‘even’

列定义参数(Columns)

参数名

说明

参考值

默认值

columns

列的初始状态的定义,该参数一个是对象数组,每一个对象元素定义一个列.注意,不需定义的列也必须以null占位,比如:

"columns": [

    {   "searchable": false },

    null,

null

 ]

Array

columnDefs

和columns设置非常类似,但可以通过targets属性可以根据灵活的选择需要设定的列.比columns更加灵活.比如:

"columnDefs": [ {

        "targets": 0,

        "searchable": false

} ]

targets可以有多种写法:

0或者正整数(可用数组): 表示正向列的索引

负数(可用数组): 表示反向列的索引

字符串: 匹配th的class来选择列.

"_all":   所有列,也是默认值.



columns.data

列的数据名,对应数据里面的属性名

String

columns.name

给列设置独立的名称,目前看意义不大

String

columns.orderable

设置列是否允许排序

Boolean

true

columns.searchable

设置列是否允许过滤

Boolean

true

columns.type

通过设置列的类型让控件在排序和过滤这个列是能更好的处理这个列的数据,比如日期,货币等.具体种类很多请参考这里:

http://datatables.net/reference/option/columns.type

String

columns.visible

设置列的可见性,true为显示

Boolean

true

columns.width

强行设置列的宽度,支持数字和任何CSS写法,比如20%.

String

columns.render

非常有用的函数,自定义列的内容.该属性比较常见的用法是函数用法,通过这个函数可以自定义改造列的任何内容,如果要在列中显示比较复杂的内容,这是一个比较好的选择.比如在列中加入功能按钮.

例如:

"render": function ( data, type, row,   meta ) {

      return   '<a href="'+data+'">Download</a>';

}

4个属性的意思是:

data : 当前单元格的数据

type: 当前列的类型

row: 当前行完整的数据对象

meta: 为一个子对象,包含3个属性

   row: 当前行的索引

   col: 当前列的索引

   settings: 当前DataTables控件的setttings对象





登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
纯私人站,当笔记本用的,学到哪写到哪,目前在学aardio+halcon机器视觉.
加入本站专享群:783804676
AARDIO语言QQ大群:70517368
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
C大Aardio论坛:Aar爱好者论坛
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
赞助商:才仁机械
下载站:
非凡软件站



Loading...