开发项目使用中插件配置为main.js
require.config({ paths : { "jquery" : "lib/jquery-1.10.2.min", "angular" : "lib/angular/angular.min", "angularResource" : "lib/angular/angular-resource", "uiRoute" : "lib/ui-router/angular-ui-router.min", "angularSanitize" : "lib/angular/angular-sanitize.min", "angularCookies" : "lib/angular/angular-cookies", "angularLocale" : "lib/angular/i18n/angular-locale_zh-cn", "bootstrapUI" : "lib/angular/angularUI/ng-bootstrap/ui-bootstrap-tpls-0.12.1.min", "bootstrapJs" : "lib/bootstrap.min", "datetimepicker" : "lib/datetimepicker/js/bootstrap-datetimepicker.min", "datetimepickerCn" : "lib/datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN", "jquery.zclip" : "lib/zclip/jquery.zclip.min", "jqueryUI" : "lib/jqueryui/jquery-ui-1.10.3.custom.min", "jqueryUITouchPunch" : "lib/jquery-ui-touch-punch/jquery.ui.touch-punch.min", "uislider" : "lib/uislider/slider", "dragscrollable" : "lib/dragscrollable/dragscrollable.min", "moment" : "lib/moment/moment", "websocket" : "lib/websocket", "md5" : "lib/md5/md5", "des" : "lib/crypto/tripledes", "crypto": "lib/crypto/core", "ecb" : "lib/crypto/mode-ecb", "lodash" : "lib/lodash/lodash.min", "postal" : "lib/postal/postal.min", "jcrop" : "lib/jcrop/jquery.Jcrop.min", "ngTable" : "lib/table/ng-table", "ueditor" : "lib/ueditor/ueditor.all", "ueditor.config" : "lib/ueditor/ueditor.config", "angularUEditor": "lib/angular-ueditor/angular-ueditor.min", "spin": "lib/spin.js/spin.min", "caret" : "lib/caret/jquery.caret", "pdfobject" : "lib/pdfobject/pdfobject", "webuploader": "lib/webuploader/webuploader.html5only", "IndexedDBShim": "lib/IndexedDBShim/IndexedDBShim", "jqueryIndexeddb": "lib/jquery-indexeddb/jquery.indexeddb", "uiSortable":"lib/ui-sortable/sortable", "xeditable":"lib/xeditable/xeditable", "qrcode" : "lib/jquery-qrcode/jquery.qrcode.min" }, shim : { "angular" : { "deps" : ["jquery"], "exports" : "angular" }, "angularLocale" : ["angular"], "uiRoute" : ["angular"], "angularResource" : ["angular"], "angularSanitize" : ["angular"], "angularCookies" : ["angular"], "bootstrapUI" : ["angular"], "bootstrapJs" : ["jquery"], "datetimepicker": ["jquery"], "datetimepickerCn": ["datetimepicker"], "jqueryUI": ["jquery"], "jqueryUITouchPunch": ["jqueryUI"], "uislider": ["angular", "jqueryUI", "jqueryUITouchPunch"], "moment": {"exports" : "moment"}, 'websocket': {'exports' : 'YGWebSocket'}, 'ecb':['des'], 'jcrop': ['jquery'], 'ngTable' : ["angular"], 'ueditor': ['ueditor.config'], 'angularUEditor': ["ueditor"], 'webuploader': ['jquery'], 'jqueryIndexeddb': ['jquery', 'IndexedDBShim'], 'uiSortable':["angular","jqueryUI"], 'dragscrollable': ['jquery'], 'xeditable' : ['angular'] }, priority: [ "jquery", "angular" ] }); require(["app"], function (app) { $(document).ready(function() { angular.bootstrap(document, [app.name]); }); });
"webuploader": "lib/webuploader/webuploader.html5only",是插件在项目中的地址。
1.编写一个directives —— Upload.js
define([
'app',
'jquery',
'webuploader',
'filters/byte'
], function (app, $, WebUploader) {
'use strict';
var deps = [ 'BaseService' ];
function directive(BaseService) {
return {
scope: {
uploadUrl: '@fcUpload',
multiple: '@?',
label: '@?',
dndInfo: '@?',
accept: '@?',
uploaderOption: '=?'
},
templateUrl: 'views/common/upload/Upload.html',
replace: true,
link: function link($scope, elem) {
$scope.files = [];
$scope.progressStylies = {};
$scope.uploadUrl = BaseService.restfulUrl + $scope.uploadUrl;
var uploader = init($scope, elem);
$scope.$on('$destroy', function scopeDestroy() {
uploader.destroy();
});
$scope.remove = function remove(file, index) {
doRemove($scope, uploader, file, index);
};
}
};
}
function doRemove($scope, uploader, file, index) {
$scope.files.splice(index, 1);
$scope.progressStylies[file.id] = null;
uploader.removeFile(file, true);
}
function init($scope, elem) {
var btn = elem.find('.js-btn-pick');
var dndContainer = elem.find('.js-dnd-container');
//上传类型限制保存对象
var typelist = ["doc","docx","xls","xlsx","ppt","pptx","pdf"];
var option = getOption($scope, btn, dndContainer);
var uploader = WebUploader.create(option);
// material design 的样式设置有些古怪, 需要是`btn btn-` 开头的才会应用到一些样式, 所以这里把默认的webuploader-pick 放到后面去.
var $realBtn = btn.find('.webuploader-pick').removeClass('webuploader-pick').addClass('btn btn-info webuploader-pick');
setTimeout(function() {
// 由于有个 + 号的符号在前面, 导致默认的计算宽度的处理有些偏小, 这里重新计算一下
$realBtn.next().width($realBtn.outerWidth());
}, 1000);
if ($scope.dndInfo) {
elem.find('.js-dnd-info').text($scope.dndInfo);
} else if (option.accept && option.accept.title) {
elem.find('.js-dnd-info').text('或将' + option.accept.title + ' 文件拖到虚线框内');
}
function tryRemainSingleFile() {
if (!option.pick.multiple) {
// 单选的, 直接把之前的文件清掉
for (var i = $scope.files.length - 1; i >= 0; i--) {
doRemove($scope, uploader, $scope.files[i], i)
}
}
}
// 当有文件被添加进队列的时候
uploader.on('fileQueued', function fileQueued(file) {
//进行上传类型判断
if(typelist.indexOf(file.ext) != -1 && file.size <= 52428800)
{
tryRemainSingleFile();
$scope.files.push(file);
$scope.$bus.publish({
channel: 'upload',
topic: 'fileQueued',
data: file
});
$scope.$apply();
}else{
if(file.size > 52428800)
{
alert("选择的格式文件超出限定大小");
}
else{
alert("请选择正确的格式文件");
}
}
});
// 当有文件被移出队列的时候
uploader.on('fileDequeued', function fileDequeued(file) {
$scope.$bus.publish({
channel: 'upload',
topic: 'fileDequeued',
data: file
});
});
uploader.on('error', function error(type) {
$scope.$bus.publish({
channel: 'upload',
topic: 'error',
data: type
});
});
// 文件上传过程中创建进度条实时显示。
uploader.on('uploadProgress', function uploadProgress(file, percentage) {
$scope.progressStylies[file.id] = $scope.progressStylies[file.id] || {};
$scope.progressStylies[file.id].width = percentage * 100 + '%';
$scope.$apply();
});
uploader.on('uploadSuccess', function uploadSuccess(file, response) {
$scope.progressStylies[file.id].width = '100%';
$scope.$bus.publish({
channel: 'upload',
topic: 'uploadSuccess',
data: {
file: file,
response: response
}
});
$scope.$apply();
});
uploader.on('uploadError', function uploadError(file, reason) {
$scope.progressStylies[file.id].width = '0%';
$scope.$bus.publish({
channel: 'upload',
topic: 'uploadError',
data: {
file: file,
reason: reason
}
});
$scope.$apply();
});
uploader.on('uploadFinished', function uploadFinished() {
$scope.$bus.publish({
channel: 'upload',
topic: 'uploadFinished',
data: {}
});
});
$scope.$bus.subscribe({
channel: 'upload',
topic: 'start',
callback: function startUpload() {
uploader.upload();
}
});
$scope.$bus.subscribe({
channel: 'upload',
topic: 'stop',
callback: function stopUpload() {
uploader.stop();
}
});
return uploader;
}
function getOption($scope, btn, dnd) {
var option = {
// swf文件路径
swf: 'bower_components/fex-webuploader/dist/Uploader.swf',
// 文件接收服务端。
server: $scope.uploadUrl,
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: {
id: btn,
multiple: $scope.multiple == null || $scope.multiple === 'true',
innerHTML: $scope.label || '<span class="glyphicon glyphicon-plus"></span> 选择文件'
},
dnd: dnd,
thumb: false,
compress: false
};
if ($scope.accept) {
option.accept = {
title: 'Files',
extensions: 'jpg,jpeg,png,pdf',
mimeTypes: 'image/jpg,image/jpeg,image/png,application/pdf'
};
}
if ($scope.accept === "Files") {
option = $.extend({}, $scope.uploaderOption, option);
}
return option;
}
directive.$inject = deps;
return app.lazy.directive('fcUpload', directive);
});
<div class="upload-container"> <!--用来存放文件信息--> <div ng-if="files.length > 0" class="js-uploader-list"> <table class="table table-striped"> <tr ng-repeat="file in files track by file.id" ng-class="{ success: file.getStatus() === 'complete', danger: file.getStatus() === 'error', warning: file.getStatus() === 'interrupt' }"> <td class="hide"></td> <td class="col-md-5 text-left">{{ file.name }}</td> <td class="col-md-2 text-left">{{ file.size | byte }}</td> <td class="col-md-5"> <div ng-class="{ active: file.getStatus() === 'progress' }" class="progress progress-striped"> <div class="progress-bar" ng-style="progressStylies[file.id]"></div> </div> </td> <td class="cs-btn-cell"><a href ng-click="remove(file, $index)" class="close">×</a></td> </tr> </table> </div> <div class="upload-dnd-container js-dnd-container"> <div class="js-btn-pick">选择文件</div> <div class="upload-dnd-info js-dnd-info">或将文件拖到虚线框内</div> </div> </div>
2.控制器导入directives
define(["app", "bootstrapJs", "services/BaseService", "services/TipsService", 'directives/ImageCrop', 'directives/alicebot/LearnSearchPicker', 'directives/Upload' ],function (app) { var deps = ["$scope", "$state", "$stateParams", "AlicebotResource", "TipsService"]; function controller($scope, $state, $stateParams, AlicebotResource, TipsService) { $scope.selectMenuId = $stateParams.selectMenuId; $scope.docList = []; var files = {}; $scope.attachLength = 0; $scope.uploaderOption = { fileSingleSizeLimit: 50 * 1024 * 1024 }; function saveAttachs() { $scope.$bus.publish({ channel: 'upload', topic: 'start', data: null }); } $scope.$bus.subscribe({ channel: 'upload', topic: 'fileQueued', callback: function fileQueued(file) { files[file.id] = file; $scope.attachLength++; if (!$scope.$$phase) { $scope.$apply(); } } }); $scope.$bus.subscribe({ channel: 'upload', topic: 'fileDequeued', callback: function fileDequeued(file) { delete files[file.id]; $scope.attachLength--; if (!$scope.$$phase) { $scope.$apply(); } } }); $scope.$bus.subscribe({ channel: 'upload', topic: 'error', callback: function error(type) { if (type === 'F_EXCEED_SIZE') { TipsService.show('请选择50M以下的文件!'); } } }); $scope.$bus.subscribe({ channel: 'upload', topic: 'uploadError', callback: function uploadError(file, reason) { var fileName = file.name; TipsService.show(fileName+'上传失败!'); } }); $scope.$bus.subscribe({ channel: 'upload', topic: 'uploadSuccess', callback: function uploadSuccess(data) { if(data.response._raw !=undefined){ files[data.file.id].attachId = data.response._raw; } } }); $scope.$bus.subscribe({ channel: 'upload', topic: 'uploadFinished', callback: function uploadFinished() { //上传成功 将信息保存到数据库 _.forOwn(files, function eachFile(value) { if(value.attachId !=undefined){ $scope.docList.push(value.attachId); AlicebotResource.docsUpdate($scope.selectMenuId,value.attachId).success(function(data){ if(!data){ TipsService.show(value.name+"上传失败"); } if(_.size(files) == $scope.docList.length){ $scope.cancel(); } }); } }); } }); /** * 删除附件资料 */ $scope.removeAttach = function removeAttach(file) { _.remove($scope.message.attachments, function removeCond(vo) { return vo.attachId === file.attachId; }); _.remove($scope.message.attachments, function removeCond(attachId) { return attachId === file.attachId; }); }; $scope.save = function(){ saveAttachs(); } $scope.cancel= function(){ $state.go('home.docmanagement'); } } controller.$inject = deps; return app.lazy.controller("DocUploadController", controller); });
<style> .col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-8,.col-md-10,.col-md-12{padding-left: 0;} </style> <div> <div class="clearfix col-m-l marginLeft0"> <div class="form col-md-8 paddingLeft0"> <div class="form-group"> <label>文档资料</label> <div ng-if="message.attachments.length > 0"> <table class="table table-striped" ng-class="{ marginBottom0: attachLength > 0 }"> <tr ng-repeat="file in message.attachments track by file.attachId"> <td class="hide"></td> <td class="col-md-5 text-left"><a ng-href="restful/fileUploadController/downFile?fileId={{ file.attachId }}">{{ file.attachName }}</a></td> <td class="col-md-2 text-left">{{ file.attachSize | byte }}</td> <td class="col-md-5"></td> <td class="cs-btn-cell"><a href ng-click="removeAttach(file)" class="close">×</a></td> </tr> </table> </div> <div class="col-sm-12 thumbnail"> <div data-tabset class="tab-content" style="margin-top: 10px"> <div data-tab data-heading="上传附件" style="cursor: pointer;"> <div fc-upload="ccalice/docsUpload" uploader-option="uploaderOption" dnd-info="拖放到这里上传附件(每个文件大小50M以下)"></div> </div> </div> </div> </div> <div class="form-group text-right"> <button data-ng-click="save()" class="btn btn-primary">保存</button> <button data-ng-click="cancel()" class="btn btn-default">返回</button> </div> </div> </div> </div>