更新文件上传插件

This commit is contained in:
邹景立 2017-02-22 13:23:37 +08:00
parent b461b5c51e
commit a158e01605
4 changed files with 171 additions and 91 deletions

View File

@ -3,7 +3,9 @@
namespace app\admin\controller;
use controller\BasicAdmin;
use library\Data;
use library\File;
use think\Db;
/**
* 插件助手控制器
@ -29,13 +31,14 @@ class Plugs extends BasicAdmin {
/**
* 文件上传
*/
public function upfile() {
public function upfile($mode = 'one') {
$types = $this->request->get('type', 'jpg,png');
$field = $this->request->get('field', 'file');
$this->assign('field', $field);
$this->assign('types', $types);
$this->assign('mimes', File::getMine($types));
$this->assign('uptype', '');
$this->assign('uptype', sysconf('storage_type'));
$this->assign('mode', $mode);
return view();
}
@ -43,10 +46,18 @@ class Plugs extends BasicAdmin {
* 检查文件上传状态
*/
public function upstate() {
$data = $this->request->post();
$this->result($data, 'IS_UPLOADED');
$this->result($data, 'NOT_FOUND');
$post = $this->request->post();
$data = array();
$data['uptype'] = $post['uptype'];
$data['file_url'] = date('Y/md') . "/{$post['md5']}." . pathinfo($post['filename'], 4);
$data['token'] = $this->_getQiniuToken($data['file_url']);
$data['server'] = url('admin/plugs/upload');
$file = Db::name('SystemFile')->where(['uptype' => $post['uptype'], 'md5' => $post['md5']])->find();
// 本地上传或文件不存在
if (empty($file) || ($file['uptype'] === 'local' && !file_exists($file['full_path']))) {
return $this->result($data, 'NOT_FOUND');
}
return $this->result($file, 'IS_FOUND');
}
/**
@ -54,62 +65,52 @@ class Plugs extends BasicAdmin {
* @param string $key
* @return string
*/
protected function _getToken($key) {
$accessKey = sysconf('qiniu_accesskey');
$secretKey = sysconf('qiniu_secretkey');
$bucket = sysconf('qiniu_bucket');
$host = sysconf('qiniu_domain');
$protocol = sysconf('qiniu_protocol');
protected function _getQiniuToken($key) {
$accessKey = sysconf('storage_qiniu_access_key');
$secretKey = sysconf('storage_qiniu_secret_key');
$bucket = sysconf('storage_qiniu_bucket');
$host = sysconf('storage_qiniu_domain');
$protocol = sysconf('storage_qiniu_is_https') ? 'https' : 'http';
$time = time() + 3600;
if (empty($key)) {
exit('param error');
} else {
$data = array(
"scope" => "{$bucket}:{$key}",
"deadline" => $time,
"returnBody" => "{\"data\":{\"site_url\":\"{$protocol}://{$host}/$(key)\",\"file_url\":\"$(key)\"}, \"code\": \"SUCCESS\"}",
);
}
empty($key) && exit('param error');
$params = [
"scope" => "{$bucket}:{$key}",
"deadline" => $time,
"returnBody" => "{\"data\":{\"site_url\":\"{$protocol}://{$host}/$(key)\",\"file_url\":\"$(key)\"}, \"code\": \"SUCCESS\"}",
];
$find = array('+', '/');
$replace = array('-', '_');
$data = str_replace($find, $replace, base64_encode(json_encode($data)));
$data = str_replace($find, $replace, base64_encode(json_encode($params)));
$sign = hash_hmac('sha1', $data, $secretKey, true);
return $accessKey . ':' . str_replace($find, $replace, base64_encode($sign)) . ':' . $data;
}
/**
* 文件上传
* 通用文件上传
* @return string
*/
public function upload() {
if (request()->isPost()) {
$filepath = 'upload/' . date('Y/md');
$file = request()->file('file');
$info = $file->move($filepath);
if ($info) {
if ($this->request->isPost()) {
$filepath = 'upload' . DS . date('Y/md');
$file = $this->request->file('file');
if (($info = $file->move($filepath))) {
$data = [];
$data['uptype'] = 'local';
$data['md5'] = input('post.md5', $info->md5());
$data['md5'] = $this->request->post('md5', $info->md5());
$data['real_name'] = $info->getInfo('name');
$data['file_name'] = $info->getFilename();
// $data['file_type'] = $info->getInfo('type');
$data['file_path'] = $info->getPathname();
$data['full_path'] = $info->getRealPath();
$data['orig_name'] = $info->getInfo('name');
$data['client_name'] = $info->getInfo('name');
$data['file_ext'] = $info->getExtension();
$data['file_url'] = $filepath . '/' . $info->getSaveName();
$data['site_url'] = pathinfo(request()->baseFile(true), PATHINFO_DIRNAME) . '/' . $data['file_url'];
$data['file_size'] = $info->getSize();
$data['create_by'] = get_user_id();
Db::table('system_file')->insert($data);
return json(['code' => 'SUCCESS', 'data' => $data]);
$data['file_url'] = str_replace('\\', '/', $filepath . '/' . $info->getSaveName());
$data['site_url'] = pathinfo($this->request->baseFile(true), PATHINFO_DIRNAME) . '/' . $data['file_url'];
$data['create_by'] = session('user.id');
Data::save('SystemFile', $data, 'md5', ['uptype' => 'local']);
return json(['data' => $data, 'code' => 'SUCCESS']);
}
}
return json([]);
}
public function upload() {
return json(['code' => 'ERROR']);
}
/**

View File

@ -95,7 +95,8 @@
<label class="layui-form-label">网站Logo</label>
<div class="layui-input-block">
<img data-tips-image="" style="height:auto;max-height:32px;min-width:32px" src="{:sysconf('site_logo')}"/>
<input type="text" name="site_logo" required="required" title="请输入公司名称" placeholder="请输入公司名称" value="{:sysconf('site_logo')}" class="layui-input hide">
<input type="hidden" onchange="$(this).prev('img').attr('src', this.value)" name="site_logo" class="layui-input">
<a class="btn btn-link" data-file="one" data-type="jpg,png,gif" data-field="site_logo">上传图片</a>
</div>
<div class="layui-form-mid layui-word-aux">
建议LOGO图片的尺寸为160x56px此LOGO图片用于后台登陆页面。
@ -104,10 +105,9 @@
<div class="layui-form-item layui-box">
<label class="layui-form-label">浏览器图标</label>
<div class="layui-input-block">
<img data-tips-image="" style="height:auto;max-height:32px;min-width:32px"
src="{:sysconf('app_logo')}"/>
<input type="text" name="app_logo" title="请输入公司名称" placeholder="请输入百度统计ID" value="{:sysconf('app_logo')}" class="layui-input hide">
<a class="btn btn-link" data-file="" data-one="true" data-type="ico,png" data-field="site_logo">上传图片</a>
<img data-tips-image="" style="height:auto;max-height:32px;min-width:32px" src="{:sysconf('app_logo')}"/>
<input type="hidden" name="app_logo" onchange="$(this).prev('img').attr('src', this.value)" value="{:sysconf('app_logo')}" class="layui-input">
<a class="btn btn-link" data-file="one" data-type="ico,png" data-field="app_logo">上传图片</a>
</div>
<div class="layui-form-mid layui-word-aux">
建议上传ICO图标的尺寸为128x128px此图标用于网站标题前ICON在线制作。

View File

@ -26,6 +26,9 @@
</div>
<div class="info"></div>
<div class="btns">
{if $mode!=='one'}
<div id="filePicker2"></div>
{/if}
<div class="uploadBtn">开始上传</div>
</div>
</div>
@ -38,13 +41,43 @@
* @type Function
*/
function uploaded(ret, file) {
$('#' + file.id).attr('data-md5', file.md5).attr('data-src', ret.url || ret.site_url);
var url = ret.url || ret.site_url;
$('#' + file.id).attr('data-md5', file.md5).attr('data-src', url);
/* {if $mode === 'one'} */
top.$('[name="{$field}"]').map(function () {
top.$(this).attr('data-srcs', ret.url).attr('data-md5', file.md5).val(ret.url || ret.site_url).trigger('change');
top.$(this).attr('data-srcs', ret.url).attr('data-md5', file.md5).val(url).trigger('change');
});
//top.$.msg.tips('文件上传成功!');
var index = top.layer.getFrameIndex(window.name);
top.layer.close(index);
/* {/if} {$mode}*/
}
function confirmSelected() {
var srcs = new Array();
var md5s = new Array();
$('[data-md5] .success').map(function () {
var $li = $(this).parents('[data-md5]');
md5s.push($li.attr('data-md5'));
srcs.push($li.attr('data-src'));
});
if (srcs.length < 1) {
return top.$.msg.tips('还没有选择文件,请勾选需要使用的文件!');
}
top.$('[name="{$field}"]').map(function () {
top.$(this).attr('data-srcs', srcs.join('|')).attr('data-md5', md5s.join('|')).val(srcs.join('|')).trigger('change');
});
var index = top.layer.getFrameIndex(window.name);
top.layer.close(index);
}
function completed() {
var btnHTML = '完成上传';
$('.uploadBtn').on('click', function () {
if (this.innerHTML === btnHTML) {
confirmSelected.call(this);
}
}).html(btnHTML);
}
// 当domReady的时候开始初始化
@ -82,7 +115,7 @@
if (this.width != 1 || this.height != 1) {
support = false;
}
}
};
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
return support;
}.call(this)),
@ -103,12 +136,10 @@
return parseFloat(version[ 0 ] + '.' + version[ 1 ], 10);
})(),
supportTransition = (function () {
var s = document.createElement('p').style,
r = 'transition' in s || 'WebkitTransition' in s || 'MozTransition' in s || 'msTransition' in s || 'OTransition' in s;
var s = document.createElement('p').style, r = 'transition' in s || 'WebkitTransition' in s || 'MozTransition' in s || 'msTransition' in s || 'OTransition' in s;
s = null;
return r;
})(),
/*WebUploader实例*/
uploader;
if (!WebUploader.Uploader.support('flash') && WebUploader.browser.ie) {
/*flash 安装了但是版本过低*/
@ -149,32 +180,20 @@
return;
}
WebUploader.Uploader.register({
'before-send-file': 'preupload'
}, {
preupload: function (file) {
WebUploader.Uploader.register({'before-send-file': 'preupload'}, {preupload: function (file) {
var me = this, owner = this.owner, deferred = WebUploader.Deferred();
owner.md5File(file.source).fail(function () {
deferred.reject();
}).then(function (md5) {
file.md5 = md5;
$.ajax("{:url('admin/plugs/upstate')}", {
dataType: 'json',
method: 'post',
data: {
id: file.id,
md5: md5,
uptype: '{$uptype}',
filename: file.name,
},
success: function (ret) {
if (ret.code !== 'IS_UPLOADED') {
// 文件
var data = {id: file.id, md5: md5, uptype: '{$uptype}', filename: file.name};
$.ajax("{:url('admin/plugs/upstate')}", {dataType: 'json', method: 'post', data: data, success: function (ret) {
if (ret.code !== 'NOT_FOUND') {
owner.skipFile(file);
uploaded.call(uploader, ret.data, file);
console.log('文件秒传成功file -> ' + file.name);
percentages[ file.id ] = [file.size, 1];
percentages[file.id] = [file.size, 1];
updateTotalProgress();
console.log('文件秒传成功 --> ' + file.name);
} else {
file.md5 = md5;
file.token = ret.data.token;
@ -202,20 +221,27 @@
mimeTypes: '{$mimes}'
},
formData: {},
/*{if $mode === 'one'}*/
fileNumLimit: 1,
auto: true,
/* {else /} */
auto: false,
fileNumLimit: 300,
/* {/if} */
compress: false,
dnd: '#dndArea',
paste: document.body,
swf: '__STATIC__/plugs/uploader/Uploader.swf',
chunked: false,
chunkSize: 512 * 1024,
server: '{"plugs/file/upload"|url}',
server: '{:url("admin/plugs/upload")}',
disableGlobalDnd: true,
fileNumLimit: 1,
fileSizeLimit: 200 * 1024 * 1024, // 200 M
fileSingleSizeLimit: 200 * 1024 * 1024 // 200 M
});
/**
* 处理上传后的结果
* @param {type} file
@ -233,7 +259,7 @@
uploader.on('dndAccept', function (items) {
var denied = false, len = items.length;
var unAllowed = 'text/plain;application/javascript ';
for (i = 0; i < len; i++) {
for (var i = 0; i < len; i++) {
if (~unAllowed.indexOf(items[ i ].type)) {
denied = true;
break;
@ -241,6 +267,7 @@
}
return !denied;
});
/* 上传开始前的处理 */
uploader.on('uploadBeforeSend', function (file, data, header) {
header['X_Requested_With'] = 'XMLHttpRequest';
@ -250,6 +277,12 @@
data['token'] = file.file.token;
});
// 添加“添加文件”的按钮,
uploader.addButton({
id: '#filePicker2',
label: '继续添加'
});
uploader.on('ready', function () {
window.uploader = uploader;
});
@ -268,6 +301,7 @@
$wrap = $li.find('p.imgWrap'),
$info = $('<p class="error"></p>'),
showError = function (code) {
var text = '';
switch (code) {
case 'exceed_size':
text = '文件大小超出';
@ -296,11 +330,7 @@
img = $('<img src="' + src + '">');
$wrap.empty().append(img);
} else {
$.ajax('{"plugs/file/preview"|url}', {
method: 'POST',
data: src,
dataType: 'json'
}).done(function (response) {
$.ajax('{"plugs/file/preview"|url}', {method: 'POST', data: src, dataType: 'json'}).done(function (response) {
if (response.result) {
img = $('<img src="' + response.result + '">');
$wrap.empty().append(img);
@ -363,12 +393,7 @@
}
if (supportTransition) {
deg = 'rotate(' + file.rotation + 'deg)';
$wrap.css({
'-webkit-transform': deg,
'-mos-transform': deg,
'-o-transform': deg,
'transform': deg
});
$wrap.css({'-webkit-transform': deg, '-mos-transform': deg, '-o-transform': deg, 'transform': deg});
} else {
$wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');
}
@ -432,11 +457,13 @@
break;
case 'ready':
$placeHolder.addClass('element-invisible');
$('#filePicker2').removeClass('element-invisible');
$queue.show();
$statusBar.removeClass('element-invisible');
uploader.refresh();
break;
case 'uploading':
$('#filePicker2').addClass('element-invisible');
$progress.show();
$upload.text('暂停上传');
break;
@ -446,6 +473,7 @@
break;
case 'confirm':
$progress.hide();
$('#filePicker2').removeClass('element-invisible');
$upload.text('开始上传');
stats = uploader.getStats();
if (stats.successNum && !stats.uploadFailNum) {
@ -456,7 +484,7 @@
case 'finish':
stats = uploader.getStats();
if (stats.successNum) {
//completed.call(this);
completed.call(this);
} else {
// 没有成功的文件,重设
state = 'done';
@ -467,6 +495,58 @@
updateStatus();
}
// function setState(val) {
// var file, stats;
// if (val === state) {
// return;
// }
// $upload.removeClass('state-' + state);
// $upload.addClass('state-' + val);
// state = val;
// switch (state) {
// case 'pedding':
// $placeHolder.removeClass('element-invisible');
// $queue.hide();
// $statusBar.addClass('element-invisible');
// uploader.refresh();
// break;
// case 'ready':
// $placeHolder.addClass('element-invisible');
// $queue.show();
// $statusBar.removeClass('element-invisible');
// uploader.refresh();
// break;
// case 'uploading':
// $progress.show();
// $upload.text('暂停上传');
// break;
// case 'paused':
// $progress.show();
// $upload.text('继续上传');
// break;
// case 'confirm':
// $progress.hide();
// $upload.text('开始上传');
// stats = uploader.getStats();
// if (stats.successNum && !stats.uploadFailNum) {
// setState('finish');
// return;
// }
// break;
// case 'finish':
// stats = uploader.getStats();
// if (stats.successNum) {
// completed.call(this);
// } else {
// // 没有成功的文件,重设
// state = 'done';
// location.reload();
// }
// break;
// }
// updateStatus();
// }
uploader.onUploadProgress = function (file, percentage) {
var $li = $('#' + file.id), $percent = $li.find('.progress span');
$percent.css('width', percentage * 100 + '%');
@ -497,7 +577,6 @@
};
uploader.on('all', function (type) {
var stats;
switch (type) {
case 'uploadFinished':
setState('confirm');

View File

@ -75,10 +75,10 @@ define(['jquery', 'admin.plugs'], function () {
this.$body.on('click', '[data-file]', function () {
var type = $(this).attr('data-type') || 'jpg,png';
var field = $(this).attr('data-field') || 'file';
var method = $(this).attr('data-one') ? 'one' : 'index';
var title = $(this).attr('data-title') || '文件管理';
var uptype = $(this).attr('data-uptype') || 'qiniu';
var url = window.ROOT_URL + '/index.php/admin/plugs/upfile/' + method + '.html?uptype=' + uptype + '&type=' + type + '&field=' + field;
var method = $(this).attr('data-file') === 'one' ? 'one' : 'mtl';
var title = $(this).attr('data-title') || '文件上传';
var uptype = $(this).attr('data-uptype') || 'local';
var url = window.ROOT_URL + '/index.php/admin/plugs/upfile/mode/' + method + '.html?uptype=' + uptype + '&type=' + type + '&field=' + field;
$.form.iframe(url, title || '文件管理');
});