backman
Version:
基于Angluar与bootstrap进行后台管理系统快速搭建的前端框架
1,246 lines (1,140 loc) • 48.6 kB
JavaScript
var backman = angular.module('backman', ['ui.router']);
backman.config(function ($httpProvider, $urlRouterProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
'use strict';
// 修正angularPost数据payload模式为formData模式
$httpProvider.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded';
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
$httpProvider.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest';
$httpProvider.defaults.headers.get = {'X-Requested-With': 'XMLHttpRequest'};
// Override $http service's default transformRequest
$httpProvider.defaults.transformRequest = [function (data) {
/**
* The workhorse; converts an object to x-www-form-urlencoded serialization.
* @param {Object} obj
* @return {String}
*/
var param = function (obj) {
var query = '';
var name, value, fullSubName, subName, subValue, innerObj, i;
for (name in obj) {
if (obj.hasOwnProperty(name)) {
value = obj[name];
if (value instanceof Array) {
for (i = 0; i < value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
} else if (value instanceof Object) {
for (subName in value) {
if (value.hasOwnProperty(subName)) {
subValue = value[subName];
/* fullSubName = name + '[' + subName + ']'; //for node */
fullSubName = name + '.' + subName;
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
} else if (value !== undefined && value !== null) {
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
}
}
return query.length ? query.substr(0, query.length - 1) : query;
};
return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
}];
//增加angular自动过滤特殊url白名单
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|sms|javascript):/);
});
//路由转接
backman.run(function ($rootScope, $state, $stateParams) {
'use strict';
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
});
//backman创建模块
backman.module = function (name, dependences) {
'use strict';
var app = angular.module(name, ['backman'].concat(dependences));
app.config(function($controllerProvider, $compileProvider, $filterProvider, $provide){
//异步controller注册器
app.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
});
return app;
};
// 服务:地址tree全局缓存服务
backman.factory('_chinaAddress', function ($http, $q, _tools, _setting) {
'use strict';
// 清除使用旧的key的本地存储
var OldStorageKey = 'AREA_TREE';
localStorage.removeItem(OldStorageKey);
var tree = null;
var deferred2 = $q.defer();
var StorageKey = 'AREA_TREE20170324';
var tempTree = localStorage.getItem(StorageKey);
tempTree = tempTree?JSON.parse(tempTree) : [];
if(tempTree && tempTree.length) {
tree = tempTree;
deferred2.resolve(tree);
}else {
// 当前修改为请求远程文件的方式来获取区域信息
$http.get('../_data/region.json').then(function (data) {
if (data.data.state.code == 10200) {
tree = [];
var list = _tools.transKeyName('camel', data.data.data);
//匹配依赖依据:
//所有地址regionId存在从小到大排列的规律,且parentId必定比自身regionId小,所以parent元素必定先于自身已经被创建
for (var i = 0; i < list.length; i++) {
//省级
if (list[i].parentId == '' || list[i].parentId == '0') {
list[i].children = [];
tree.push(list[i]);
} else {
//市级
for (var j = 0; j < tree.length; j++) {
if (tree[j].regionId == list[i].parentId) {
list[i].children = [];
tree[j].children.push(list[i]);
break;
} else {
//区级
for (var k = 0; k < tree[j].children.length; k++) {
if (tree[j].children[k].regionId == list[i].parentId) {
tree[j].children[k].children.push(list[i]);
break;
}
}
}
}
}
}
} else {
tree = [];
}
localStorage.setItem(StorageKey, JSON.stringify(tree));
deferred2.resolve(tree);
}, function (err) {
tree = [];
deferred2.resolve(tree);
});
}
return {
getTree: function () {
if (tree) {
var deferred = $q.defer();
deferred.resolve(tree);
return deferred.promise;
} else {
return deferred2.promise;
}
},
getProvinces: function(){
return this.getTree();
},
getCities: function(provinceId){
return this.getProvinces().then(function(data){
for (var i = 0; i < data.length; i++) {
if (data[i].regionId == provinceId) {
return data[i].children;
}
}
});
},
getDistricts: function(provinceId, cityId){
return this.getCities(provinceId).then(function(data){
for (var i = 0; i < data.length; i++) {
if (data[i].regionId == cityId) {
return data[i].children;
}
}
});
},
/**
* 获取对应的区域id的数据
* @param {String} type 'provinces','cities','blocks'
* @param {String} regionId 区域id
* @return {Object} 区域id对应的对象
*/
getRegionIdData: function(arr, regionId){
var result = '';
if (arr) {
for (var i = 0, len = arr.length; i < len; i++) {
if (arr[i].regionId == regionId) {
result = arr[i].regionName;
break;
}
}
}
return result;
}
};
});
// 服务:请求预处理
backman.factory('_responePreHandler', function (_tools, _setting) {
'use strict';
return {
//正常通行
success: function (success, config) {
//需要重新登录
if (success.data.state.code == 20001) {
if (config && config.noVerify == true) {
return null;
}
layer.alert('您的登录已失效,即将跳转登录页...', {
icon: 0,
title: false,
closeBtn: 0
}, function () {
}
);
setTimeout(function () {
window.location.href = _setting.get('loginUrl');
}, 3000);
return null;
}
//正常code:10200
if (success.data.state.code == 10200) {
var data = success.data.data ? _tools.transKeyName('camel', success.data.data) : {};
data.__state = _tools.transKeyName('camel', success.data.state);
return data;
}
//正常code:10205
else if (success.data.state.code == 10205) {
return {
__state: _tools.transKeyName('camel', success.data.state)
};
}
//报错code
else {
var str = '错误:code ' + success.data.state.code + '<br>' + (success.data.state && success.data.state.msg);
layer.alert(str, {
icon: 2,
title: '通讯内容有误!'
});
return null;
}
},
//http级报错
error: function (err) {
layer.alert('错误:status ' + err.status + ' ' + err.statusText, {
icon: 2,
title: '建立通讯失败!'
});
return null;
}
};
});
backman.factory('_httpPost', function ($http, _tools, _responePreHandler, _setting) {
'use strict';
return function (url, postData, config) {
if (!config || !config.globAjaxParams) {
angular.extend(postData, _setting.globAjaxParams);
}
postData = _tools.transKeyName('underline', postData);
return $http({
method: 'POST',
url: url,
data: postData
}).then(function (success) {
return _responePreHandler.success(success, config);
}, function (err) {
return _responePreHandler.error(err);
}
);
};
});
backman.factory('_httpGet', function ($http, _tools, _responePreHandler, _setting) {
'use strict';
return function (url, getData, config) {
if (!config || !config.globAjaxParams) {
angular.extend(getData, _setting.globAjaxParams);
}
getData = _tools.transKeyName('underline', getData);
return $http({
method: 'GET',
url: url,
params: getData
}).then(function (success) {
return _responePreHandler.success(success, config);
}, function (err) {
return _responePreHandler.error(err);
});
};
});
backman.factory('_setting', function ($rootScope) {
'use strict';
var _data = {
base: location.protocol + '//' + location.host,
path: '/' + location.pathname.split('/index.html')[0],
globAjaxParams: {}
};
_data.path = _data.path == '/' ? '' : _data.path;
//左侧导航栏接口地址
_data.navListUrl = _data.base + _data.path + '/_data/navList.json';
//登录页地址
_data.loginUrl = _data.base + _data.path + '/login.html';
//退出登录接口地址
_data.logoutUrl = _data.base + _data.path + '';
//全局图片上传设置
_data.globUploadImg = {
//接口地址
url: '/api/upload-base64-image',
//base64键名
fileKeyName: 'base64File',
//同时发送的其他参数
parameters: {}
};
_data.userInforUrl = '/reseller-admin/user/user-info';
//富文本编辑器图片上传接口
_data.kindUploadImgUrl = '/api/upload-image';
return {
get: function (key) {
return _data[key];
},
set: function (key, val) {
if (key == 'globAjaxParams') {
if ($.type(val) == 'object') {
angular.extend(_data.globAjaxParams, val);
}
} else if (key == 'globUploadImg') {
if ($.type(val) == 'object') {
angular.extend(_data.globUploadImg, val);
}
} else {
_data[key] = val;
}
}
};
});
backman.constant('_tools', (function () {
'use strict';
//获取url参数
var urlData = null;
var getUrlParam = function (name) {
if (!urlData) {
var url = window.location.href;
urlData = {};
var arr = url.split("?");
if (arr.length > 1) {
arr = arr[1].split("&");
for (var i = 0, l = arr.length; i < l; i++) {
var a = arr[i].split("=");
urlData[a[0]] = a[1];
}
urlData = transKeyName('camel', urlData);
}
}
return urlData[name];
};
//峰驼与下划线命名模式转换
var transKeyName = function (type, json) {
//下划线字符串转小峰驼
var toCamel = function (str) {
var str2 = '';
if (str.indexOf('_') < 0) {
str2 = str;
} else {
var words = str.split('_');
for (var i = 1; i < words.length; i++) {
words[i] = words[i].substr(0, 1).toUpperCase() + words[i].substr(1);
}
str2 = words.join('');
}
return str2;
};
//小峰驼字符串转下划线
var toUnderline = function (str) {
var str2 = '';
if ((/[A-Z]/).test(str)) {
str2 = str.replace(/([A-Z])/g, function ($1) {
return '_' + $1.toLowerCase();
});
} else {
str2 = str;
}
return str2;
};
var transform = function (json, json2) {
for (var p in json) {
if (json.hasOwnProperty(p)) {
var key;
//字符串进行键名转换
if (!/^\d+$/.test(p)) {
if (type == 'camel') {
key = toCamel(p);
} else if (type == 'underline') {
key = toUnderline(p);
}
}
//数值直接传递
else {
key = parseInt(p);
}
//属性为对象时,递归转换
if (json[p] instanceof Object) {
json2[key] = transform(json[p], $.type(json[p]) == 'array' ? [] : {});
}
//属性非对象,为字符串但内容符合json格式,递归转换
else if ($.type(json[p]) == 'string' && /^[\{\[]+("([a-zA-Z][a-zA-Z0-9\-_]*?)"\:(.+?))+[\}\]]+$/.test(json[p])) {
json2[key] = JSON.parse(json[p]);
json2[key] = transform(json2[key], $.type(json2[key]) == 'array' ? [] : {});
json2[key] = JSON.stringify(json2[key]);
}
//属性非对象,非json字符串,直接传递
else {
json2[key] = json[p];
}
}
}
return json2;
};
return transform(json, $.type(json) == 'array' ? [] : {});
};
var loadJs = function (jsList) {
return function ($q, $rootScope) {
var deferred = $q.defer();
$script(jsList, function () {
$rootScope.$apply(function () {
deferred.resolve();
});
});
return deferred.promise;
};
};
return {
getUrlParam: getUrlParam,
transKeyName: transKeyName,
loadJs: loadJs
};
})());
backman.factory('_validate', function () {
'use strict';
return {
isMobile: function (val) {
var rgx = /^(13[0-9]|14[0-9]|15[0-9]|18[0-9])\d{8}$/i;
return rgx.test($.trim(val));
},
isRequired: function (val) {
return $.trim(val) ? true : false;
},
isMatchLength: function (val, len) {
return (($.trim(val)).length == len);
},
isLengthInRange: function (val, arr) {
var len = ($.trim(val)).length;
return (len >= arr[0] && len <= arr[1]);
},
isInRange: function (val, arr) {
return (val >= arr[0] && val <= arr[1]);
},
isIdCard: function (val) {
var rgx = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;
return rgx.test($.trim(val));
},
isTheSame: function (val1, val2) {
return (val1 == val2);
},
// 验证密码
isCorrectPassword: function (val) {
// 只包含数字或字母
var rgx = /^(?!\d+$)(?![a-z]+$).+$/i;
return rgx.test($.trim(val));
}
};
});
backman.controller('backmanFramework', function ($scope, _setting, _httpGet) {
'use strict';
//移动端导航栏显示隐藏
$scope.sidebarOpen = false;
$scope.act = {
//导航栏移动端显示隐藏
toggleSidebar: function () {
$scope.sidebarOpen = !$scope.sidebarOpen;
}
};
_httpGet(_setting.get('userInforUrl'),{});
});
backman.controller('backmanNavigation', function ($scope, _setting, _httpGet) {
'use strict';
var getNavData = function (cb, cberr) {
var apiAddress = _setting.get('navListUrl');
_httpGet(apiAddress, {})
.then(function (data) {
if ($.type(cb) === 'function') {
var navList = [];
for (var i = 0, item1; item1 = data[i]; i++) {
//第一级不允许使用连接
if (item1.state || item1.hash) {
continue;
}
//检查children属性
if ($.type(item1.children) != 'array') {
item1.children = [];
} else {
for (var j = 0, item2; item2 = item1[j]; j++) {
if ($.type(item2.children) != 'array') {
item2.children = [];
}
}
}
navList.push(item1);
}
cb(navList);
}
}, function (data) {
if ($.type(cberr) === 'function') {
cberr(data);
}
});
},
renderNavigation = function (data) {
//第一层排序
data = data.sort(sortNavigation);
for (var i = 0, item; item = data[i]; i++) {
if (item.children && item.children.length) {
//第二层排序
item.children.sort(sortNavigation);
}
}
$scope.navData = data;
},
sortNavigation = function (item1, item2) {
return item1.order > item2.order;
};
getNavData(renderNavigation);
});
backman.directive('bmDatepick', function () {
'use strict';
return {
scope: {
bindDate: '='
},
restrict: 'A',
link: function ($scope, iElm, iAttrs) {
var format = iAttrs.dateFormat || 'YYYY-MM-DD hh:mm:ss'; //日期格式
var timePick = /(hh|mm|ss)+/g.test(format); //是否开启时间选择
var eid = iAttrs.id || 'datepick' + (Date.now() % 1e7) + parseInt(Math.random() * 1e3);
iElm.attr('id', eid)
.attr('placeholder', format)
.addClass('laydate-icon')
.on('click', function () {
var $this = $(this);
if (!$this.attr('readonly')) {
$this[0].dispatchEvent(new MouseEvent('dblclick', {
bubbles: true,
cancelable: true,
view: window
}))
}
});
$('#' + eid).one('dblclick', function () {
var $this = $(this);
setTimeout(function(){
$('#laydate_today').on('click', function () {
$scope.bindDate = $this.val();
if (!$scope.$$phase && !$scope.$root.$$phase) {
$scope.$apply();
}
});
}, 0);
});
laydate({
elem: '#' + eid,
format: format,
istime: timePick,
event: 'dblclick',
choose: function (dates) {
$scope.bindDate = dates;
if (!$scope.$$phase && !$scope.$root.$$phase) {
$scope.$apply();
}
}
});
//初次数据
var initW = $scope.$watch('bindDate', function (newVal, oldVal) {
if (newVal) {
initW();
iElm.val(newVal);
}
});
}
}
});
// 指令: 处理多级联动下拉菜单
// disabled-select="1" 设置该属性将不能设置区域
backman.directive('bmDistpicker', function() {
'use strict';
return {
restrict: 'A',
scope: {
region: '=region', // 与控制器的$scope.region绑定
selectedPlace: '=selectedplace' // 与控制器的$scope.selectedPlace (双向)绑定
},
replace: true,
transclude: false,
template: '<div class="distpicker">' +
'<div class="distpicker-content" >' +
'<select class="" ng-options="province.regionId as province.regionName for province in region.provinces" ng-model="selectedPlace.provinceCode">' +
'<option value="" disabled>请选择省份</option>' +
'</select>' +
'<select class="" ng-options="city.regionId as city.regionName for city in region.cities" ng-model="selectedPlace.cityCode">' +
'<option value="" disabled>请选择市</option>' +
'</select>' +
'<select class="" ng-options="block.regionId as block.regionName for block in region.blocks" ng-model="selectedPlace.blockCode">' +
'<option value="" disabled>请选择区/县</option>' +
'</select>' +
'</div>' +
'</div>',
link: function(scope, iElement, iAttrs) {
if (parseInt(iAttrs.disabledSelect, 10) == 1) {
iElement.find('.distpicker-content>select').attr('disabled', 'disabled');
}
},
controller: function($scope, _chinaAddress) {
// 获取一次菜单
_chinaAddress.getTree().then(function(data) {
$scope.region.provinces = data;
});
// 省的变化
$scope.$watch('selectedPlace.provinceCode', function(newVal, oldVal, scope) {
// 如果值改变
if (!!newVal) {
// 设置显示的值 城市与区域
_chinaAddress.getCities($scope.selectedPlace.provinceCode).then(function(data) {
$scope.region.cities = data;
$scope.region.blocks = [];
});
$scope.selectedPlace = {
provinceCode: newVal, //省编号
cityCode: '', //市编号
blockCode: '', //区/县编号
provinceName: _chinaAddress.getRegionIdData($scope.region.provinces,newVal), //省名
cityName: '', //市名
blockName: '', //区/县名
};
}else{
$scope.region.cities = [];
$scope.region.blocks = [];
}
});
// 市的变化
$scope.$watch('selectedPlace.cityCode', function(newVal, oldVal, scope) {
// 如果值改变
if (!!newVal) {
// 设置显示的值 区域
_chinaAddress.getDistricts(
$scope.selectedPlace.provinceCode,
$scope.selectedPlace.cityCode
).then(function(data) {
$scope.selectedPlace.cityCode = newVal;
$scope.region.blocks = data;
});
// $scope.selectedPlace.blockCode = '';
scope.selectedPlace = {
provinceCode: $scope.selectedPlace.provinceCode, //省编号
cityCode: newVal, //市编号
blockCode: '', //区/县编号
provinceName: $scope.selectedPlace.provinceName, //省名
cityName: _chinaAddress.getRegionIdData($scope.region.cities,newVal), //市名
blockName: '', //区/县名
};
}else{
$scope.region.blocks = [];
}
});
// 区的变化
$scope.$watch('selectedPlace.blockCode', function(newVal, oldVal, scope) {
if (newVal !== oldVal) {
$scope.selectedPlace.blockCode = newVal;
$scope.selectedPlace = {
provinceCode: $scope.selectedPlace.provinceCode, //省编号
cityCode: $scope.selectedPlace.cityCode, //市编号
blockCode: newVal, //区/县编号
provinceName: $scope.selectedPlace.provinceName, //省名
cityName: $scope.selectedPlace.cityName, //市名
blockName: _chinaAddress.getRegionIdData($scope.region.blocks,newVal), //区/县名
};
}
});
}
};
});
backman.directive('bmEditor', function (_setting) {
'use strict';
return {
scope: {
bindContent: '='
},
restrict: 'A',
link: function ($scope, iElm, iAttrs) {
var eid = iAttrs.id || 'editor' + (Date.now() % 1e7) + parseInt(Math.random() * 1e3);
iElm.attr('id', eid);
var editor = KindEditor.create('#' + eid, {
items: [
'source', '|',
'undo', 'redo', '|',
'template', 'code', '|',
'cut', 'copy', 'paste', 'plainpaste', 'wordpaste', '|',
'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'insertorderedlist',
'insertunorderedlist', 'indent', 'outdent', 'subscript', 'superscript', 'clearhtml',
'quickformat', '|', 'selectall', 'fullscreen', '/',
'formatblock', 'fontname', 'fontsize', '|',
'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'strikethrough', 'lineheight',
'removeformat', '|',
'image', 'multiimage', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', 'anchor', 'link', 'unlink', '|',
'preview', 'print', 'about'
],
width: '100%',
height: '270px',
resizeMode: 1,
allowFileManager: false,
//imageUploadJson: _setting.get('kindUploadImgUrl') || '',
uploadJson: _setting.get('kindUploadImgUrl') || '',
afterChange: function () {
if (editor) {
$scope.bindContent = editor.html();
if (!$scope.$$phase && !$scope.$root.$$phase) {
$scope.$apply();
}
}
}
});
//初次数据
var initW = $scope.$watch('bindContent', function (newVal, oldVal) {
if (newVal) {
initW();
editor.html(newVal + '');
}
});
}
}
});
backman.directive('bmSidebar', function () {
return {
scope: false,
restrict: 'A',
link: function ($scope, iElm, iAttrs) {
iElm.on('click', '.treeview-title', function () {
var $this = $(this);
if ($this.parent().hasClass('active')) {
$this.parent().removeClass('active').end()
.next('ul.treeview-menu').slideUp('fast');
} else {
$this.parent().addClass('active').end()
.next('ul.treeview-menu').slideDown('fast');
}
});
var navInitHandler = $scope.$watch('navData', function (newValue, oldValue) {
if (newValue) {
navInitHandler(); //仅运行一次
var hash = window.location.hash;
setTimeout(function () {
iElm.find('.treeview-link').each(function () {
var $this = $(this);
if ($this.attr('href') == hash) {
var $parent1 = $this.parent().parent().show().parent().addClass('active');
if ($parent1.hasClass('treeview')) {
var $parent2 = $parent1.parent().show().parent().addClass('active');
if ($parent2.hasClass('treeview')) {
$parent2.addClass('active');
}
}
}
});
}, 0);
}
});
}
}
});
/*
* author:tank
* date:2016-12-12
* desc:component select2
*/
backman.directive('bmSelect2', function($timeout){
'use strict';
return {
scope: {
bindList:'=', // 列表中的数据集
bindSearch:'@', // 搜索哪个字段
bindData:'=' // 统一返回数组
},
restrict: 'A',
template: '<div class="bm-select2-box" ng-click="$event.stopPropagation();">' +
'<input type="text" class="bm-select2-input" ng-model="name">' +
'<ul class="bm-select2-list list-unstyled">' +
'<li ng-if="isShowCheckbox">' +
'<label style="margin: 0;">'+
'<input type="checkbox" ng-checked="checkedAll" ng-click="act.doCheckAll(filtoutData);"/>' +
'<span>全选</span>' +
'</label>' +
'</li>' +
'<li ng-repeat="item in filtoutData">' +
'<label style="margin: 0;" ng-if="!isShowCheckbox" ng-click="act.doClick(item);" ng-bind="item[bindSearch]"></label>' +
'<label style="margin: 0;" ng-if="isShowCheckbox">'+
'<input type="checkbox" ng-checked="item.checked" ng-click="act.doClick(item);"/>' +
'<span ng-bind="item[bindSearch]"></span>' +
'</label>' +
'</li>' +
'</ul> ' +
'</div>',
replace: true,
link: function($scope, iElm, iAttrs, ctrl) {
var doc = $(document),
input = iElm.children('input'),
ul = iElm.children('ul');
// 控件行为
input.click(function(e) {
var hideUl = function() {
ul.hide();
doc.off('click', hideUl);
};
var isUlShow = ul.css('display') != 'none';
if(isUlShow) {
ul.hide();
doc.off('click', hideUl);
}else {
ul.show();
doc.on('click', hideUl);
}
});
// 筛选用函数
var filterFn = function(key, data) {
var searchin = $scope.bindSearch;
var result = [];
if(key && data && data.length) {
angular.forEach(data, function(v, k, obj) {
if(v[searchin].indexOf(key) >= 0) {
result.push(v);
}
});
}
return result;
};
// 模板中用到的模型
$scope.bindListCopy = []; // 拷贝出来的数据源
$scope.filtoutData = []; // 过滤出来的数据(展示用)
$scope.name = ''; // input输入框的模型
$scope.isShowCheckbox = parseInt(iAttrs.isShowCheckbox, 10) === 1 ? true : false ; // 是否显示复选框
$scope.checkedAll = false; // 是否全选
$scope.bindData = []; // 返回控制器的结果集
// arr就是结果集合$scope.bindData
var toggleSelectedItem = function(arr, it) {
var idx = arr.indexOf(it);
if(it.checked) {
if(idx < 0) {
arr.push(it);
}
} else {
if(idx >= 0) {
arr.splice(idx, 1);
}
}
return arr;
};
$scope.act = {
doClick:function(item) {
if($scope.isShowCheckbox) { // 多选的情况
item.checked = !item.checked;
$scope.bindData = toggleSelectedItem($scope.bindData, item);
} else { // 单选的情况
$scope.name = item[$scope.bindSearch];
$scope.bindData = [item];
// 写这里貌似不太好
ul.hide();
}
},
doCheckAll:function(allItems) {
if($scope.isShowCheckbox) { // 多选的情况
$scope.checkedAll = !$scope.checkedAll;
angular.forEach(allItems, function(v, k) {
v.checked = $scope.checkedAll;
toggleSelectedItem($scope.bindData, v);
});
}
}
};
// 如果绑定的数据源改变了,则重新初始化一些值
$scope.$watch('bindList', function(newVal, oldVal) {
var dataPreHandler = function(dt) {
if(dt && dt.length) {
angular.forEach(dt, function(v, k) {
v.checked = false;
});
}
return dt;
};
if(newVal) {
$scope.bindListCopy = dataPreHandler(angular.copy($scope.bindList));
$scope.filtoutData = [].concat($scope.bindListCopy);
$scope.name = '';
$scope.bindData = [];
if ($scope.isShowCheckbox) {
$scope.checkedAll = false;
}
}
});
// 函数节流,减少筛选的次数
var timeObj = null;
$scope.$watch('name', function(newVal, oldVal) {
if(timeObj){
$timeout.cancel(timeObj);
}
timeObj = $timeout(function(){
var search = $.trim(newVal)?$.trim(newVal):'';
if(search) {
$scope.filtoutData = filterFn(search ,$scope.bindListCopy);
}else {
$scope.filtoutData = [].concat($scope.bindListCopy);
}
$scope.checkedAll = false;
timeObj = null;
}, 500);
});
}
};
});
backman.directive('bmUploadImg', function (_setting, _httpPost) {
'use strict';
return {
scope: {
bindId: '=',
bindUrl: '='
},
restrict: 'A',
template: '<div class="bm-upload-img-bg img-thumbnail">' +
' <i class="fa fa-image"></i><i class="fa fa-plus"></i></div>' +
'<div class="bm-upload-img-input"><input type="file" /></div>' +
'<div class="bm-upload-img-uping" ng-if="state.upAjaxing" title="上传中,请稍后...">' +
' <i class="fa fa-spinner"></i></div>' +
'<div class="bm-upload-img-view img-thumbnail" ng-if="bindUrl" tabindex="-1">' +
' <span><img ng-src="{{bindUrl}}" data-img-id="{{bindId}}"/></span>' +
' <i class="fa fa-times" ng-click="act.delImg()"></i>' +
'</div>',
link: function ($scope, iElm, iAttrs) {
var eid = iAttrs.id || 'uploadImg' + (Date.now() % 1e7) + parseInt(Math.random() * 1e3);
iElm.addClass('bm-upload-img').attr('id', eid);
$scope.state = {
upAjaxing: false //显示上传中状态
};
//交互
$scope.act = {
delImg: function () {
layer.confirm('<img class="bm-upload-img-del" src="' + $scope.bindUrl + '"/>',
{title: '确认删除此图片?'}, function (index) {
layer.close(index);
$scope.bindId = $scope.bindUrl = '';
if (!$scope.$$phase && !$scope.$root.$$phase) {
$scope.$apply();
}
}
);
}
};
//上传图片
var upload = function (img) {
var opt = _setting.get('globUploadImg');
var sendDate = opt.parameters;
sendDate[opt.fileKeyName] = img.src;
_httpPost(opt.url, sendDate)
.then(function (data) {
$scope.state.upAjaxing = false;
if (data) {
$scope.bindUrl = data.url;
$scope.bindId = data.imgId;
}
});
};
//操作
iElm
.find('input').on('change', function () {
var files = this.files;
if (!files[0]) {
$scope.state.upAjaxing = false;
return;
}
//状态检测
if (!_setting.get('globUploadImg').url) {
layer.alert('未检测到上传接口地址!<br>请配置 “全局上传接口” ');
return;
}
if (iAttrs.imgSize) {
if (!/^\d{1,4}[,-_\|xX×]\d{1,4}$/.test(iAttrs.imgSize)) {
layer.alert('图片尺寸限制配置不合法!<br>格式例如:300-200');
return
}
}
//显示加载中图标
$scope.state.upAjaxing = true;
if (!$scope.$$phase && !$scope.$root.$$phase) {
$scope.$apply();
}
//读取文件
var reader = new FileReader();
reader.onload = function (e) {
var img = new Image();
img.onload = function () {
img.onload = null;
if (iAttrs.imgSize) {
var matchs = iAttrs.imgSize.match(/^(\d{1,4})[,-_\|xX×](\d{1,4})$/);
if (img.width != matchs[1] || img.height != matchs[2]) {
var msg = '您选择的图片尺寸为 ' + img.width + ' × ' + img.height +
',与此处上传要求的尺寸 <b class="text-danger">' +
matchs[1] + ' × ' + matchs[2] + '</b> 不匹配!' +
'是否仍然要坚持继续上传?';
layer.confirm(msg, {icon: 0, title: '尺寸不匹配!'}, function (index) {
layer.close(index);
upload(img);
}, function(){
$scope.state.upAjaxing = false;
if (!$scope.$$phase && !$scope.$root.$$phase) {
$scope.$apply();
}
});
} else {
upload(img);
}
} else {
upload(img);
}
};
img.src = e.target.result;
};
reader.readAsDataURL(files[0]);
})
.end()
//点击图片放大显示
.on('click', 'img', function () {
var $this = $(this);
var $win = $(window);
var widthW = parseInt($win.width() * 0.8);
widthW = (widthW % 2 == 0) ? widthW : widthW + 1;
var heightW = parseInt($win.height() * 0.8);
heightW = (heightW % 2 == 0) ? heightW : heightW + 1;
var width = this.naturalWidth;
var height = this.naturalHeight;
var size = [width, height];
//图片宽高比比窗口宽,按宽度计算
if (width / height >= widthW / heightW) {
if (width > widthW) {
size[0] = parseInt(widthW);
size[1] = parseInt(height / width * widthW);
}
}
//图片宽高比比窗口高,按高度计算
else {
if (height > heightW) {
size[0] = parseInt(width / height * heightW);
size[1] = parseInt(heightW);
}
}
//打开弹窗
layer.open({
type: 1,
shade: 0.3,
shadeClose: true,
title: false,
closeBtn: 2,
move: '.layui-layer-content',
skin: 'bm-upload-img-super',
content: '<span>' + $this[0].src + '</span><img src="' + $this.attr('src') + '"/>',
area: [size[0] + 'px', size[1] + 'px'],
end: function() {
$this.parent().parent().focus();
}
});
});
}
}
});
backman.directive('form', function () {
'use strict';
return {
scope: false,
restrict: 'E',
priority: 10,
link: function ($scope, iElm, iAttrs) {
var fName = '';
if (iElm.attr('id')) {
fName = iElm.attr('id');
} else {
fName = 'form' + (Date.now() % 1e7) + parseInt(Math.random() * 1e3);
iElm.attr('id', fName);
}
if (!$scope.$forms) {
$scope.$forms = {};
}
$scope.$forms[fName] = {};
}
}
});
backman.directive('bmVerify', function () {
'use strict';
return {
scope: {
bindVerify: '='
},
restrict: 'A',
link: function ($scope, iElm, iAttrs) {
if (!iAttrs.bindVerify) {
return;
}
if (!iAttrs.verifyItem || iAttrs.verifyItem == '{}') {
return;
}
var validations = null;
if (iAttrs.verifyItem == 'require') {
validations = {
require: true
};
} else {
validations = JSON.parse(iAttrs.verifyItem.replace(/'/g, '"'));
}
var messages = JSON.parse(iAttrs.verifyMsg ? iAttrs.verifyMsg.replace(/'/g, '"') : '{}');
//当前指令脏值
var _dirtyState = false;
//所属表单
var $curForm = iElm.closest('form');
var fName = ($curForm.length > 0) ? $curForm.attr('id') : '';
//变化
$scope.$watch('bindVerify', function (newVal, oldVal) {
//脏检查
if (!_dirtyState && newVal) {
_dirtyState = true;
}
});
}
}
});
backman.directive('bmVerifyControl', function ($timeout) {
'use strict';
return {
scope: false,
restrict: 'A',
link: function ($scope, iElm, iAttrs) {
//等待其他指令完成
$timeout(function () {
var fName = '';
if (iAttrs.bmVerifyControl != '') {
fName = iAttrs.bmVerifyControl;
} else {
fName = iElm.closest('form').attr('id');
}
$scope.$watch('$forms.' + fName, function (newVal, oldVal) {
console.log(newVal);
});
}, 10);
}
}
});