Browse Source

git-svn-id: svn+ssh://10.10.101.21/source/platform/platform-b2b@892 f3bf4e98-0cf0-11e4-a00c-a99a8b9d557d

administrator 11 years ago
parent
commit
f69bdf840b

+ 16 - 1
src/main/java/com/uas/platform/b2b/controller/RoleController.java

@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
@@ -50,10 +51,24 @@ public class RoleController {
 	 * @return
 	 */
 	@RequestMapping(method = RequestMethod.POST)
-	public ResponseEntity<String> replyInquiryItem(@RequestBody String json) {
+	public ResponseEntity<String> save(@RequestBody String json) {
 		Role role = FlexJsonUtils.fromJson(json, Role.class);
 		role = roleService.save(role);
 		logger.log("角色", "添加角色", role.getDuty(), role.getDesc(), role.getId());
 		return new ResponseEntity<String>(HttpStatus.OK);
 	}
+
+	/**
+	 * 删除角色
+	 * 
+	 * @param roleId ID
+	 * @return
+	 */
+	@RequestMapping(value = "/{roleId}", method = RequestMethod.DELETE)
+	public ResponseEntity<String> delete(@PathVariable("roleId") Long roleId) {
+		Role role = roleService.findById(roleId);
+		roleService.delete(role);
+		logger.log("角色", "删除角色", role.getDuty(), role.getDesc(), role.getId());
+		return new ResponseEntity<String>(HttpStatus.OK);
+	}
 }

+ 19 - 0
src/main/java/com/uas/platform/b2b/dao/RoleDao.java

@@ -15,6 +15,15 @@ public interface RoleDao extends JpaRepository<Role, Long> {
 	@Query("from Role r where r.enUU = :enUU order by id")
 	public List<Role> findByEnUU(@Param("enUU") long enUU);
 
+	/**
+	 * 按角色描述查找角色
+	 * 
+	 * @param enUU
+	 * @param desc
+	 * @return
+	 */
+	public List<Role> findByEnUUAndDesc(long enUU, String desc);
+
 	/**
 	 * 角色个数
 	 * 
@@ -24,4 +33,14 @@ public interface RoleDao extends JpaRepository<Role, Long> {
 	@Query("select count(r) from Role r where r.enUU = :enUU")
 	public int getCountByEnUU(@Param("enUU") long enUU);
 
+	/**
+	 * 按角色描述查找角色个数
+	 * 
+	 * @param enUU
+	 * @param desc
+	 * @return
+	 */
+	@Query("select count(r) from Role r where r.enUU = :enUU and r.desc = :desc")
+	public int getCountByEnUUAndDesc(@Param("enUU") long enUU, @Param("desc") String desc);
+
 }

+ 9 - 0
src/main/java/com/uas/platform/b2b/dao/UserDao.java

@@ -44,4 +44,13 @@ public interface UserDao extends JpaSpecificationExecutor<User>, JpaRepository<U
 	@Query("select u from User u inner join u.enterprises as e where e.uu = :enUU")
 	public List<User> findByEnUU(@Param("enUU") long enUU);
 
+	/**
+	 * 按角色ID查找该角色下的用户
+	 * 
+	 * @param roleId
+	 * @return
+	 */
+	@Query("select u from User u inner join u.roles as r where r.id = :roleId")
+	public List<User> findByRole(@Param("roleId") long roleId);
+
 }

+ 25 - 0
src/main/java/com/uas/platform/b2b/model/Role.java

@@ -159,4 +159,29 @@ public class Role implements Serializable {
 		this.duty = duty;
 	}
 
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Role other = (Role) obj;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		return true;
+	}
+
 }

+ 22 - 0
src/main/java/com/uas/platform/b2b/service/RoleService.java

@@ -21,4 +21,26 @@ public interface RoleService {
 	 */
 	public Role save(Role role);
 
+	/**
+	 * 查找角色
+	 * 
+	 * @param id
+	 * @return
+	 */
+	public Role findById(long id);
+
+	/**
+	 * 删除角色
+	 * 
+	 * @param role
+	 */
+	public void delete(Role role);
+	
+	/**
+	 * 删除角色
+	 * 
+	 * @param id
+	 */
+	public void delete(long id);
+
 }

+ 41 - 4
src/main/java/com/uas/platform/b2b/service/impl/RoleServiceImpl.java

@@ -9,9 +9,12 @@ import org.springframework.util.CollectionUtils;
 
 import com.uas.platform.b2b.dao.EnterpriseDao;
 import com.uas.platform.b2b.dao.RoleDao;
+import com.uas.platform.b2b.dao.UserDao;
 import com.uas.platform.b2b.model.Role;
+import com.uas.platform.b2b.model.User;
 import com.uas.platform.b2b.service.RoleService;
 import com.uas.platform.b2b.support.SystemSession;
+import com.uas.platform.core.exception.IllegalOperatorException;
 import com.uas.platform.core.model.Constant;
 
 @Service
@@ -23,6 +26,9 @@ public class RoleServiceImpl implements RoleService {
 	@Autowired
 	private EnterpriseDao enterpriseDao;
 
+	@Autowired
+	private UserDao userDao;
+
 	@Override
 	public List<Role> findAll() {
 		long enUU = SystemSession.getUser().getEnterprise().getUu();
@@ -38,12 +44,43 @@ public class RoleServiceImpl implements RoleService {
 	@Override
 	public Role save(Role role) {
 		Assert.notNull(role.getDesc());
-		if (role.getName() == null)
+		long enUU = SystemSession.getUser().getEnterprise().getUu();
+		// 角色描述不能重复
+		List<Role> roles = roleDao.findByEnUUAndDesc(enUU, role.getDesc());
+		if (roles.size() > 0 && !roles.get(0).equals(role))
+			throw new IllegalOperatorException("角色描述不能重复");
+		if (role.getName() == null) {
+			// 自定义角色
 			role.setName("ROLE_" + System.currentTimeMillis());
-		role.setEnUU(SystemSession.getUser().getEnterprise().getUu());
-		role.setIsdefault(Constant.NO);
-		role.setIssys(Constant.NO);
+			role.setEnUU(enUU);
+			role.setIsdefault(Constant.NO);
+			role.setIssys(Constant.NO);
+		}
 		return roleDao.save(role);
 	}
 
+	@Override
+	public Role findById(long id) {
+		return roleDao.findOne(id);
+	}
+
+	@Override
+	public void delete(Role role) {
+		if (role != null && role.getId() != null) {
+			List<User> users = userDao.findByRole(role.getId());
+			if (!CollectionUtils.isEmpty(users)) {
+				for (User user : users) {
+					user.getRoles().remove(role);
+				}
+				userDao.save(users);
+			}
+			roleDao.delete(role);
+		}
+	}
+
+	@Override
+	public void delete(long id) {
+		delete(findById(id));
+	}
+
 }

+ 5 - 0
src/main/webapp/resources/css/index.css

@@ -18,6 +18,10 @@ a {
 	text-decoration: none;
 }
 
+a.none:hover {
+	text-decoration: none;
+}
+
 .block {
 	background-color: #fff;
 	width: 100%;
@@ -1177,6 +1181,7 @@ a {
 /*account*/
 .resource-container,.role-container {
 	padding: 15px;
+	min-height: 677px;
 }
 
 .simple-list {

+ 41 - 2
src/main/webapp/resources/js/common/services.js

@@ -1,6 +1,6 @@
-define([ 'angular', 'toaster' ], function(angular) {
+define([ 'angular', 'toaster', 'ui.bootstrap' ], function(angular) {
 	'use strict';
-	angular.module('common.services', ['toaster' ]).factory('SessionService', function() {
+	angular.module('common.services', ['toaster', 'ui.bootstrap', 'common.tpls' ]).factory('SessionService', function() {
 		return {
 			get : function(key) {
 				var storage = window.sessionStorage;
@@ -216,5 +216,44 @@ define([ 'angular', 'toaster' ], function(angular) {
 			customer: $resource('vendor/customer/:id', {}),
 			vendor: $resource('vendor/:id', {})
 		};
+	}).factory('ngAlert', function($modal){
+		var ngAlert = function(config, trueFn, falseFn){
+			var modalInstance = $modal.open({
+				animation: true,
+				templateUrl: 'common/template/alert.html',
+				controller: 'AlertInstanceCtrl',
+				resolve: {
+					alertConfig: function() {
+						return config;
+					}
+				}
+			});
+			modalInstance.result.then(function(bool){
+				var fn = bool ? trueFn : falseFn;
+				fn && (fn.call());
+			});
+			return this;
+		};
+		return ngAlert;
+	}).controller('AlertInstanceCtrl', function($scope, $modalInstance, alertConfig){
+		$scope.alertConfig = alertConfig;
+		$scope.ok = function () {
+		    $modalInstance.close(true);
+		};
+		$scope.cancel = function () {
+			$modalInstance.close(false);
+		};
 	});
+	angular.module("common.tpls", ["common/template/alert.html"]);
+	angular.module("common/template/alert.html", []).run(["$templateCache", function($templateCache) {
+		  $templateCache.put("common/template/alert.html",
+			"<div class=\"modal-header\">" +
+				  		"<h3 class=\"modal-title\" ng-bind=\"alertConfig.title\"></h3>" + 
+			"</div>" +
+			"<div class=\"modal-body\" ng-bind=\"alertConfig.content\"></div>" +
+			"<div class=\"modal-footer\">" +
+				  	"<button class=\"btn btn-primary\" ng-click=\"ok()\">确定</button>" +
+				  	"<button class=\"btn btn-warning\" ng-click=\"cancel()\">取消</button>" +
+		  	"</div>");
+	}]);
 });

+ 52 - 5
src/main/webapp/resources/js/index/app.js

@@ -2263,11 +2263,16 @@ define([ 'toaster', 'charts', 'ngTable', 'common/services', 'service/Purc', 'ser
 			});
 		};
 		getData();
-		$scope.addRole = function(){
+		$scope.editRole = function(role){
 			var modalInstance = $modal.open({
 				animation: true,
-				templateUrl: 'static/tpl/index/account/role_add.html',
-				controller: 'RoleAddCtrl'
+				templateUrl: 'static/tpl/index/account/role_detail.html',
+				controller: 'RoleEditCtrl',
+				resolve: {
+					role: function() {
+						return role;
+					}
+				}
 			});
 			modalInstance.result.then(function(added){
 				added && (getData());
@@ -2275,16 +2280,44 @@ define([ 'toaster', 'charts', 'ngTable', 'common/services', 'service/Purc', 'ser
 		};
 	});
 	
-	app.controller('RoleAddCtrl', function($scope, $modalInstance, AccountResource, AccountRole, toaster){
+	app.controller('RoleEditCtrl', function($scope, $modalInstance, $timeout, AccountResource, AccountRole, toaster, role, ngAlert){
+		$scope.role = role;
+		$scope.master = angular.copy($scope.role);
+		var isNew = role == null;
 		$scope.cancel = function() {
 			$modalInstance.close(false);
 		};
 		AccountResource.getAll({}, function(data){
 			if(data && data.length > 0) {
+				if(role && role.resourceItems) {
+					var rs = [];// 已分配的资源的id
+					angular.forEach(role.resourceItems, function(item){
+						rs.push(item.id);
+					});
+					angular.forEach(data, function(resource){
+						var c = 0;
+						angular.forEach(resource.items, function(item){
+							if(rs.indexOf(item.id) > -1) {
+								item.$checked = true;
+								c += 1;
+							}
+						});
+						resource.$checked = c == resource.items.length;
+					});
+				}
 				$scope.resourceItems = data[0].items;
 				data[0].$active = true;
 			}
 			$scope.resources = data;
+			$timeout(function(){
+				angular.forEach($scope.resources, function(resource){
+					var c = 0;
+					angular.forEach(resource.items, function(item){
+						item.$checked && (c+=1);
+					});
+					angular.element(document.getElementById('check_' + resource.id)).prop('indeterminate', (c > 0 && !resource.$checked));
+				});
+			}, 100);
 		});
 		$scope.onItemClick = function(resource) {
 			$scope.resourceItems = resource.items;
@@ -2316,6 +2349,7 @@ define([ 'toaster', 'charts', 'ngTable', 'common/services', 'service/Purc', 'ser
 						item.$checked && (c+=1);
 					});
 					resource.$checked = (c == resource.items.length);
+					angular.element(document.getElementById('check_' + resource.id)).prop('indeterminate', (c > 0 && !resource.$checked));
 				}
 			});
 			getChecked();
@@ -2328,12 +2362,25 @@ define([ 'toaster', 'charts', 'ngTable', 'common/services', 'service/Purc', 'ser
 		$scope.save = function() {
 			$scope.master = angular.copy($scope.role);
 			AccountRole.save($scope.master, function(){
-				toaster.pop('success', '提示', '角色:' + $scope.role.desc + ' 添加成功');
+				toaster.pop('success', '提示', '角色:' + $scope.role.desc + ' 资料' + (isNew ? '添加': '修改') + '成功');
 				$modalInstance.close(true);
 			}, function(response){
 				toaster.pop('error', '错误', response.data);
 			});
 		};
+		$scope.del = function() {
+			new ngAlert({
+				title: '提示',
+				content: '确定删除角色(' + $scope.role.desc + ')吗?'
+			}, function(){
+				AccountRole.remove({id: role.id}, function(){
+					toaster.pop('success', '提示', '角色:' + $scope.role.desc + ' 删除成功');
+					$modalInstance.close(true);
+				}, function(response){
+					toaster.pop('error', '错误', response.data);
+				});
+			})
+		};
 	});
 	
 	/**

+ 1 - 1
src/main/webapp/resources/js/index/services/Account.js

@@ -51,7 +51,7 @@ define([ 'ngResource' ], function() {
 			}
 		});
 	}).factory('AccountRole', function($resource) {
-		return $resource('account/role', {}, {
+		return $resource('account/role/:id', {}, {
 			getAll: {
 				isArray: true
 			}

+ 9 - 9
src/main/webapp/resources/tpl/index/account/role.html

@@ -2,12 +2,12 @@
 	<h1 class="page-header">默认角色</h1>
 	<div class="role-list">
 		<div class="item" ng-repeat="role in roles.defaults track by role.id">
-			<div class="icon">
+			<a class="icon" ng-click="editRole(role)">
 				<i class="fa fa-user"
 					ng-class="{'fa-user-md': role.name=='ROLE_ADMIN','fa-male': role.name=='ROLE_SALE','fa-street-view': role.name=='ROLE_USER'}"></i>
-			</div>
+			</a>
 			<div class="desc">
-				<h3 ng-bind="role.desc"></h3>
+				<h3><a ng-click="editRole(role)" ng-bind="role.desc" class="none"></a></h3>
 				<div class="text-muted" ng-bind="role.duty"></div>
 			</div>
 		</div>
@@ -15,22 +15,22 @@
 	<h1 class="page-header">自定义角色</h1>
 	<div class="role-list">
 		<div class="item" ng-repeat="role in roles.custom track by role.id">
-			<div class="icon">
+			<a class="icon" ng-click="editRole(role)">
 				<i class="fa fa-user"></i>
-			</div>
+			</a>
 			<div class="desc">
-				<h3 ng-bind="role.desc"></h3>
+				<h3><a ng-click="editRole(role)" ng-bind="role.desc" class="none"></a></h3>
 				<div class="text-muted" ng-bind="role.duty"></div>
 			</div>
 		</div>
 		<div class="item">
-			<a class="icon" ng-click="addRole()"> <i
+			<a class="icon" ng-click="editRole()"> <i
 				class="fa fa-plus text-warning"></i>
 			</a>
 			<div class="desc">
-				<h3>自定义角色</h3>
+				<h3><a ng-click="editRole()" class="none">自定义角色</a></h3>
 				<div class="text-muted">
-					某个角色的职责和默认角色差异较大时,可以<a ng-click="addRole()">自定义角色</a>
+					某个角色的职责和默认角色差异较大时,可以<a ng-click="editRole()">自定义角色</a>
 				</div>
 			</div>
 		</div>

+ 18 - 8
src/main/webapp/resources/tpl/index/account/role_add.html → src/main/webapp/resources/tpl/index/account/role_detail.html

@@ -1,6 +1,7 @@
 <div class="modal-header">
 	<h3 class="modal-title">
-		<i class="fa fa-user fa-fw text-default"></i>添加自定义角色
+		<i class="fa fa-user fa-fw text-default"></i><span
+			ng-bind="role.id?'编辑角色':'添加自定义角色'"></span>
 	</h3>
 </div>
 <form name="roleForm" novalidate ng-submit="save()">
@@ -8,7 +9,7 @@
 		<div class="form-group">
 			<label>角色名称</label> <input type="text" name="desc"
 				ng-model="role.desc" class="form-control" placeholder="输入3-8个中文字描述"
-				required autofocus>
+				required autofocus ng-readonly="role.isdefault">
 			<div class="tooltip in left control-tooltip"
 				ng-show="roleForm.desc.$dirty && roleForm.desc.$invalid">
 				<div class="tooltip-arrow"></div>
@@ -18,14 +19,15 @@
 		<div class="form-group">
 			<label>职责范围</label>
 			<textarea class="form-control" name="duty" ng-model="role.duty"
-				placeholder="角色的具体职责(50个中文字以内)" required></textarea>
+				placeholder="角色的具体职责(50个中文字以内)" required
+				ng-readonly="role.isdefault"></textarea>
 			<div class="tooltip in left control-tooltip"
 				ng-show="roleForm.duty.$dirty && roleForm.duty.$invalid">
 				<div class="tooltip-arrow"></div>
 				<span class="tooltip-inner">请描述一下角色的具体职责,内容保持在50个中文字以内</span>
 			</div>
 		</div>
-		<div class="form-group role-resources">
+		<div class="form-group role-resources" ng-if="role.issys != 1">
 			<label>权限分配</label>
 			<p class="help-block">
 				给角色分配允许操作的资源<span class="pull-right"><input type="checkbox"
@@ -37,9 +39,9 @@
 						<ul class="list-unstyled">
 							<li ng-repeat="resource in resources"
 								ng-class="{active: resource.$active}"
-								ng-click="onItemClick(resource)"><input type="checkbox"
+								ng-click="onItemClick(resource)"><input id="check_{{resource.id}}" type="checkbox"
 								ng-model="resource.$checked"
-								ng-change="onResourceChange(resource)" /><a>{{::resource.name}}<span
+								ng-change="onResourceChange(resource)"/><a>{{::resource.name}}<span
 									class="caret"></span></a></li>
 						</ul>
 					</div>
@@ -53,9 +55,17 @@
 			</div>
 		</div>
 	</div>
-	<div class="modal-footer">
+	<div class="modal-footer" ng-if="role.issys != 1">
+		<p class="pull-left text-muted" ng-show="role.isdefault == 1">
+			<i class="fa fa-fw fa-warning"></i>默认角色不允许删除,只能修改权限分配
+		</p>
 		<button class="btn btn-primary" type="submit"
-			ng-disabled="roleForm.$invalid || !isChanged(role)">确认添加</button>
+			ng-disabled="roleForm.$invalid || !isChanged(role)">确认并保存</button>
+		<button class="btn btn-default" type="button"
+			ng-show="role.id && role.isdefault == 0" ng-click="del()">删除角色</button>
 		<button class="btn btn-default" ng-click="cancel()" type="button">取消</button>
 	</div>
+	<div class="modal-footer" ng-if="role.issys == 1">
+		<button class="btn btn-default" ng-click="cancel()" type="button">关闭</button>
+	</div>
 </form>