版本:0.1.6
适用所有php站点
日期:2016年11月9日
插件下载地址:http://fex.baidu.com/webuploader/

所需要的必须文件其他文件可删

webuploader.css
webuploader.min.js
Uploader.swf
fileupload.php

引入样式

  <link rel="stylesheet" type="text/css" href="/Public/static/css/plugins/webuploader/webuploader.css"><link rel="stylesheet" type="text/css" href="/Public/static/css/demo/webuploader-demo.min.css">

webuploader-demo.min.css文件代码

#container {color: #838383;font-size: 12px
}#uploader .queueList {margin: 20px;border: 3px dashed #e6e6e6
}#uploader .queueList.filled {padding: 17px;margin: 0;border: 3px dashed transparent
}#uploader .queueList.webuploader-dnd-over {border: 3px dashed #999
}#uploader p {margin: 0
}.element-invisible {position: absolute!important;clip: rect(1px 1px 1px 1px);clip: rect(1px,1px,1px,1px)
}#uploader .placeholder {min-height: 350px;padding-top: 178px;text-align: center;background: url(../../../img/webuploader.png) center 93px no-repeat;color: #ccc;font-size: 18px;position: relative
}#uploader .placeholder .webuploader-pick {font-size: 18px;background: #00b7ee;border-radius: 3px;line-height: 44px;padding: 0 30px;*width: 120px;color: #fff;display: inline-block;margin: 0 auto 20px;cursor: pointer;box-shadow: 0 1px 1px rgba(0,0,0,.1)
}#uploader .placeholder .webuploader-pick-hover {background: #00a2d4
}#uploader .placeholder .flashTip {color: #666;font-size: 12px;position: absolute;width: 100%;text-align: center;bottom: 20px
}#uploader .placeholder .flashTip a {color: #0785d1;text-decoration: none
}#uploader .placeholder .flashTip a:hover {text-decoration: underline
}#uploader .filelist {list-style: none;margin: 0;padding: 0
}#uploader .filelist:after {content: '';display: block;width: 0;height: 0;overflow: hidden;clear: both
}#uploader .filelist li {width: 110px;height: 110px;background: url(../../img/bg.png) no-repeat;text-align: center;margin: 0 8px 20px 0;position: relative;display: inline;float: left;overflow: hidden;font-size: 12px
}#uploader .filelist li p.log {position: relative;top: -45px
}#uploader .filelist li p.title {position: absolute;left: 0;width: 100%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;top: 5px;text-indent: 5px;text-align: left
}#uploader .filelist li p.progress {position: absolute;width: 100%;bottom: 0;left: 0;height: 8px;overflow: hidden;z-index: 50;margin: 0;border-radius: 0;background: 0 0;-webkit-box-shadow: 0 0 0
}#uploader .filelist li p.progress span {display: none;overflow: hidden;width: 0;height: 100%;background: #1483d8 url(../../img/progress.png) repeat-x;-webit-transition: width 200ms linear;-moz-transition: width 200ms linear;-o-transition: width 200ms linear;-ms-transition: width 200ms linear;transition: width 200ms linear;-webkit-animation: progressmove 2s linear infinite;-moz-animation: progressmove 2s linear infinite;-o-animation: progressmove 2s linear infinite;-ms-animation: progressmove 2s linear infinite;animation: progressmove 2s linear infinite;-webkit-transform: translateZ(0)
}@-webkit-keyframes progressmove {0% {background-position: 0 0}100% {background-position: 17px 0}
}@-moz-keyframes progressmove {0% {background-position: 0 0}100% {background-position: 17px 0}
}@keyframes progressmove {0% {background-position: 0 0}100% {background-position: 17px 0}
}#uploader .filelist li p.imgWrap {position: relative;z-index: 2;line-height: 110px;vertical-align: middle;overflow: hidden;width: 110px;height: 110px;-webkit-transform-origin: 50% 50%;-moz-transform-origin: 50% 50%;-o-transform-origin: 50% 50%;-ms-transform-origin: 50% 50%;transform-origin: 50% 50%;-webit-transition: 200ms ease-out;-moz-transition: 200ms ease-out;-o-transition: 200ms ease-out;-ms-transition: 200ms ease-out;transition: 200ms ease-out
}#uploader .filelist li img {width: 100%
}#uploader .filelist li p.error {background: #f43838;color: #fff;position: absolute;bottom: 0;left: 0;height: 28px;line-height: 28px;width: 100%;z-index: 100
}#uploader .filelist li .success {display: block;position: absolute;left: 0;bottom: 0;height: 40px;width: 100%;z-index: 200;background: url(../../img/success.png) no-repeat right bottom
}#uploader .filelist div.file-panel {position: absolute;height: 0;filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000')\0;background: rgba(0,0,0,.5);width: 100%;top: 0;left: 0;overflow: hidden;z-index: 300
}#uploader .filelist div.file-panel span {width: 24px;height: 24px;display: inline;float: right;text-indent: -9999px;overflow: hidden;background: url(../../img/icons.png) no-repeat;margin: 5px 1px 1px;cursor: pointer
}#uploader .filelist div.file-panel span.rotateLeft {background-position: 0 -24px
}#uploader .filelist div.file-panel span.rotateLeft:hover {background-position: 0 0
}#uploader .filelist div.file-panel span.rotateRight {background-position: -24px -24px
}#uploader .filelist div.file-panel span.rotateRight:hover {background-position: -24px 0
}#uploader .filelist div.file-panel span.cancel {background-position: -48px -24px
}#uploader .filelist div.file-panel span.cancel:hover {background-position: -48px 0
}#uploader .statusBar {height: 63px;border-top: 1px solid #dadada;padding: 0 20px;line-height: 63px;vertical-align: middle;position: relative
}#uploader .statusBar .progress {border: 1px solid #1483d8;width: 198px;background: #fff;height: 18px;display: inline-block;text-align: center;line-height: 20px;color: #6dbfff;position: relative;margin: 0 10px 0 0
}#uploader .statusBar .progress span.percentage {width: 0;height: 100%;left: 0;top: 0;background: #1483d8;position: absolute
}#uploader .statusBar .progress span.text {position: relative;z-index: 10
}#uploader .statusBar .info {display: inline-block;font-size: 14px;color: #666
}#uploader .statusBar .btns {position: absolute;top: 10px;right: 20px;line-height: 40px
}#filePicker2 {display: inline-block;float: left
}#uploader .statusBar .btns .uploadBtn,#uploader .statusBar .btns .uploadBtn.state-paused,#uploader .statusBar .btns .uploadBtn.state-uploading,#uploader .statusBar .btns .webuploader-pick {background: #fff;border: 1px solid #cfcfcf;color: #565656;padding: 0 18px;display: inline-block;border-radius: 3px;margin-left: 10px;cursor: pointer;font-size: 14px;float: left
}#uploader .statusBar .btns .uploadBtn.state-paused:hover,#uploader .statusBar .btns .uploadBtn.state-uploading:hover,#uploader .statusBar .btns .uploadBtn:hover,#uploader .statusBar .btns .webuploader-pick-hover {background: #f0f0f0
}#uploader .statusBar .btns .uploadBtn {background: #00b7ee;color: #fff;border-color: transparent
}#uploader .statusBar .btns .uploadBtn:hover {background: #00a2d4
}#uploader .statusBar .btns .uploadBtn.disabled {pointer-events: none;opacity: .6
}

引入js文件

<script src="/Public/static/js/plugins/webuploader/webuploader.min.js"></script>

js使用代码

<script type="text/javascript">jQuery(function() {function e(e) {var a = o('<li id="' + e.id + '"><p class="title">' + e.name + '</p><p class="imgWrap"></p><p class="progress"><span></span></p></li>'),s = o('<div class="file-panel"><span class="cancel">删除</span><span class="rotateRight">向右旋转</span><span class="rotateLeft">向左旋转</span></div>').appendTo(a),i = a.find("p.progress span"),t = a.find("p.imgWrap"),r = o('<p class="error"></p>'),d = function(e) {switch (e) {case "exceed_size":text = "文件大小超出";break;case "interrupt":text = "上传暂停";break;default:text = "上传失败,请重试"}r.text(text).appendTo(a)};"invalid" === e.getStatus() ? d(e.statusText) : (t.text("预览中"), n.makeThumb(e, function(e, a) {if (e) return void t.text("不能预览");var s = o('<img src="' + a + '">');t.empty().append(s)}, v, b), w[e.id] = [e.size, 0], e.rotation = 0), e.on("statuschange", function(t, n) {"progress" === n ? i.hide().width(0) : "queued" === n && (a.off("mouseenter mouseleave"), s.remove()), "error" === t || "invalid" === t ? (console.log(e.statusText), d(e.statusText), w[e.id][1] = 1) : "interrupt" === t ? d("interrupt") : "queued" === t ? w[e.id][1] = 0 : "progress" === t ? (r.remove(), i.css("display", "block")) : "complete" === t && a.append('<span class="success"></span>'), a.removeClass("state-" + n).addClass("state-" + t)}), a.on("mouseenter", function() {s.stop().animate({height: 30})}), a.on("mouseleave", function() {s.stop().animate({height: 0})}), s.on("click", "span", function() {var a, s = o(this).index();switch (s) {case 0:return void n.removeFile(e);case 1:e.rotation += 90;break;case 2:e.rotation -= 90}x ? (a = "rotate(" + e.rotation + "deg)", t.css({"-webkit-transform": a,"-mos-transform": a,"-o-transform": a,transform: a})) : t.css("filter", "progid:DXImageTransform.Microsoft.BasicImage(rotation=" + ~~ (e.rotation / 90 % 4 + 4) % 4 + ")")}), a.appendTo(l)}function a(e) {var a = o("#" + e.id);delete w[e.id], s(), a.off().find(".file-panel").off().end().remove()}function s() {var e, a = 0,s = 0,t = f.children();o.each(w, function(e, i) {s += i[0], a += i[0] * i[1]}), e = s ? a / s : 0, t.eq(0).text(Math.round(100 * e) + "%"), t.eq(1).css("width", Math.round(100 * e) + "%"), i()}function i() {var e, a = "";"ready" === k ? a = "选中" + m + "张文件,共" + WebUploader.formatSize(h) + "。" : "confirm" === k ? (e = n.getStats(), e.uploadFailNum && (a = "已成功上传" + e.successNum + "张照片至XX相册," + e.uploadFailNum + '张照片上传失败,<a class="retry" href="#">重新上传</a>失败文件或<a class="ignore" href="#">忽略</a>')) : (e = n.getStats(), a = "共" + m + "张(" + WebUploader.formatSize(h) + "),已上传" + e.successNum + "张", e.uploadFailNum && (a += ",失败" + e.uploadFailNum + "张")), p.html(a)}function t(e) {var a;if (e !== k) {switch (c.removeClass("state-" + k), c.addClass("state-" + e), k = e) {case "pedding":u.removeClass("element-invisible"), l.parent().removeClass("filled"), l.hide(), d.addClass("element-invisible"), n.refresh();break;case "ready":u.addClass("element-invisible"), o("#filePicker2").removeClass("element-invisible"), l.parent().addClass("filled"), l.show(), d.removeClass("element-invisible"), n.refresh();break;case "uploading":o("#filePicker2").addClass("element-invisible"), f.show(), c.text("暂停上传");break;case "paused":f.show(), c.text("继续上传");break;case "confirm":if (f.hide(), c.text("开始上传").addClass("disabled"), a = n.getStats(), a.successNum && !a.uploadFailNum) return void t("finish");break;case "finish":a = n.getStats(), a.successNum ? swal('上传成功!') : (k = "done", location.reload()),c.hide(),location.reload()}i()}}var n, o = jQuery,r = o("#uploader"),l = o('<ul class="filelist"></ul>').appendTo(r.find(".queueList")),d = r.find(".statusBar"),p = d.find(".info"),c = r.find(".uploadBtn"),u = r.find(".placeholder"),f = d.find(".progress").hide(),m = 0,h = 0,g = window.devicePixelRatio || 1,v = 110 * g,b = 110 * g,k = "pedding",w = {},x = function() {var e = document.createElement("p").style,a = "transition" in e || "WebkitTransition" in e || "MozTransition" in e || "msTransition" in e || "OTransition" in e;return e = null, a}();if (!WebUploader.Uploader.support()) throw alert("Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器"), new Error("WebUploader does not support the browser you are using.");n = WebUploader.create({pick: {id: "#filePicker",label: "点击选择文件"},dnd: "#uploader .queueList",paste: document.body,accept: {title: 'Files',extensions: 'gif,jpg,jpeg,bmp,png,pdf,doc,docx,txt,xls,xlsx,ppt,pptx,zip,mp3,mp4,text,csv',mimeTypes: 'image/*,text/*'//word+',application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document'//excel+',application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'//ppt+',application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation'+',application/pdf'+',application/zip'+',application/csv'},swf: BASE_URL + "/Uploader.swf",disableGlobalDnd: !0,chunked: !0,server: BASE_URL +"/fileupload.php",fileNumLimit: 300,fileSizeLimit: 5242880,fileSingleSizeLimit: 1048576}), n.addButton({id: "#filePicker2",label: "继续添加"}), n.onUploadProgress = function(e, a) {var i = o("#" + e.id),t = i.find(".progress span");t.css("width", 100 * a + "%"), w[e.id][1] = a, s()}, n.onFileQueued = function(a) {m++, h += a.size, 1 === m && (u.addClass("element-invisible"), d.show()), e(a), t("ready"), s()}, n.onFileDequeued = function(e) {m--, h -= e.size, m || t("pedding"), a(e), s()}, n.on("all", function(e) {switch (e) {case "uploadFinished":t("confirm");break;case "startUpload":t("uploading");break;case "stopUpload":t("paused")}}), n.onError = function() {swal('操作失败!',"错误:文件类型不符、添加的文件有重复、字节超大!", "warning");}, c.on("click", function() {return o(this).hasClass("disabled") ? !1 : void("ready" === k ? n.upload() : "paused" === k ? n.upload() : "uploading" === k && n.stop())}), p.on("click", ".retry", function() {n.retry()}), p.on("click", ".ignore", function() {$.fancybox.close();}), c.addClass("state-" + k), s(),n.on("uploadSuccess",function(file,ret) {$.post("/team-dzone-event.html",{name:ret.oldName,path:ret.filePath,type:ret.fileSuffixes});})});
</script>

注释:swal是个插件可以用alert代替不然实例出不来哦!

fileupload.php文件内容

<?php
/*** 创建者 admin.* 日期: 2016/11/8* 时间: 12:52*/header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {exit; // finish preflight CORS requests here
}
if ( !empty($_REQUEST[ 'debug' ]) ) {$random = rand(0, intval($_REQUEST[ 'debug' ]) );if ( $random === 0 ) {header("HTTP/1.0 500 Internal Server Error");exit;}
}// header("HTTP/1.0 500 Internal Server Error");
// exit;
// 5 minutes execution time
@set_time_limit(5 * 60);
// Uncomment this one to fake upload time
// usleep(5000);
// Settings
$php_path = dirname(__FILE__) . '/';
$php_url = dirname($_SERVER['PHP_SELF']) . '/';
$targetDir = $php_path . '../../../../../Uploads/'.DIRECTORY_SEPARATOR.'file/'.date('Ym',time());
$uploadDir = $php_path . '../../../../../Uploads/'.DIRECTORY_SEPARATOR.'file/'.date('Ym',time());
//echo $uploadDir;die;
$cleanupTargetDir = true; // Remove old files
$maxFileAge = 5 * 3600; // Temp file age in seconds
// Create target dir
if (!file_exists($targetDir)) {mkdir($targetDir,0700,true);
}
// Create target dir
if (!file_exists($uploadDir)) {mkdir($uploadDir,0700,true);
}// Get a file name
if (isset($_REQUEST["name"])) {$fileName = $_REQUEST["name"];
} elseif (!empty($_FILES)) {$fileName = $_FILES["file"]["name"];
} else {$fileName = uniqid("file_");
}
$oldName = $fileName;
$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
// $uploadPath = $uploadDir . DIRECTORY_SEPARATOR . $fileName;
// Chunking might be enabled
//echo $filePath;
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1;
// Remove old temp files
if ($cleanupTargetDir) {if (!is_dir($targetDir) || !$dir = opendir($targetDir)) {die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');}while (($file = readdir($dir)) !== false) {$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;// If temp file is current file proceed to the nextif ($tmpfilePath == "{$filePath}_{$chunk}.part" || $tmpfilePath == "{$filePath}_{$chunk}.parttmp") {continue;}// Remove temp file if it is older than the max age and is not the current fileif (preg_match('/\.(part|parttmp)$/', $file) && (@filemtime($tmpfilePath) < time() - $maxFileAge)) {@unlink($tmpfilePath);}}closedir($dir);
}// Open temp file
if (!$out = @fopen("{$filePath}_{$chunk}.parttmp", "wb")) {die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
}
if (!empty($_FILES)) {if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');}// Read binary input stream and append it to temp fileif (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) {die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');}
} else {if (!$in = @fopen("php://input", "rb")) {die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');}
}
while ($buff = fread($in, 4096)) {fwrite($out, $buff);
}
@fclose($out);
@fclose($in);
rename("{$filePath}_{$chunk}.parttmp", "{$filePath}_{$chunk}.part");
$index = 0;
$done = true;
for( $index = 0; $index < $chunks; $index++ ) {if ( !file_exists("{$filePath}_{$index}.part") ) {$done = false;break;}
}if ( $done ) {$pathInfo = pathinfo($fileName);$hashStr = substr(md5($pathInfo['basename']),8,16);$hashName = time() . $hashStr . '.' .$pathInfo['extension'];$uploadPath = $uploadDir . DIRECTORY_SEPARATOR .$hashName;if (!$out = @fopen($uploadPath, "wb")) {die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');}if ( flock($out, LOCK_EX) ) {for( $index = 0; $index < $chunks; $index++ ) {if (!$in = @fopen("{$filePath}_{$index}.part", "rb")) {break;}while ($buff = fread($in, 4096)) {fwrite($out, $buff);}@fclose($in);@unlink("{$filePath}_{$index}.part");}flock($out, LOCK_UN);}@fclose($out);$saveUrl = 'Uploads/file/'.date('Ym',time())."/".$hashName;$response = ['success'=>true,'oldName'=>$oldName,'filePath'=>$saveUrl,'fileSize'=>$_FILES['file']['size'],'fileSuffixes'=>$pathInfo['extension'],'file_id'=>'',];die(json_encode($response));
}// Return Success JSON-RPC response
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');

最后推荐一个源码网站,博主感觉不错,希望能帮助到大家里面有很多开源程序发布,名字叫做原创源码库。

使用百度webuploader插件进行多文件类型分片上传实例相关推荐

  1. vue+element-ui大文件的分片上传和断点续传js-spark-md5和browser-md5-file

    注意:以下共两份代码片段,第一份为原博主链接代码,第二份自己写的整体代码(比较乱) 1.参考 https://www.cnblogs.com/kelelipeng/p/10158599.html (j ...

  2. php上传多个文件类型,ThinkPHP上传多文件多类型

    首先是使用环境 在项目中添加个人信息的时候,需要选择上传图片作为头像还有上传个人简历.头像的格式是必须图片,简历的格式是文档格式(含PDF) 下面是代码带注释//添加用户逻辑操作 public fun ...

  3. thinkphp6+webuploader实现大文件(视频)分片上传/本地保存或上传OSS

    thinkPHP6+webuploader分片上传大视频的解决方案: ①能解决视频太大,1G.2G直传服务器压力过大 ②部分追求完美的人不发接受直传,那只能分片上传 ③分片上传是我找到的比较合理的解决 ...

  4. layui 文件实现分片上传和 断点续传 和 急速秒传 SpringBoot JAVA

    一丶分片上传 分片上传 slice()这个方法功能是将一个文件切割为一系列特定大小的小数据片,分别将这些小数据片分别上传到服务端,全部上传完后再由服务端将这些小数据片合并成为一个完整的资源. 二 丶 ...

  5. webuploader插件 前端实现图片旋转后上传

    前端上传图片正向的图片,上传后就被旋转了.这是因为,图片中包含许多属性来记录拍摄信息.引入EXIF就可以读取这些属性. 引入exif.js文件 exif.js文件下载地址:http://code.ci ...

  6. php限制文件类型,限制上传文件类型程序代码_PHP教程

    我们一般不会在前段限制用户上传文件时的文件类,因为也没什么好的办法来限制只能使用像php,asp这类来操作,下面我来介绍利用js来定义type=file浏览上传时的文件类型与php中限制上传文件类型代 ...

  7. html 5 上传图片教程,HTML5实现多文件多图上传实例

    HTML5上传图片 注意图片太小的话,看不到进度条 读取进度: //定义获取对象的方法 function $(id) { return document.getElementById(id); } v ...

  8. 【JS实战】base64转换为file文件类型(上传头像为例子)

    base64转换为file类型 点击头像,选择文件 点击选取时,获取base64文件 这里使用了Vue-ImgCut插件(后续博客介绍) 代码讲解 function base64toFile(data ...

  9. 简单的文件操作-分片上传【h5技术】

    在以前我们用分片上传很麻烦可能还需要用到一些库,今天给大家带来H5的分片上传,简单易学 <input type="file" id="input"> ...

最新文章

  1. linux新建文件权限问题
  2. TeamLab安装及使用
  3. Android性能优化典范第四季
  4. linux可读可写为啥设置421
  5. hexo : 无法加载文件 C:\Users\mxz\AppData\Roaming\npm\hexo.ps1,因为在此系统上禁止运行脚本。
  6. 阿里巴巴数据分析沙龙 杭州站圆满召开
  7. apache +php + mysql_apache+php+mysql
  8. scm maven_在运行时访问工件的Maven和SCM版本
  9. centeros7安装mysql
  10. OpenCV3学习(4.2)——图像常用滤波方法(方框、均值、高斯、中值、双边)
  11. 数学图形(1.49)Nephroid曲线
  12. 申请以及集成 Stripe 的 Alipay 支付方案
  13. Atitit..状态机与词法分析  通用分词器 分词引擎的设计与实现 attilax总结
  14. 开发小工具和一些小技巧
  15. cai鸟驿站管理系统
  16. 程序员最爱的11个在线社区,你去过几个?
  17. linux reboot故障
  18. 经常问到的前端面试题
  19. 加密货币涨跌的原理到底是什么?
  20. 第七篇 nacos 注册中心

热门文章

  1. 最新Java校招面试题及答案
  2. MySQL安装 - Linux7下. rpm方式安装
  3. objective-c 语法快速过(4)
  4. 如何手工完全卸载SQL SERVER 2000数据库
  5. 我编程很渣,但我就是喜欢编程,我该怎么做?放弃还是继续坚持?
  6. 帆软《商业智能》书籍首发,国产BI行业独家,福利发售!
  7. NanShan作者:风景未变人已变
  8. 可到了关键部分的作文
  9. 飞鸽传书的这一新的通信方式采用云技术
  10. 再讨论下古老的include