Browse Source

teamWork接口服务开发

luojing 5 years ago
parent
commit
6c3ebc0699
71 changed files with 4854 additions and 128 deletions
  1. 1 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_teamwork_assemble_control.java
  2. 75 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/Business.java
  3. 1 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/ThisApplication.java
  4. 0 4
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/factory/ProjectFactory.java
  5. 266 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/factory/ProjectTemplateFactory.java
  6. 21 2
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/factory/ReviewFactory.java
  7. 268 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/factory/TaskListTemplateFactory.java
  8. 4 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/ActionApplication.java
  9. 2 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/JaxrsManagerUserFilter.java
  10. 2 2
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/list/ActionGet.java
  11. 12 5
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/list/ActionListWithTaskGroup.java
  12. 22 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionGet.java
  13. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListArchiveNextWithFilter.java
  14. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListCompletedNextWithFilter.java
  15. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListMyNextWithFilter.java
  16. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListNextInGroupWithFilter.java
  17. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListNextWithFilter.java
  18. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListNoGroupNextWithFilter.java
  19. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListPageInGroupWithFilter.java
  20. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListPageWithFilter.java
  21. 25 6
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListRecycleNextWithFilter.java
  22. 21 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListStarNextWithFilter.java
  23. 21 19
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionStatisticMyProjects.java
  24. 35 14
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/WrapOutControl.java
  25. 122 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionDelete.java
  26. 86 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionGet.java
  27. 81 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionList.java
  28. 114 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionListWithFilter.java
  29. 31 33
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionSave.java
  30. 25 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/BaseAction.java
  31. 128 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplateAction.java
  32. 12 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplateFlagForQueryEmptyException.java
  33. 12 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplateNotExistsException.java
  34. 20 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplatePersistException.java
  35. 16 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplateQueryException.java
  36. 54 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionGet.java
  37. 67 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionListMyTaskWithTaskList.java
  38. 68 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionListNextWithFilter.java
  39. 69 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionListPageWithFilter.java
  40. 79 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionListWithTaskList.java
  41. 50 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewAllListNextWithFilter.java
  42. 50 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewCompletedListNextWithFilter.java
  43. 50 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewMyExecutListNextWithFilter.java
  44. 49 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewOverTimeListNextWithFilter.java
  45. 50 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewUncompletedListNextWithFilter.java
  46. 63 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/WrapOutControl.java
  47. 108 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionDelete.java
  48. 87 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionGet.java
  49. 81 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionList.java
  50. 114 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionListWithFilter.java
  51. 206 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionSave.java
  52. 25 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/BaseAction.java
  53. 92 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplateAction.java
  54. 12 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplateFlagForQueryEmptyException.java
  55. 12 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplateNotExistsException.java
  56. 20 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplatePersistException.java
  57. 16 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplateQueryException.java
  58. 32 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/DynamicPersistService.java
  59. 65 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/DynamicService.java
  60. 26 1
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/ProjectQueryService.java
  61. 146 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/ProjectTemplatePersistService.java
  62. 347 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/ProjectTemplateQueryService.java
  63. 290 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/ProjectTemplateService.java
  64. 129 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/TaskListTemplatePersistService.java
  65. 322 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/TaskListTemplateQueryService.java
  66. 290 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/TaskListTemplateService.java
  67. 4 0
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/TaskQueryService.java
  68. 5 3
      o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/timertask/Timertask_CheckAllTaskOverTime.java
  69. 4 0
      o2server/x_teamwork_core_entity/src/main/java/com/x/teamwork/core/entity/PersistenceProperties.java
  70. 14 0
      o2server/x_teamwork_core_entity/src/main/java/com/x/teamwork/core/entity/ProjectTemplate.java
  71. 167 0
      o2server/x_teamwork_core_entity/src/main/java/com/x/teamwork/core/entity/TaskListTemplate.java

+ 1 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_teamwork_assemble_control.java

@@ -8,6 +8,7 @@ import com.x.base.core.project.annotation.ModuleType;
 containerEntities = {
 		"com.x.teamwork.core.entity.Project", "com.x.teamwork.core.entity.ProjectDetail",
 		"com.x.teamwork.core.entity.ProjectExtFieldRele", "com.x.teamwork.core.entity.ProjectGroup",
+		"com.x.teamwork.core.entity.ProjectTemplate","com.x.teamwork.core.entity.TaskListTemplate",
 		"com.x.teamwork.core.entity.ProjectGroupRele", "com.x.teamwork.core.entity.Task",
 		"com.x.teamwork.core.entity.TaskGroup", "com.x.teamwork.core.entity.TaskGroupRele",
 		"com.x.teamwork.core.entity.TaskDetail", "com.x.teamwork.core.entity.TaskExtField", "com.x.teamwork.core.entity.TaskList",

+ 75 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/Business.java

@@ -1,6 +1,11 @@
 package com.x.teamwork.assemble.control;
 
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
 import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.project.http.EffectivePerson;
 import com.x.organization.core.express.Organization;
 import com.x.teamwork.assemble.control.factory.AttachmentFactory;
 import com.x.teamwork.assemble.control.factory.BatchOperationFactory;
@@ -10,12 +15,14 @@ import com.x.teamwork.assemble.control.factory.ProjectExtFieldReleFactory;
 import com.x.teamwork.assemble.control.factory.ProjectFactory;
 import com.x.teamwork.assemble.control.factory.ProjectGroupFactory;
 import com.x.teamwork.assemble.control.factory.ProjectGroupReleFactory;
+import com.x.teamwork.assemble.control.factory.ProjectTemplateFactory;
 import com.x.teamwork.assemble.control.factory.ReviewFactory;
 import com.x.teamwork.assemble.control.factory.SystemConfigFactory;
 import com.x.teamwork.assemble.control.factory.TaskFactory;
 import com.x.teamwork.assemble.control.factory.TaskGroupFactory;
 import com.x.teamwork.assemble.control.factory.TaskGroupReleFactory;
 import com.x.teamwork.assemble.control.factory.TaskListFactory;
+import com.x.teamwork.assemble.control.factory.TaskListTemplateFactory;
 import com.x.teamwork.assemble.control.factory.TaskTagFactory;
 import com.x.teamwork.assemble.control.factory.TaskViewFactory;
 
@@ -33,6 +40,8 @@ public class Business {
 	private Organization organization;
 	private ProjectFactory projectFactory;
 	private TaskFactory taskFactory;
+	private ProjectTemplateFactory projectTemplateFactory;
+	private TaskListTemplateFactory taskListTemplateFactory;
 	private DynamicFactory dynamicFactory;
 	private SystemConfigFactory systemConfigFactory;
 	private ProjectGroupFactory projectGroupFactory;
@@ -187,6 +196,30 @@ public class Business {
 		return projectGroupFactory;
 	}
 	
+	/**
+	 * 获取项目模板数据库访问类
+	 * @return
+	 * @throws Exception
+	 */
+	public ProjectTemplateFactory projectTemplateFactory() throws Exception {
+		if (null == this.projectTemplateFactory) {
+			this.projectTemplateFactory = new ProjectTemplateFactory( this );
+		}
+		return projectTemplateFactory;
+	}
+	
+	/**
+	 * 获取项目模板对应的泳道数据库访问类
+	 * @return
+	 * @throws Exception
+	 */
+	public TaskListTemplateFactory taskListTemplateFactory() throws Exception {
+		if (null == this.taskListTemplateFactory) {
+			this.taskListTemplateFactory = new TaskListTemplateFactory( this );
+		}
+		return taskListTemplateFactory;
+	}
+	
 	/**
 	 * 获取项目与项目组关联信息数据库访问类
 	 * @return
@@ -246,4 +279,46 @@ public class Business {
 		}
 		return dynamicFactory;
 	}
+	
+	/**
+	 * TODO 判断用户是否管理员权限 1、person.isManager() 2、xadmin 3、CRMManager
+	 * 
+	 * @param request
+	 * @param personName
+	 * @return
+	 * @throws Exception
+	 */
+
+	public boolean isManager(EffectivePerson person) throws Exception {
+		// 如果用户的身份是平台的超级管理员,那么就是超级管理员权限
+		if (person.isManager()) {
+			return true;
+		}
+		if ("xadmin".equalsIgnoreCase(person.getDistinguishedName())) {
+			return true;
+		}
+		if (isHasPlatformRole(person.getDistinguishedName(), "TeamWorkManager@TeamWorkManager@R")) {
+			return true;
+		}
+		return false;
+	}
+	
+	public boolean isHasPlatformRole(String personName, String roleName) throws Exception {
+		if (StringUtils.isEmpty(personName)) {
+			throw new Exception("personName is null!");
+		}
+		if (StringUtils.isEmpty(roleName)) {
+			throw new Exception("roleName is null!");
+		}
+		List<String> roleList = null;
+		roleList = organization().role().listWithPerson(personName);
+		if (roleList != null && !roleList.isEmpty()) {
+			if (roleList.stream().filter(r -> roleName.equalsIgnoreCase(r)).count() > 0) {
+				return true;
+			}
+		} else {
+			return false;
+		}
+		return false;
+	}
 }

+ 1 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/ThisApplication.java

@@ -36,7 +36,7 @@ public class ThisApplication {
 			
 			//每30分钟核对一次所有的工作任务,判断工作任务是否已经超时
 			//context.schedule( Timertask_CheckAllTaskOverTime.class, "0 0/30 * * * ?" ); 
-			context.schedule( Timertask_CheckAllTaskOverTime.class, "* 0/10 * * * ?" );
+			context.schedule( Timertask_CheckAllTaskOverTime.class, "0 */9 * * * ?" );
 		} catch (Exception e) {
 			e.printStackTrace();
 		}

+ 0 - 4
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/factory/ProjectFactory.java

@@ -238,10 +238,6 @@ public class ProjectFactory extends AbstractFactory {
 		Root<Project> root = cq.from(Project.class);
 		Predicate p_permission = null;
 		
-		System.out.println("personName="+personName);
-		System.out.println("identityNames="+identityNames);
-		System.out.println("unitNames="+unitNames);
-		System.out.println("groupNames="+groupNames);
 		
 		if( StringUtils.isNotEmpty( personName )) {
 			//可以管理的栏目,肯定可以发布信息

+ 266 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/factory/ProjectTemplateFactory.java

@@ -0,0 +1,266 @@
+package com.x.teamwork.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Order;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.exception.ExceptionWhen;
+import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.AbstractFactory;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.core.entity.Dynamic_;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.ProjectDetail;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.Project_;
+import com.x.teamwork.core.entity.tools.CriteriaBuilderTools;
+import com.x.teamwork.core.entity.tools.filter.QueryFilter;
+
+
+public class ProjectTemplateFactory extends AbstractFactory {
+
+	public ProjectTemplateFactory( Business business ) throws Exception {
+		super(business);
+	}
+
+	/**
+	 * 获取指定Id的Project实体信息对象
+	 * @param id
+	 * @return
+	 * @throws Exception
+	 */
+	public ProjectTemplate get( String id ) throws Exception {
+		return this.entityManagerContainer().find( id, ProjectTemplate.class, ExceptionWhen.none );
+	}
+	
+	public ProjectDetail getDetail(String id) throws Exception {
+		return this.entityManagerContainer().find( id, ProjectDetail.class, ExceptionWhen.none );
+	}
+	
+	/**
+	 * 列示指定Id的Project实体信息列表
+	 * @param ids
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> list( List<String> ids ) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<Project>();
+		}
+		EntityManager em = this.entityManagerContainer().get(Project.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Project> cq = cb.createQuery(Project.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p = root.get(Project_.id).in(ids);
+		cq.orderBy( cb.desc( root.get( Project_.updateTime ) ) );
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	public List<String> listAllProjectIds() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(Project.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<Project> root = cq.from(Project.class);
+		cq.select( root.get( Project_.id) );
+		return em.createQuery(cq ).getResultList();
+	}	
+	
+	/**
+	 * 根据条件查询符合条件的项目信息数量
+	 * @param personName
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countWithFilter( String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p_permission = null;
+
+		if( StringUtils.isNotEmpty( personName )) {
+			//可以管理的栏目,肯定可以发布信息
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.participantPersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.manageablePersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.creatorPerson ), personName ) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.executor ), personName ) );
+		}
+		
+		if( ListTools.isNotEmpty( identityNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantIdentityList).in(identityNames));
+		}
+		if( ListTools.isNotEmpty( unitNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantUnitList).in(unitNames));
+		}
+		if( ListTools.isNotEmpty( groupNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantGroupList).in(groupNames));
+		}
+		
+		Predicate p = CriteriaBuilderTools.composePredicateWithQueryFilter( Project_.class, cb, p_permission, root, queryFilter );
+		cq.select(cb.count(root)).where(p);
+		Long count =  em.createQuery(cq).getSingleResult();
+		return count;
+	}
+	
+	/**
+	 *  根据条件查询符合条件的项目信息ID
+	 * @param maxCount
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> listWithFilter( Integer maxCount, String orderField, String orderType, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Project> cq = cb.createQuery(Project.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p_permission = null;
+		
+		if( StringUtils.isNotEmpty( personName )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.participantPersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.manageablePersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.creatorPerson ), personName ) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.executor ), personName ) );
+		}
+		
+		if( ListTools.isNotEmpty( identityNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantIdentityList).in(identityNames));
+		}
+		if( ListTools.isNotEmpty( unitNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantUnitList).in(unitNames));
+		}
+		if( ListTools.isNotEmpty( groupNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantGroupList).in(groupNames));
+		}
+		
+		Predicate p = CriteriaBuilderTools.composePredicateWithQueryFilter( Project_.class, cb, p_permission, root, queryFilter );
+
+		Order orderWithField = CriteriaBuilderTools.getOrder(cb, root, Project_.class, orderField, orderType);
+		if( orderWithField != null ){
+			cq.orderBy( orderWithField );
+		}
+		return em.createQuery(cq.where(p)).setMaxResults( maxCount).getResultList();
+	}
+	
+	/**
+	 * 根据条件查询符合条件的项目信息ID,根据上一条的sequnce查询指定数量的信息
+	 * @param maxCount
+	 * @param sequenceFieldValue
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> listWithFilter( Integer maxCount, Object sequenceFieldValue, String orderField, String orderType, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Project> cq = cb.createQuery(Project.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p_permission = null;
+		
+		if( StringUtils.isNotEmpty( personName )) {
+			//可以管理的栏目,肯定可以发布信息
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.participantPersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.manageablePersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.creatorPerson ), personName ) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.executor ), personName ) );
+		}
+		
+		if( ListTools.isNotEmpty( identityNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantIdentityList).in(identityNames));
+		}
+		if( ListTools.isNotEmpty( unitNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantUnitList).in(unitNames));
+		}
+		if( ListTools.isNotEmpty( groupNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantGroupList).in(groupNames));
+		}
+		
+		Predicate p = CriteriaBuilderTools.composePredicateWithQueryFilter( Project_.class, cb, p_permission, root, queryFilter );
+		
+		if( sequenceFieldValue != null && StringUtils.isNotEmpty( sequenceFieldValue.toString() )) {
+			Predicate p_seq = cb.isNotNull( root.get( Dynamic_.sequence ) );
+			if( "desc".equalsIgnoreCase( orderType )){
+				p_seq = cb.and( p_seq, cb.lessThan( root.get( Project_.sequence ), sequenceFieldValue.toString() ));
+			}else{
+				p_seq = cb.and( p_seq, cb.greaterThan( root.get( Project_.sequence ), sequenceFieldValue.toString() ));
+			}
+			p = cb.and( p, p_seq);
+		}		
+		
+		Order orderWithField = CriteriaBuilderTools.getOrder( cb, root, Project_.class, orderField, orderType );
+		if( orderWithField != null ){
+			cq.orderBy( orderWithField );
+		}
+		System.out.println(">>>SQL:" + em.createQuery(cq.where(p)).setMaxResults( maxCount).toString() );
+		return em.createQuery(cq.where(p)).setMaxResults( maxCount).getResultList();
+	}
+	
+	/**
+	 * 根据条件查询所有符合条件的项目信息ID,项目信息不会很多 ,所以直接查询出来
+	 * @param maxCount
+	 * @param sequenceFieldValue
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public List<String> listAllViewableProjectIds( Integer maxCount, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p_permission = null;
+		
+		
+		if( StringUtils.isNotEmpty( personName )) {
+			//可以管理的栏目,肯定可以发布信息
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.participantPersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.manageablePersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.creatorPerson ), personName ) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.executor ), personName ) );
+		}
+		if( ListTools.isNotEmpty( identityNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantIdentityList).in(identityNames));
+		}
+		if( ListTools.isNotEmpty( unitNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantUnitList).in(unitNames));
+		}
+		if( ListTools.isNotEmpty( groupNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantGroupList).in(groupNames));
+		}
+		
+		Predicate p = CriteriaBuilderTools.composePredicateWithQueryFilter( Project_.class, cb, p_permission, root, queryFilter );
+		cq.distinct(true).select( root.get(Project_.id) );
+		return em.createQuery(cq.where(p)).setMaxResults( maxCount).getResultList();
+	}
+
+	
+}

+ 21 - 2
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/factory/ReviewFactory.java

@@ -15,6 +15,8 @@ import org.apache.commons.lang3.StringUtils;
 import com.x.base.core.project.tools.ListTools;
 import com.x.teamwork.assemble.control.AbstractFactory;
 import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.Project_;
 import com.x.teamwork.core.entity.Review;
 import com.x.teamwork.core.entity.Review_;
 import com.x.teamwork.core.entity.tools.CriteriaBuilderTools;
@@ -51,7 +53,9 @@ public class ReviewFactory extends AbstractFactory {
 		Root<Review> root = cq.from( Review.class );
 		Predicate p = cb.equal( root.get( Review_.permissionObj ), person );
 		p = cb.and( p, cb.equal( root.get( Review_.project ), project ));
-		p = cb.and( p, cb.equal( root.get( Review_.deleted ), false ));
+		if(!this.getProject(project)){
+			p = cb.and( p, cb.equal( root.get( Review_.deleted ), false ));
+		}
 		cq.select(root.get( Review_.taskId)).where(p);
 		return em.createQuery( cq ).getResultList();
 	}
@@ -66,7 +70,9 @@ public class ReviewFactory extends AbstractFactory {
 		Root<Review> root = cq.from( Review.class );
 		Predicate p = cb.equal(root.get( Review_.project ), project );
 		p = cb.and( p, cb.equal(root.get( Review_.permissionObj ), person ));
-		p = cb.and( p, cb.equal( root.get( Review_.deleted ), false ));
+		if(!this.getProject(project)){
+			p = cb.and( p, cb.equal( root.get( Review_.deleted ), false ));
+		}
 		cq.select( root.get( Review_.taskId) ).where(p);
 		return em.createQuery( cq ).setMaxResults(maxCount).getResultList();
 	}
@@ -207,4 +213,17 @@ public class ReviewFactory extends AbstractFactory {
 		p = cb.and( p, cb.equal( root.get( Review_.deleted ), false ));
 		return em.createQuery( cq.where(p) ).getResultList();
 	}
+	
+	public Boolean getProject(String project) throws Exception {
+		if( StringUtils.isEmpty( project ) ) {
+			throw new Exception("project id can not be empty!");
+		}
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Boolean> cq = cb.createQuery(Boolean.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p = cb.equal( root.get(Project_.id), project );
+		cq.select(root.get( Project_.deleted)).where(p);
+		return em.createQuery(cq).getSingleResult();
+	}
 }

+ 268 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/factory/TaskListTemplateFactory.java

@@ -0,0 +1,268 @@
+package com.x.teamwork.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Order;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.exception.ExceptionWhen;
+import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.AbstractFactory;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.core.entity.Dynamic_;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.ProjectDetail;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.Project_;
+import com.x.teamwork.core.entity.TaskListTemplate;
+import com.x.teamwork.core.entity.TaskListTemplate_;
+import com.x.teamwork.core.entity.tools.CriteriaBuilderTools;
+import com.x.teamwork.core.entity.tools.filter.QueryFilter;
+
+
+public class TaskListTemplateFactory extends AbstractFactory {
+
+	public TaskListTemplateFactory( Business business ) throws Exception {
+		super(business);
+	}
+
+	/**
+	 * 获取指定Id的Project实体信息对象
+	 * @param id
+	 * @return
+	 * @throws Exception
+	 */
+	public TaskListTemplate get( String id ) throws Exception {
+		return this.entityManagerContainer().find( id, TaskListTemplate.class, ExceptionWhen.none );
+	}
+	
+	public ProjectDetail getDetail(String id) throws Exception {
+		return this.entityManagerContainer().find( id, ProjectDetail.class, ExceptionWhen.none );
+	}
+	
+	/**
+	 * 列示指定ProjectTemplate Id的TaskListTemplate实体信息列表
+	 * @param id
+	 * @return
+	 * @throws Exception
+	 */
+	public List<TaskListTemplate> list( String id ) throws Exception {
+		if( StringUtils.isNotEmpty( id ) ){
+			return new ArrayList<TaskListTemplate>();
+		}
+		EntityManager em = this.entityManagerContainer().get(Project.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<TaskListTemplate> cq = cb.createQuery(TaskListTemplate.class);
+		Root<TaskListTemplate> root = cq.from(TaskListTemplate.class);
+		Predicate p = cb.equal( root.get( TaskListTemplate_.id ), id ); 
+		cq.orderBy( cb.desc( root.get( TaskListTemplate_.updateTime ) ) ); 
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	public List<String> listAllProjectIds() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(Project.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<Project> root = cq.from(Project.class);
+		cq.select( root.get( Project_.id) );
+		return em.createQuery(cq ).getResultList();
+	}	
+	
+	/**
+	 * 根据条件查询符合条件的项目信息数量
+	 * @param personName
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countWithFilter( String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p_permission = null;
+
+		if( StringUtils.isNotEmpty( personName )) {
+			//可以管理的栏目,肯定可以发布信息
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.participantPersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.manageablePersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.creatorPerson ), personName ) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.executor ), personName ) );
+		}
+		
+		if( ListTools.isNotEmpty( identityNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantIdentityList).in(identityNames));
+		}
+		if( ListTools.isNotEmpty( unitNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantUnitList).in(unitNames));
+		}
+		if( ListTools.isNotEmpty( groupNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantGroupList).in(groupNames));
+		}
+		
+		Predicate p = CriteriaBuilderTools.composePredicateWithQueryFilter( Project_.class, cb, p_permission, root, queryFilter );
+		cq.select(cb.count(root)).where(p);
+		Long count =  em.createQuery(cq).getSingleResult();
+		return count;
+	}
+	
+	/**
+	 *  根据条件查询符合条件的项目信息ID
+	 * @param maxCount
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> listWithFilter( Integer maxCount, String orderField, String orderType, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Project> cq = cb.createQuery(Project.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p_permission = null;
+		
+		if( StringUtils.isNotEmpty( personName )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.participantPersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.manageablePersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.creatorPerson ), personName ) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.executor ), personName ) );
+		}
+		
+		if( ListTools.isNotEmpty( identityNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantIdentityList).in(identityNames));
+		}
+		if( ListTools.isNotEmpty( unitNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantUnitList).in(unitNames));
+		}
+		if( ListTools.isNotEmpty( groupNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantGroupList).in(groupNames));
+		}
+		
+		Predicate p = CriteriaBuilderTools.composePredicateWithQueryFilter( Project_.class, cb, p_permission, root, queryFilter );
+
+		Order orderWithField = CriteriaBuilderTools.getOrder(cb, root, Project_.class, orderField, orderType);
+		if( orderWithField != null ){
+			cq.orderBy( orderWithField );
+		}
+		return em.createQuery(cq.where(p)).setMaxResults( maxCount).getResultList();
+	}
+	
+	/**
+	 * 根据条件查询符合条件的项目信息ID,根据上一条的sequnce查询指定数量的信息
+	 * @param maxCount
+	 * @param sequenceFieldValue
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> listWithFilter( Integer maxCount, Object sequenceFieldValue, String orderField, String orderType, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Project> cq = cb.createQuery(Project.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p_permission = null;
+		
+		if( StringUtils.isNotEmpty( personName )) {
+			//可以管理的栏目,肯定可以发布信息
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.participantPersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.manageablePersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.creatorPerson ), personName ) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.executor ), personName ) );
+		}
+		
+		if( ListTools.isNotEmpty( identityNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantIdentityList).in(identityNames));
+		}
+		if( ListTools.isNotEmpty( unitNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantUnitList).in(unitNames));
+		}
+		if( ListTools.isNotEmpty( groupNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantGroupList).in(groupNames));
+		}
+		
+		Predicate p = CriteriaBuilderTools.composePredicateWithQueryFilter( Project_.class, cb, p_permission, root, queryFilter );
+		
+		if( sequenceFieldValue != null && StringUtils.isNotEmpty( sequenceFieldValue.toString() )) {
+			Predicate p_seq = cb.isNotNull( root.get( Dynamic_.sequence ) );
+			if( "desc".equalsIgnoreCase( orderType )){
+				p_seq = cb.and( p_seq, cb.lessThan( root.get( Project_.sequence ), sequenceFieldValue.toString() ));
+			}else{
+				p_seq = cb.and( p_seq, cb.greaterThan( root.get( Project_.sequence ), sequenceFieldValue.toString() ));
+			}
+			p = cb.and( p, p_seq);
+		}		
+		
+		Order orderWithField = CriteriaBuilderTools.getOrder( cb, root, Project_.class, orderField, orderType );
+		if( orderWithField != null ){
+			cq.orderBy( orderWithField );
+		}
+		System.out.println(">>>SQL:" + em.createQuery(cq.where(p)).setMaxResults( maxCount).toString() );
+		return em.createQuery(cq.where(p)).setMaxResults( maxCount).getResultList();
+	}
+	
+	/**
+	 * 根据条件查询所有符合条件的项目信息ID,项目信息不会很多 ,所以直接查询出来
+	 * @param maxCount
+	 * @param sequenceFieldValue
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public List<String> listAllViewableProjectIds( Integer maxCount, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( Project.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<Project> root = cq.from(Project.class);
+		Predicate p_permission = null;
+		
+		
+		if( StringUtils.isNotEmpty( personName )) {
+			//可以管理的栏目,肯定可以发布信息
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.participantPersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.isMember( personName, root.get( Project_.manageablePersonList )) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.creatorPerson ), personName ) );
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission, cb.equal( root.get( Project_.executor ), personName ) );
+		}
+		if( ListTools.isNotEmpty( identityNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantIdentityList).in(identityNames));
+		}
+		if( ListTools.isNotEmpty( unitNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantUnitList).in(unitNames));
+		}
+		if( ListTools.isNotEmpty( groupNames )) {
+			p_permission = CriteriaBuilderTools.predicate_or( cb, p_permission,  root.get( Project_.participantGroupList).in(groupNames));
+		}
+		
+		Predicate p = CriteriaBuilderTools.composePredicateWithQueryFilter( Project_.class, cb, p_permission, root, queryFilter );
+		cq.distinct(true).select( root.get(Project_.id) );
+		return em.createQuery(cq.where(p)).setMaxResults( maxCount).getResultList();
+	}
+
+	
+}

+ 4 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/ActionApplication.java

@@ -12,8 +12,10 @@ import com.x.teamwork.assemble.control.jaxrs.dynamic.DynamicAction;
 import com.x.teamwork.assemble.control.jaxrs.extfield.ProjectExtFieldReleAction;
 import com.x.teamwork.assemble.control.jaxrs.list.TaskListAction;
 import com.x.teamwork.assemble.control.jaxrs.project.ProjectAction;
+import com.x.teamwork.assemble.control.jaxrs.projectTemplate.ProjectTemplateAction;
 import com.x.teamwork.assemble.control.jaxrs.projectgroup.ProjectGroupAction;
 import com.x.teamwork.assemble.control.jaxrs.task.TaskAction;
+import com.x.teamwork.assemble.control.jaxrs.taskListTemplate.TaskListTemplateAction;
 import com.x.teamwork.assemble.control.jaxrs.taskgroup.TaskGroupAction;
 import com.x.teamwork.assemble.control.jaxrs.tasktag.TaskTagAction;
 import com.x.teamwork.assemble.control.jaxrs.taskview.TaskViewAction;
@@ -35,6 +37,8 @@ public class ActionApplication extends AbstractActionApplication {
 		this.classes.add( ChatAction.class );
 		this.classes.add( SystemConfigAction.class );
 		this.classes.add( ProjectExtFieldReleAction.class );
+		this.classes.add( ProjectTemplateAction.class );
+		this.classes.add( TaskListTemplateAction.class );
 		return this.classes;
 	}
 

+ 2 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/JaxrsManagerUserFilter.java

@@ -12,6 +12,8 @@ import com.x.base.core.project.jaxrs.ManagerUserJaxrsFilter;
 		"/jaxrs/task_view/*",
 		"/jaxrs/attachment/*",
 		"/jaxrs/project_group/*",
+		"/jaxrs/projectTemplate/*",
+		"/jaxrs/taskListTemplate/*",
 		"/jaxrs/task_group/*",
 		"/jaxrs/task_list/*",
 		"/jaxrs/config/*",

+ 2 - 2
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/list/ActionGet.java

@@ -75,9 +75,9 @@ public class ActionGet extends BaseAction {
 						}
 					}
 					if( "NoneList".equalsIgnoreCase( wo.getMemo() )) {
-						wo.setControl( new Control(false, false, false ));
+						wo.setControl( new Control(false, false, false, false ));
 					}else {
-						wo.setControl( new Control(true, true, true ));
+						wo.setControl( new Control(true, true, true, true));
 					}
 					taskListCache.put(new Element(cacheKey, wo));
 					result.setData(wo);

+ 12 - 5
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/list/ActionListWithTaskGroup.java

@@ -9,7 +9,6 @@ import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
-import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
@@ -17,7 +16,6 @@ import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.teamwork.core.entity.TaskList;
 
-import net.sf.ehcache.Element;
 
 public class ActionListWithTaskGroup extends BaseAction {
 
@@ -47,9 +45,9 @@ public class ActionListWithTaskGroup extends BaseAction {
 								//计算当前List里的任务数量
 								wo.setTaskCount(taskListQueryService.countTaskWithTaskListId( effectivePerson.getDistinguishedName(), wo.getId(), wo.getTaskGroup() ));
 								if( "NoneList".equalsIgnoreCase( wo.getMemo() )) {
-									wo.setControl( new Control(false, false, false ));
+									wo.setControl( new Control(false, false, false, false ));
 								}else {
-									wo.setControl( new Control(true, true, true ));
+									wo.setControl( new Control(true, true, true, true ));
 								}
 							}
 						}
@@ -116,11 +114,14 @@ public class ActionListWithTaskGroup extends BaseAction {
 		private Boolean edit = false;
 		
 		private Boolean sortable = true;
+		
+		private Boolean founder = false;
 
-		public Control( Boolean edit, Boolean delete, Boolean sortable ) {
+		public Control( Boolean edit, Boolean delete, Boolean sortable, Boolean founder ) {
 			this.delete = delete;
 			this.edit = edit;
 			this.sortable = sortable;
+			this.founder = founder;
 		}
 		public Boolean getDelete() {
 			return delete;
@@ -143,5 +144,11 @@ public class ActionListWithTaskGroup extends BaseAction {
 		public void setSortable(Boolean sortable) {
 			this.sortable = sortable;
 		}
+		public Boolean getFounder() {
+			return founder;
+		}
+		public void setFounder(Boolean founder) {
+			this.founder = founder;
+		}
 	}
 }

+ 22 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionGet.java

@@ -7,6 +7,8 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.lang3.StringUtils;
 
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -16,6 +18,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.ProjectDetail;
 import com.x.teamwork.core.entity.ProjectGroup;
@@ -82,10 +85,26 @@ public class ActionGet extends BaseAction {
 					groups = projectGroupQueryService.list( groupIds );
 					wo.setGroups( groups );	
 					
+					Business business = null;
+					try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+						business = new Business(bc);
+					}
 					control = new WrapOutControl();
-					if( effectivePerson.isManager() || effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )) {
-						control.setManageAble( true );
-						control.setEditAble( true );
+					if( business.isManager(effectivePerson)
+							|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
+							|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
+						control.setDelete( true );
+						control.setEdit( true );
+						control.setSortable( true );
+					}else{
+						control.setDelete( false );
+						control.setEdit( false );
+						control.setSortable( false );
+					}
+					if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+						control.setFounder( true );
+					}else{
+						control.setFounder( false );
 					}
 					wo.setControl(control);
 					projectCache.put(new Element(cacheKey, wo));

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListArchiveNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.InTerm;
@@ -99,12 +102,27 @@ public class ActionListArchiveNextWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListCompletedNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.InTerm;
@@ -99,12 +102,27 @@ public class ActionListCompletedNextWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListMyNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.EqualsTerm;
@@ -99,12 +102,27 @@ public class ActionListMyNextWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListNextInGroupWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.InTerm;
@@ -93,12 +96,27 @@ public class ActionListNextInGroupWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.InTerm;
@@ -96,12 +99,27 @@ public class ActionListNextWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListNoGroupNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.EqualsTerm;
@@ -99,12 +102,27 @@ public class ActionListNoGroupNextWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListPageInGroupWithFilter.java

@@ -6,6 +6,8 @@ import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -15,6 +17,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.InTerm;
@@ -89,12 +92,27 @@ public class ActionListPageInGroupWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListPageWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.InTerm;
@@ -96,12 +99,27 @@ public class ActionListPageWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 25 - 6
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListRecycleNextWithFilter.java

@@ -1,5 +1,7 @@
 package com.x.teamwork.assemble.control.jaxrs.project;
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -9,6 +11,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.InTerm;
@@ -51,6 +54,8 @@ public class ActionListRecycleNextWithFilter extends BaseAction {
 			if( wrapIn == null ) {
 				wrapIn = new Wi();
 			}
+			//已删除
+			wrapIn.setDeleted("true");
 			queryFilter = wrapIn.getQueryFilter();
 			if( StringUtils.isNotEmpty( wrapIn.getGroup() )) {
 				//如果项目分组不为空,那么需要先根据项目分组来查询这个分组下的所有项目ID集合
@@ -64,8 +69,7 @@ public class ActionListRecycleNextWithFilter extends BaseAction {
 				}
 				queryFilter.addInTerm( new InTerm("id", new ArrayList<Object>(queryProjectIds) ));
 			}
-			//已删除
-			queryFilter.addIsTrueTerm( new IsTrueTerm("deleted" ));
+			//queryFilter.addIsTrueTerm( new IsTrueTerm("deleted" ));
 		}
 		
 		if( Boolean.TRUE.equals( check ) ) {
@@ -80,7 +84,7 @@ public class ActionListRecycleNextWithFilter extends BaseAction {
 			} else {
 				try {	
 					//获取用户能查看的所有的项目信息ID列表,最多查询2000条数据
-					List<String>  projectIds = projectQueryService.listAllViewableProjectIds( effectivePerson, 2000, queryFilter );
+					List<String>  projectIds = projectQueryService.listAllProjectIds( effectivePerson, 2000, queryFilter );
 					if( ListTools.isNotEmpty( projectIds )) {
 						//直接根据可见项目ID列表进行分页查询
 						Long total = Long.parseLong( projectIds.size() + "" );										
@@ -94,12 +98,27 @@ public class ActionListRecycleNextWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionListStarNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
 import com.x.teamwork.core.entity.tools.filter.term.InTerm;
@@ -99,12 +102,27 @@ public class ActionListStarNextWithFilter extends BaseAction {
 								if( wo.getStarPersonList().contains( effectivePerson.getDistinguishedName() )) {
 									wo.setStar( true );
 								}
+								
+								Business business = null;
+								try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+									business = new Business(bc);
+								}
 								control = new WrapOutControl();
-								if( effectivePerson.isManager() 
+								if( business.isManager(effectivePerson) 
 										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson() )
 										|| project.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )) {
-									control.setManageAble( true );
-									control.setEditAble( true );
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( project.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
 								}
 								wo.setControl(control);
 								wos.add( wo );

+ 21 - 19
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionStatisticMyProjects.java

@@ -53,7 +53,7 @@ public class ActionStatisticMyProjects extends BaseAction {
 			if( Boolean.TRUE.equals( check ) ){
 				try {
 					//查询我参与的所有项目
-					projectIds = projectQueryService.listAllViewableProjectIds( effectivePerson, 2000,  new QueryFilter() );
+					projectIds = projectQueryService.listAllProjectIds( effectivePerson, 2000,  new QueryFilter() );
 					if( ListTools.isNotEmpty( projectIds )) {
 						projectList = projectQueryService.list( projectIds );
 					}
@@ -87,26 +87,28 @@ public class ActionStatisticMyProjects extends BaseAction {
 			if( Boolean.TRUE.equals( check ) ){
 				if( ListTools.isNotEmpty( projectList )) {
 					for(  Project project : projectList ) {
-						allCount++;						
-						if( project.getStarPersonList() != null  && project.getStarPersonList().contains( effectivePerson.getDistinguishedName() ) ) {
-							starCount++;
-						}
-						if( project.getCreatorPerson().equalsIgnoreCase(effectivePerson.getDistinguishedName()  )) {
-							myCount++;
-						}
-						if( project.getGroupCount() == null || project.getGroupCount() == 0 ) {
-							unGroupCount++;
-						}
-						if( project.getCompleted() != null && project.getCompleted() ) {
-							completedCount++;
-						}
-						if( project.getArchive() != null && project.getArchive() ) {
-							archiveCount++;
-						}
-						if( project.getDeleted() != null && project.getDeleted() ) {
+						if(project.getDeleted() != null && project.getDeleted() ){
 							deleteCount++;
+						}else{
+							allCount++;						
+							if( project.getStarPersonList() != null  && project.getStarPersonList().contains( effectivePerson.getDistinguishedName() ) ) {
+								starCount++;
+							}
+							if( project.getCreatorPerson().equalsIgnoreCase(effectivePerson.getDistinguishedName()  )) {
+								myCount++;
+							}
+							if( project.getGroupCount() == null || project.getGroupCount() == 0 ) {
+								unGroupCount++;
+							}
+							if( project.getCompleted() != null && project.getCompleted() ) {
+								completedCount++;
+							}
+							if( project.getArchive() != null && project.getArchive() ) {
+								archiveCount++;
+							}
+							woGroupList = checkGroup( project, woGroupList );
 						}
-						woGroupList = checkGroup( project, woGroupList );
+						
 					}
 				}
 			}

+ 35 - 14
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/WrapOutControl.java

@@ -3,28 +3,49 @@ package com.x.teamwork.assemble.control.jaxrs.project;
 import com.x.base.core.project.annotation.FieldDescribe;
 
 public class WrapOutControl {
-
-	@FieldDescribe("是可以管理")
-	private Boolean manageAble = false;
 	
-	@FieldDescribe("是可以编辑")
-	private Boolean editAble = false;
-
-	public Boolean getManageAble() {
-		return manageAble;
+	@FieldDescribe("是否可删除")
+	private Boolean delete = false;
+	
+	@FieldDescribe("是否可编辑")
+	private Boolean edit = false;
+	
+	@FieldDescribe("是否可排序")
+	private Boolean sortable = true;
+	
+	@FieldDescribe("是否创始人")
+	private Boolean founder = false;
+	
+	public Boolean getDelete() {
+		return delete;
 	}
 
-	public void setManageAble(Boolean manageAble) {
-		this.manageAble = manageAble;
+	public void setDelete(Boolean delete) {
+		this.delete = delete;
+	}
+	
+	public Boolean getEdit() {
+		return edit;
 	}
 
-	public Boolean getEditAble() {
-		return editAble;
+	public void setEdit(Boolean edit) {
+		this.edit = edit;
+	}
+	
+	public Boolean getSortable() {
+		return sortable;
 	}
 
-	public void setEditAble(Boolean editAble) {
-		this.editAble = editAble;
+	public void setSortable(Boolean sortable) {
+		this.sortable = sortable;
 	}
 	
+	public Boolean getFounder() {
+		return founder;
+	}
+
+	public void setFounder(Boolean founder) {
+		this.founder = founder;
+	}
 	
 }

+ 122 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionDelete.java

@@ -0,0 +1,122 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoId;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.teamwork.core.entity.Dynamic;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.TaskListTemplate;
+
+public class ActionDelete extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionDelete.class);
+
+	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson, String flag) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		ProjectTemplate projectTemplate = null;
+		Boolean check = true;
+		Wo wo = new Wo();
+
+		if ( StringUtils.isEmpty( flag ) ) {
+			check = false;
+			Exception exception = new ProjectTemplateFlagForQueryEmptyException();
+			result.error( exception );
+		}
+
+		if( Boolean.TRUE.equals( check ) ){
+			try {
+				projectTemplate = projectTemplateQueryService.get(flag);
+				if ( projectTemplate == null) {
+					check = false;
+					Exception exception = new ProjectTemplateNotExistsException(flag);
+					result.error( exception );
+				}
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ProjectTemplateQueryException(e, "根据指定flag查询项模板目信息对象时发生异常。flag:" + flag);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		
+		if( Boolean.TRUE.equals( check ) ){
+			try {
+				projectTemplatePersistService.delete(flag, effectivePerson );
+				
+				// 更新缓存
+				ApplicationCache.notify( ProjectTemplate.class );
+				ApplicationCache.notify( TaskListTemplate.class );
+				
+				wo.setId( projectTemplate.getId() );
+				
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ProjectTemplateQueryException(e, "根据指定flag删除项目模板信息对象时发生异常。flag:" + flag);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		/*if( Boolean.TRUE.equals( check ) ){
+			try {					
+				Dynamic dynamic = dynamicPersistService.projectGroupDeleteDynamic( projectGroup, effectivePerson );
+				if( dynamic != null ) {
+					List<WoDynamic> dynamics = new ArrayList<>();
+					dynamics.add( WoDynamic.copier.copy( dynamic ) );
+					if( wo != null ) {
+						wo.setDynamics(dynamics);
+					}
+				}
+			} catch (Exception e) {
+				logger.error(e, effectivePerson, request, null);
+			}	
+		}*/
+		result.setData( wo );
+		return result;
+	}
+
+	public static class Wo extends WoId {
+		
+		@FieldDescribe("操作引起的动态内容")
+		List<WoDynamic> dynamics = new ArrayList<>();
+
+		public List<WoDynamic> getDynamics() {
+			return dynamics;
+		}
+
+		public void setDynamics(List<WoDynamic> dynamics) {
+			this.dynamics = dynamics;
+		}
+		
+	}
+	
+	public static class WoDynamic extends Dynamic{
+
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static WrapCopier<Dynamic, WoDynamic> copier = WrapCopierFactory.wo( Dynamic.class, WoDynamic.class, null, JpaObject.FieldsInvisible);
+		
+		private Long rank = 0L;
+
+		public Long getRank() {
+			return rank;
+		}
+
+		public void setRank(Long rank) {
+			this.rank = rank;
+		}		
+	}
+}

+ 86 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionGet.java

@@ -0,0 +1,86 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.core.entity.ProjectTemplate;
+
+import net.sf.ehcache.Element;
+
+public class ActionGet extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionGet.class);
+
+	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson, String id ) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		Wo wo = null;
+		ProjectTemplate projectTemplate = null;
+		Boolean check = true;
+
+		if ( StringUtils.isEmpty( id ) ) {
+			check = false;
+			Exception exception = new ProjectTemplateFlagForQueryEmptyException();
+			result.error( exception );
+		}
+
+		String cacheKey = ApplicationCache.concreteCacheKey( id ,effectivePerson);
+		Element element = projectTemplateCache.get( cacheKey );
+
+		if ((null != element) && (null != element.getObjectValue())) {
+			wo = (Wo) element.getObjectValue();
+			result.setData( wo );
+		} else {
+			if( Boolean.TRUE.equals( check ) ){
+				try {
+					projectTemplate = projectTemplateQueryService.get( id );
+					if ( projectTemplate == null) {
+						check = false;
+						Exception exception = new ProjectTemplateNotExistsException( id );
+						result.error( exception );
+					}
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new ProjectTemplateQueryException(e, "根据指定flag查询项目模板信息对象时发生异常。id:" + id );
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+			}
+			
+			if( Boolean.TRUE.equals( check ) ){
+				try {
+					wo = Wo.copier.copy( projectTemplate );					
+					projectTemplateCache.put(new Element(cacheKey, wo));
+					result.setData(wo);
+				} catch (Exception e) {
+					Exception exception = new ProjectTemplateQueryException(e, "将查询出来的项目模板信息对象转换为可输出的数据信息时发生异常。");
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+			}
+		}
+		return result;
+	}
+
+	public static class Wo extends ProjectTemplate {
+		
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static List<String> Excludes = new ArrayList<String>();
+
+		static WrapCopier<ProjectTemplate, Wo> copier = WrapCopierFactory.wo( ProjectTemplate.class, Wo.class, null, ListTools.toList(JpaObject.FieldsInvisible));		
+
+	}
+}

+ 81 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionList.java

@@ -0,0 +1,81 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.tools.SortTools;
+import com.x.teamwork.core.entity.ProjectGroup;
+
+import net.sf.ehcache.Element;
+
+public class ActionList extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionList.class);
+
+	@SuppressWarnings("unchecked")
+	protected ActionResult<List<Wo>> execute(HttpServletRequest request, EffectivePerson effectivePerson ) throws Exception {
+		ActionResult<List<Wo>> result = new ActionResult<>();
+		List<Wo> wos = null;
+		List<ProjectGroup> projectGroups = null;
+		Boolean check = true;
+
+		String cacheKey = ApplicationCache.concreteCacheKey( "list.my", effectivePerson.getDistinguishedName() );
+		/*Element element = projectGroupCache.get( cacheKey );
+		
+		if ((null != element) && (null != element.getObjectValue())) {
+			wos = (List<Wo>) element.getObjectValue();
+			result.setData( wos );
+		} else {
+			if( Boolean.TRUE.equals( check ) ){
+				try {
+					projectGroups = projectGroupQueryService.listGroupByPerson( effectivePerson.getDistinguishedName() );
+					if( ListTools.isNotEmpty( projectGroups )) {
+						wos = Wo.copier.copy( projectGroups );
+						
+						SortTools.asc( wos, "createTime");
+						
+						projectGroupCache.put(new Element(cacheKey, wos));
+						result.setData(wos);
+					}
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new ProjectTemplateQueryException(e, "根据用户拥有的项目组信息列表时发生异常。");
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+			}
+		}*/
+		return result;
+	}
+
+	public static class Wo extends ProjectGroup {
+		
+		private Long rank;
+
+		public Long getRank() {
+			return rank;
+		}
+
+		public void setRank(Long rank) {
+			this.rank = rank;
+		}
+
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static List<String> Excludes = new ArrayList<String>();
+
+		static WrapCopier<ProjectGroup, Wo> copier = WrapCopierFactory.wo( ProjectGroup.class, Wo.class, null, ListTools.toList(JpaObject.FieldsInvisible));
+
+	}
+}

+ 114 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionListWithFilter.java

@@ -0,0 +1,114 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.tools.SortTools;
+import com.x.teamwork.core.entity.ProjectGroup;
+
+import net.sf.ehcache.Element;
+
+public class ActionListWithFilter extends BaseAction {
+
+	private static  Logger logger = LoggerFactory.getLogger(ActionListWithFilter.class);
+
+	@SuppressWarnings("unchecked")
+	protected ActionResult<List<Wo>> execute(HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
+		ActionResult<List<Wo>> result = new ActionResult<>();
+		List<ProjectGroup> projectGroups = null;
+		List<Wo> wos = null;
+		Wi wi = null;
+		Boolean check = true;
+
+		try {
+			wi = this.convertToWrapIn( jsonElement, Wi.class );
+		} catch (Exception e) {
+			check = false;
+			Exception exception = new ProjectTemplateQueryException(e, "系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString() );
+			result.error(exception);
+			logger.error(e, effectivePerson, request, null);
+		}
+		
+		String cacheKey = ApplicationCache.concreteCacheKey( getStringListHeyx( wi.getIds()) );
+		/*Element element = projectGroupCache.get( cacheKey );
+
+		if ((null != element) && (null != element.getObjectValue())) {
+			wos = (List<Wo>) element.getObjectValue();
+			result.setData( wos );
+		} else {
+			if( Boolean.TRUE.equals( check ) ){
+				try {
+					projectGroups = projectGroupQueryService.list( wi.getIds() );
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new ProjectTemplateQueryException(e, "系统通过指定的ID列表查询项目组信息列表时发生异常。JSON:" + jsonElement.toString() );
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+				
+			}
+			
+			if( Boolean.TRUE.equals( check ) ){
+				if( ListTools.isNotEmpty( projectGroups )) {
+					wos = Wo.copier.copy( projectGroups );					
+					SortTools.asc( wos, "createTime");					
+					projectGroupCache.put(new Element(cacheKey, wos));
+					result.setData(wos);
+				}	
+			}
+		}*/
+		return result;
+	}	
+
+	public static class Wi {
+
+		@FieldDescribe("项目组ID列表")
+		private List<String> ids;
+
+		public List<String> getIds() {
+			return ids;
+		}
+
+		public void setIds(List<String> ids) {
+			this.ids = ids;
+		}
+	}
+
+	public static class Wo extends ProjectGroup {
+		
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static List<String> Excludes = new ArrayList<String>();
+
+		static WrapCopier<ProjectGroup, Wo> copier = WrapCopierFactory.wo( ProjectGroup.class, Wo.class, null, ListTools.toList(JpaObject.FieldsInvisible));		
+
+	}
+	
+	private String getStringListHeyx( List<String> list ) {
+		StringBuffer content = new StringBuffer();
+		if( ListTools.isNotEmpty( list )) {
+			SortTools.asc( list );
+			for( String str : list ) {
+				content.append( str );
+			}
+			return DigestUtils.sha1Hex(content.toString() );
+		}
+		return "null";
+	}
+	
+}

+ 31 - 33
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/project/ActionTemplateSave.java → o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ActionSave.java

@@ -1,4 +1,4 @@
-package com.x.teamwork.assemble.control.jaxrs.project;
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -16,19 +16,15 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
-import com.x.base.core.project.tools.ListTools;
 import com.x.teamwork.assemble.control.service.BatchOperationPersistService;
 import com.x.teamwork.assemble.control.service.BatchOperationProcessService;
 import com.x.teamwork.core.entity.Dynamic;
-import com.x.teamwork.core.entity.Project;
-import com.x.teamwork.core.entity.ProjectDetail;
-import com.x.teamwork.core.entity.ProjectGroup;
 import com.x.teamwork.core.entity.ProjectTemplate;
-import com.x.teamwork.core.entity.Task;
+import com.x.teamwork.core.entity.TaskListTemplate;
 
-public class ActionTemplateSave extends BaseAction {
+public class ActionSave extends BaseAction {
 
-	private static  Logger logger = LoggerFactory.getLogger(ActionTemplateSave.class);
+	private static  Logger logger = LoggerFactory.getLogger(ActionSave.class);
 
 	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
 		ActionResult<Wo> result = new ActionResult<>();
@@ -42,47 +38,37 @@ public class ActionTemplateSave extends BaseAction {
 			wi = this.convertToWrapIn( jsonElement, Wi.class );
 		} catch (Exception e) {
 			check = false;
-			Exception exception = new ProjectPersistException(e, "系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString());
+			Exception exception = new ProjectTemplatePersistException(e, "系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString());
 			result.error(exception);
 			logger.error(e, effectivePerson, request, null);
 		}
 		
 		
-		/*if( Boolean.TRUE.equals( check ) ){
-			old_template = projectQueryService.get( wi.getId() );
+		if( Boolean.TRUE.equals( check ) ){
+			old_template = projectTemplateQueryService.get( wi.getId() );
 		}
 		
 		if( Boolean.TRUE.equals( check ) ){
-			ProjectDetail projectDetail = new ProjectDetail();
-			projectDetail.setDescription( wi.getDescription() );
-			
-			try {	
-				if( ListTools.isNotEmpty( wi.getGroups() )) {
-					wi.setGroupCount( wi.getGroups().size() );
-				}
+			try {
+				template = projectTemplatePersistService.save( Wi.copier.copy(wi), effectivePerson );
 				
-				template = projectPersistService.save( Wi.copier.copy(wi), projectDetail, effectivePerson );
-				
-				//将项目添加到指定的项目组
-				projectGroupPersistService.releProjectToGroup(  template.getId(), wi.getGroups() );
+				//添加模板对应的泳道
+				projectTemplatePersistService.createTaskList( template ,effectivePerson.getDistinguishedName());
 				
 				// 更新缓存
-				ApplicationCache.notify( Project.class );
-				ApplicationCache.notify( ProjectGroup.class );
-
-				ApplicationCache.notify( Task.class, ApplicationCache.concreteCacheKey( "ActionStatisticMyTasks", template.getId(), effectivePerson.getDistinguishedName() )  );
-				ApplicationCache.notify( Task.class, ApplicationCache.concreteCacheKey( "ActionStatisticMyTaskViews", template.getId(),  effectivePerson.getDistinguishedName() )  );				
+				ApplicationCache.notify( ProjectTemplate.class );
+				ApplicationCache.notify( TaskListTemplate.class );			
 				
 				wo.setId( template.getId() );
 				
 			} catch (Exception e) {
 				check = false;
-				Exception exception = new ProjectPersistException(e, "项目信息保存时发生异常。");
+				Exception exception = new ProjectTemplatePersistException(e, "项目信息保存时发生异常。");
 				result.error(exception);
 				logger.error(e, effectivePerson, request, null);
 			}
 		}
-		*/
+		
 		if( Boolean.TRUE.equals( check ) ){
 			try {					
 				new BatchOperationPersistService().addOperation( 
@@ -93,9 +79,9 @@ public class ActionTemplateSave extends BaseAction {
 			}	
 		}
 		
-		/*if( Boolean.TRUE.equals( check ) ){
+		if( Boolean.TRUE.equals( check ) ){
 			try {					
-				List<Dynamic> dynamics = dynamicPersistService.projectSaveDynamic(old_template, template, effectivePerson,  jsonElement.toString() );
+				List<Dynamic> dynamics = dynamicPersistService.projectTemplateSaveDynamic(old_template, template, effectivePerson,  jsonElement.toString() );
 				if( dynamics == null ) {
 					dynamics = new ArrayList<>();
 				}
@@ -105,7 +91,7 @@ public class ActionTemplateSave extends BaseAction {
 			} catch (Exception e) {
 				logger.error(e, effectivePerson, request, null);
 			}
-		}*/
+		}
 		result.setData( wo );
 		return result;
 	}	
@@ -130,10 +116,14 @@ public class ActionTemplateSave extends BaseAction {
 		@FieldDescribe("说明信息(1M),非必填")
 		private String description;
 		
-		@FieldDescribe("模板包含的默认永道,可多值,非必填.")
+		@FieldDescribe("模板包含的永道,可多值,非必填.")
 		private List<String> taskList = null;
 		
+		public static WrapCopier<Wi, ProjectTemplate> copier = WrapCopierFactory.wi( Wi.class, ProjectTemplate.class, null, null );
+		
 		private String owner = null;
+	
+		private Boolean deleted = false;
 		
 		public String getId() {
 			return id;
@@ -198,6 +188,14 @@ public class ActionTemplateSave extends BaseAction {
 		public void setTaskList(List<String> taskList) {
 			this.taskList = taskList;
 		}
+		
+		public Boolean getDeleted() {
+			return deleted;
+		}
+
+		public void setDeleted(Boolean deleted) {
+			this.deleted = deleted;
+		}
 	}
 
 public static class Wo extends WoId {

+ 25 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/BaseAction.java

@@ -0,0 +1,25 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.teamwork.assemble.control.service.DynamicPersistService;
+import com.x.teamwork.assemble.control.service.ProjectTemplatePersistService;
+import com.x.teamwork.assemble.control.service.ProjectTemplateQueryService;
+import com.x.teamwork.assemble.control.service.SystemConfigQueryService;
+import com.x.teamwork.core.entity.ProjectTemplate;
+
+import net.sf.ehcache.Ehcache;
+
+public class BaseAction extends StandardJaxrsAction {
+
+	protected Ehcache projectTemplateCache = ApplicationCache.instance().getCache( ProjectTemplate.class );
+	
+	protected 	ProjectTemplateQueryService projectTemplateQueryService = new ProjectTemplateQueryService();
+	
+	protected 	ProjectTemplatePersistService projectTemplatePersistService = new ProjectTemplatePersistService();
+	
+	protected 	DynamicPersistService dynamicPersistService = new DynamicPersistService();
+	
+	protected 	SystemConfigQueryService systemConfigQueryService = new SystemConfigQueryService();
+	
+}

+ 128 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplateAction.java

@@ -0,0 +1,128 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.JaxrsDescribe;
+import com.x.base.core.project.annotation.JaxrsMethodDescribe;
+import com.x.base.core.project.annotation.JaxrsParameterDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.http.HttpMediaType;
+import com.x.base.core.project.jaxrs.ResponseFactory;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+
+@Path("projectTemplate")
+@JaxrsDescribe("项目模板信息管理")
+public class ProjectTemplateAction extends StandardJaxrsAction {
+
+	private Logger logger = LoggerFactory.getLogger(ProjectTemplateAction.class);
+	
+	@JaxrsMethodDescribe(value = "根据ID查询项目模板信息.", action = ActionGet.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void get(@Suspended final AsyncResponse asyncResponse, 
+			@Context HttpServletRequest request, 
+			@JaxrsParameterDescribe("项目组ID") @PathParam("id") String id ) {
+		ActionResult<ActionGet.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionGet().execute( request, effectivePerson, id );
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+	
+	@JaxrsMethodDescribe(value = "查询用户创建的所有项目组信息列表.", action = ActionList.class)
+	@GET
+	@Path("list/my")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void listGroups(@Suspended final AsyncResponse asyncResponse, 
+			@Context HttpServletRequest request ) {
+		ActionResult<List<ActionList.Wo>> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);	
+		try {
+			result = new ActionList().execute( request, effectivePerson );
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+	
+	@JaxrsMethodDescribe(value = "根据ID列表查询项目组信息列表.", action = ActionListWithFilter.class)
+	@PUT
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void listWithIds(@Suspended final AsyncResponse asyncResponse, 
+			@Context HttpServletRequest request, 
+			@JaxrsParameterDescribe("传入的ID列表") JsonElement jsonElement ) {
+		ActionResult<List<ActionListWithFilter.Wo>> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionListWithFilter().execute(request, effectivePerson, jsonElement);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+	
+	@JaxrsMethodDescribe(value = "创建或者更新一个项目模板信息.", action = ActionSave.class)
+	@POST
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void save(@Suspended final AsyncResponse asyncResponse, 
+			@Context HttpServletRequest request, 
+			@JaxrsParameterDescribe("需要保存的项目模板信息") JsonElement jsonElement ) {
+		ActionResult<ActionSave.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionSave().execute(request, effectivePerson, jsonElement);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+	
+	@JaxrsMethodDescribe(value = "根据标识删除项目模板信息.", action = ActionDelete.class)
+	@DELETE
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void delete(@Suspended final AsyncResponse asyncResponse, 
+			@Context HttpServletRequest request, 
+			@JaxrsParameterDescribe("标识") @PathParam("id") String id ) {
+		ActionResult<ActionDelete.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionDelete().execute(request, effectivePerson, id);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+}

+ 12 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplateFlagForQueryEmptyException.java

@@ -0,0 +1,12 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ProjectTemplateFlagForQueryEmptyException extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	ProjectTemplateFlagForQueryEmptyException() {
+		super("查询的项目模板信息ID为空,无法继续查询数据。" );
+	}
+}

+ 12 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplateNotExistsException.java

@@ -0,0 +1,12 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ProjectTemplateNotExistsException extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	ProjectTemplateNotExistsException( String id ) {
+		super("指定ID的项目模板信息不存在。ID:" + id );
+	}
+}

+ 20 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplatePersistException.java

@@ -0,0 +1,20 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ProjectTemplatePersistException extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	ProjectTemplatePersistException( Throwable e ) {
+		super("系统在保存项目模板信息时发生异常。" , e );
+	}
+	
+	ProjectTemplatePersistException( Throwable e, String message ) {
+		super("系统在保存项目模板信息时发生异常。Message:" + message, e );
+	}
+	
+	ProjectTemplatePersistException( String message ) {
+		super("系统在保存项目模板信息时发生异常。Message:" + message );
+	}
+}

+ 16 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/projectTemplate/ProjectTemplateQueryException.java

@@ -0,0 +1,16 @@
+package com.x.teamwork.assemble.control.jaxrs.projectTemplate;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ProjectTemplateQueryException extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	ProjectTemplateQueryException( Throwable e ) {
+		super("系统在查询项目模板信息时发生异常。" , e );
+	}
+	
+	ProjectTemplateQueryException( Throwable e, String message ) {
+		super("系统在查询项目模板信息时发生异常。Message:" + message, e );
+	}
+}

+ 54 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionGet.java

@@ -5,9 +5,12 @@ import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
 
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.*;
 import org.apache.commons.lang3.StringUtils;
 
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -34,6 +37,7 @@ public class ActionGet extends BaseAction {
 		List<ProjectExtFieldRele> extFieldReleList = null;
 		List<TaskTag> tags = null;
 		Boolean check = true;
+		WrapOutControl control = null;
 
 		if ( StringUtils.isEmpty( flag ) ) {
 			check = false;
@@ -123,12 +127,51 @@ public class ActionGet extends BaseAction {
 					}
 
 				} catch (Exception e) {
+					check = false;
 					Exception exception = new TaskQueryException(e, "将查询出来的工作任务信息对象转换为可输出的数据信息时发生异常。");
 					result.error(exception);
 					logger.error(e, effectivePerson, request, null);
 				}
 			}
-
+			
+			//计算权限
+			if( Boolean.TRUE.equals( check ) ){
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
+				try {
+					control = new WrapOutControl();
+					if( business.isManager(effectivePerson) 
+							|| effectivePerson.getDistinguishedName().equalsIgnoreCase( task.getCreatorPerson() )
+							|| task.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+						control.setDelete( true );
+						control.setEdit( true );
+						control.setSortable( true );
+						control.setChangeExecutor( true );
+					}else{
+						control.setDelete( false );
+						control.setEdit( false );
+						control.setSortable( false );
+						control.setChangeExecutor( false );
+					}
+					if(effectivePerson.getDistinguishedName().equalsIgnoreCase( task.getExecutor())){
+						control.setChangeExecutor( true );
+					}
+					if(effectivePerson.getDistinguishedName().equalsIgnoreCase( task.getCreatorPerson())){
+						control.setFounder( true );
+					}else{
+						control.setFounder( false );
+					}
+					wo.setControl(control);
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + flag);
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+			}
+			
 			//查询任务所在的Group信息
 			if( Boolean.TRUE.equals( check ) ){
 				List<String> groupIds = null;
@@ -191,6 +234,9 @@ public class ActionGet extends BaseAction {
 		
 		@FieldDescribe("所属项目的扩展列设定(配置列表)")
 		private List<WoExtFieldRele> extFieldConfigs;
+		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
 
 		@FieldDescribe("工作任务所属的工作任务组信息ID")
 		String taskGroupId = null;
@@ -263,7 +309,14 @@ public class ActionGet extends BaseAction {
 		public void setTags(List<WoTaskTag> tags) {
 			this.tags = tags;
 		}
+		
+		public WrapOutControl getControl() {
+			return control;
+		}
 
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
 
 		private static final long serialVersionUID = -5076990764713538973L;
 

+ 67 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionListMyTaskWithTaskList.java

@@ -7,6 +7,8 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.lang3.StringUtils;
 
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -17,6 +19,8 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.assemble.control.jaxrs.task.ActionListWithTaskList.WoSubTask;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 
@@ -34,6 +38,8 @@ public class ActionListMyTaskWithTaskList extends BaseAction {
 		String cacheKey = null;
 		Element element = null;
 		List<TaskTag> tags = null;
+		List<Task> subTasks = null;
+		WrapOutControl control = null;
 		
 		if ( StringUtils.isEmpty( taskListId ) ) {
 			check = false;
@@ -50,6 +56,10 @@ public class ActionListMyTaskWithTaskList extends BaseAction {
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
 			} else {
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					List<Task>  taskList = taskQueryService.listMyTaskWithTaskListId( projectId, taskListId, effectivePerson.getDistinguishedName() );
 					Long total = 0L;
@@ -61,6 +71,41 @@ public class ActionListMyTaskWithTaskList extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							//添加一级子任务信息
+							subTasks = taskQueryService.listTaskWithParentId( wo.getId(), effectivePerson );
+							if( ListTools.isNotEmpty( subTasks )) {
+								wo.setSubTasks( WoSubTask.copier.copy( subTasks ));
+							}
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}
 					
@@ -85,6 +130,12 @@ public class ActionListMyTaskWithTaskList extends BaseAction {
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
 		
+		@FieldDescribe("一级子任务")
+		private List<WoSubTask> subTasks = null;
+		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
 		public List<WoTaskTag> getTags() {
 			return tags;
 		}
@@ -93,6 +144,14 @@ public class ActionListMyTaskWithTaskList extends BaseAction {
 			this.tags = tags;
 		}
 		
+		public List<WoSubTask> getSubTasks() {
+			return subTasks;
+		}
+
+		public void setSubTasks(List<WoSubTask> subTasks) {
+			this.subTasks = subTasks;
+		}
+		
 		private Long rank;
 
 		public Long getRank() {
@@ -102,6 +161,14 @@ public class ActionListMyTaskWithTaskList extends BaseAction {
 		public void setRank(Long rank) {
 			this.rank = rank;
 		}
+		
+		public WrapOutControl getControl() {
+			return control;
+		}
+
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
 
 		private static final long serialVersionUID = -5076990764713538973L;
 

+ 68 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionListNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -18,6 +20,8 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.assemble.control.jaxrs.task.ActionListWithTaskList.WoSubTask;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
@@ -39,6 +43,8 @@ public class ActionListNextWithFilter extends BaseAction {
 		Element element = null;
 		List<TaskTag> tags = null;
 		QueryFilter  queryFilter = null;
+		List<Task> subTasks = null;
+		WrapOutControl control = null;
 		
 		if ( StringUtils.isEmpty( flag ) || "(0)".equals(flag)) {
 			flag = null;
@@ -68,6 +74,10 @@ public class ActionListNextWithFilter extends BaseAction {
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
 			} else {
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					List<String> taskIds = null;
 					if( StringUtils.isNotEmpty(  wrapIn.getTag() )) {
@@ -90,6 +100,42 @@ public class ActionListNextWithFilter extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							//添加一级子任务信息
+							subTasks = taskQueryService.listTaskWithParentId( wo.getId(), effectivePerson );
+							if( ListTools.isNotEmpty( subTasks )) {
+								wo.setSubTasks( WoSubTask.copier.copy( subTasks ));
+							}
+							
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}
 					
@@ -113,6 +159,12 @@ public class ActionListNextWithFilter extends BaseAction {
 	}
 	
 	public static class Wo extends Task {
+		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
+		@FieldDescribe("一级子任务")
+		private List<WoSubTask> subTasks = null;
 
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
@@ -125,6 +177,22 @@ public class ActionListNextWithFilter extends BaseAction {
 			this.tags = tags;
 		}
 		
+		public List<WoSubTask> getSubTasks() {
+			return subTasks;
+		}
+
+		public void setSubTasks(List<WoSubTask> subTasks) {
+			this.subTasks = subTasks;
+		}
+		
+		public WrapOutControl getControl() {
+			return control;
+		}
+
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
+		
 		private Long rank;
 
 		public Long getRank() {

+ 69 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionListPageWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -18,6 +20,8 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.assemble.control.jaxrs.task.ActionListWithTaskList.WoSubTask;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
@@ -39,6 +43,8 @@ public class ActionListPageWithFilter extends BaseAction {
 		Element element = null;
 		QueryFilter  queryFilter = null;
 		List<TaskTag> tags = null;
+		List<Task> subTasks = null;
+		WrapOutControl control = null;
 		
 		try {
 			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
@@ -64,7 +70,11 @@ public class ActionListPageWithFilter extends BaseAction {
 				resultObject = (ResultObject) element.getObjectValue();
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
-			} else {				
+			} else {	
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					List<String> taskIds = null;
 					if( StringUtils.isNotEmpty(  wrapIn.getTag() )) {
@@ -86,6 +96,42 @@ public class ActionListPageWithFilter extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							//添加一级子任务信息
+							subTasks = taskQueryService.listTaskWithParentId( wo.getId(), effectivePerson );
+							if( ListTools.isNotEmpty( subTasks )) {
+								wo.setSubTasks( WoSubTask.copier.copy( subTasks ));
+							}
+							
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}
 
@@ -113,6 +159,12 @@ public class ActionListPageWithFilter extends BaseAction {
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
 		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
+		@FieldDescribe("一级子任务")
+		private List<WoSubTask> subTasks = null;
+		
 		public List<WoTaskTag> getTags() {
 			return tags;
 		}
@@ -121,6 +173,22 @@ public class ActionListPageWithFilter extends BaseAction {
 			this.tags = tags;
 		}
 		
+		public List<WoSubTask> getSubTasks() {
+			return subTasks;
+		}
+
+		public void setSubTasks(List<WoSubTask> subTasks) {
+			this.subTasks = subTasks;
+		}
+		
+		public WrapOutControl getControl() {
+			return control;
+		}
+
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
+		
 		private Long rank;
 
 		public Long getRank() {

+ 79 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionListWithTaskList.java

@@ -7,6 +7,8 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.lang3.StringUtils;
 
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -17,6 +19,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 
@@ -34,6 +37,8 @@ public class ActionListWithTaskList extends BaseAction {
 		String cacheKey = null;
 		Element element = null;
 		List<TaskTag> tags = null;
+		List<Task> subTasks = null;
+		WrapOutControl control = null;
 		
 		if ( StringUtils.isEmpty( taskListId ) ) {
 			check = false;
@@ -50,6 +55,10 @@ public class ActionListWithTaskList extends BaseAction {
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
 			} else {
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					List<Task>  taskList = taskQueryService.listTaskWithTaskListId( projectId, taskListId, effectivePerson.getDistinguishedName() );
 					Long total = 0L;
@@ -62,6 +71,42 @@ public class ActionListWithTaskList extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							//添加一级子任务信息
+							subTasks = taskQueryService.listTaskWithParentId( wo.getId(), effectivePerson );
+							if( ListTools.isNotEmpty( subTasks )) {
+								wo.setSubTasks( WoSubTask.copier.copy( subTasks ));
+							}
+							
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}					
 					resultObject = new ResultObject( total, wos );
@@ -85,6 +130,12 @@ public class ActionListWithTaskList extends BaseAction {
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
 		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
+		@FieldDescribe("一级子任务")
+		private List<WoSubTask> subTasks = null;
+		
 		public List<WoTaskTag> getTags() {
 			return tags;
 		}
@@ -92,6 +143,23 @@ public class ActionListWithTaskList extends BaseAction {
 		public void setTags(List<WoTaskTag> tags) {
 			this.tags = tags;
 		}
+				
+		
+		public List<WoSubTask> getSubTasks() {
+			return subTasks;
+		}
+
+		public void setSubTasks(List<WoSubTask> subTasks) {
+			this.subTasks = subTasks;
+		}
+		
+		public WrapOutControl getControl() {
+			return control;
+		}
+
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
 		
 		private Long rank;
 
@@ -102,6 +170,7 @@ public class ActionListWithTaskList extends BaseAction {
 		public void setRank(Long rank) {
 			this.rank = rank;
 		}
+		
 
 		private static final long serialVersionUID = -5076990764713538973L;
 
@@ -120,6 +189,16 @@ public class ActionListWithTaskList extends BaseAction {
 		static WrapCopier<TaskTag, WoTaskTag> copier = WrapCopierFactory.wo( TaskTag.class, WoTaskTag.class, null, ListTools.toList(JpaObject.FieldsInvisible));		
 
 	}
+	
+	public static class WoSubTask extends Task {
+		
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static List<String> Excludes = new ArrayList<String>();
+
+		static WrapCopier<Task, WoSubTask> copier = WrapCopierFactory.wo( Task.class, WoSubTask.class, null, ListTools.toList(JpaObject.FieldsInvisible));		
+
+	}
 
 	public static class ResultObject {
 

+ 50 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewAllListNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -19,6 +21,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
@@ -42,6 +45,7 @@ public class ActionViewAllListNextWithFilter extends BaseAction {
 		Element element = null;
 		QueryFilter  queryFilter = null;
 		List<TaskTag> tags = null; 
+		WrapOutControl control = null;
 		
 		if ( StringUtils.isEmpty( projectId ) ) {
 			check = false;
@@ -78,7 +82,11 @@ public class ActionViewAllListNextWithFilter extends BaseAction {
 				resultObject = (ResultObject) element.getObjectValue();
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
-			} else {				
+			} else {	
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					
 					Long total = taskQueryService.countWithFilter( effectivePerson, queryFilter );
@@ -91,6 +99,36 @@ public class ActionViewAllListNextWithFilter extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}
 
@@ -252,6 +290,7 @@ public class ActionViewAllListNextWithFilter extends BaseAction {
 			this.executor = executor;
 		}
 		
+		
 		/**
 		 * 根据传入的查询参数,组织一个完整的QueryFilter对象
 		 * @return
@@ -310,6 +349,9 @@ public class ActionViewAllListNextWithFilter extends BaseAction {
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
 		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
 		public List<WoTaskTag> getTags() {
 			return tags;
 		}
@@ -327,7 +369,14 @@ public class ActionViewAllListNextWithFilter extends BaseAction {
 		public void setRank(Long rank) {
 			this.rank = rank;
 		}
+		
+		public WrapOutControl getControl() {
+			return control;
+		}
 
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
 		private static final long serialVersionUID = -5076990764713538973L;
 
 		public static List<String> Excludes = new ArrayList<String>();

+ 50 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewCompletedListNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -19,6 +21,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
@@ -42,6 +45,7 @@ public class ActionViewCompletedListNextWithFilter extends BaseAction {
 		Element element = null;
 		QueryFilter  queryFilter = null;
 		List<TaskTag> tags = null; 
+		WrapOutControl control = null;
 		
 		if ( StringUtils.isEmpty( projectId ) ) {
 			check = false;
@@ -79,7 +83,11 @@ public class ActionViewCompletedListNextWithFilter extends BaseAction {
 				resultObject = (ResultObject) element.getObjectValue();
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
-			} else {				
+			} else {
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					
 					Long total = taskQueryService.countWithFilter( effectivePerson, queryFilter );
@@ -92,6 +100,36 @@ public class ActionViewCompletedListNextWithFilter extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}
 
@@ -309,6 +347,9 @@ public class ActionViewCompletedListNextWithFilter extends BaseAction {
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
 		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
 		public List<WoTaskTag> getTags() {
 			return tags;
 		}
@@ -326,6 +367,14 @@ public class ActionViewCompletedListNextWithFilter extends BaseAction {
 		public void setRank(Long rank) {
 			this.rank = rank;
 		}
+		
+		public WrapOutControl getControl() {
+			return control;
+		}
+
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
 
 		private static final long serialVersionUID = -5076990764713538973L;
 

+ 50 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewMyExecutListNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -19,6 +21,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
@@ -42,6 +45,7 @@ public class ActionViewMyExecutListNextWithFilter extends BaseAction {
 		Element element = null;
 		QueryFilter  queryFilter = null;
 		List<TaskTag> tags = null; 
+		WrapOutControl control = null;
 		
 		if ( StringUtils.isEmpty( projectId ) ) {
 			check = false;
@@ -79,7 +83,11 @@ public class ActionViewMyExecutListNextWithFilter extends BaseAction {
 				resultObject = (ResultObject) element.getObjectValue();
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
-			} else {				
+			} else {	
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					
 					Long total = taskQueryService.countWithFilter( effectivePerson, queryFilter );
@@ -92,6 +100,36 @@ public class ActionViewMyExecutListNextWithFilter extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}
 
@@ -310,6 +348,9 @@ public class ActionViewMyExecutListNextWithFilter extends BaseAction {
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
 		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
 		public List<WoTaskTag> getTags() {
 			return tags;
 		}
@@ -327,6 +368,14 @@ public class ActionViewMyExecutListNextWithFilter extends BaseAction {
 		public void setRank(Long rank) {
 			this.rank = rank;
 		}
+		
+		public WrapOutControl getControl() {
+			return control;
+		}
+
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
 
 		private static final long serialVersionUID = -5076990764713538973L;
 

+ 49 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewOverTimeListNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -19,6 +21,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
@@ -42,6 +45,7 @@ public class ActionViewOverTimeListNextWithFilter extends BaseAction {
 		Element element = null;
 		QueryFilter  queryFilter = null;
 		List<TaskTag> tags = null; 
+		WrapOutControl control = null;
 		
 		if ( StringUtils.isEmpty( projectId ) ) {
 			check = false;
@@ -79,7 +83,11 @@ public class ActionViewOverTimeListNextWithFilter extends BaseAction {
 				resultObject = (ResultObject) element.getObjectValue();
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
-			} else {				
+			} else {		
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					
 					Long total = taskQueryService.countWithFilter( effectivePerson, queryFilter );
@@ -92,6 +100,36 @@ public class ActionViewOverTimeListNextWithFilter extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}
 
@@ -310,6 +348,9 @@ public class ActionViewOverTimeListNextWithFilter extends BaseAction {
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
 		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
 		public List<WoTaskTag> getTags() {
 			return tags;
 		}
@@ -328,6 +369,13 @@ public class ActionViewOverTimeListNextWithFilter extends BaseAction {
 			this.rank = rank;
 		}
 
+		public WrapOutControl getControl() {
+			return control;
+		}
+
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
 		private static final long serialVersionUID = -5076990764713538973L;
 
 		public static List<String> Excludes = new ArrayList<String>();

+ 50 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/ActionViewUncompletedListNextWithFilter.java

@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -19,6 +21,7 @@ import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskTag;
 import com.x.teamwork.core.entity.tools.filter.QueryFilter;
@@ -43,6 +46,7 @@ public class ActionViewUncompletedListNextWithFilter extends BaseAction {
 		Element element = null;
 		QueryFilter  queryFilter = null;
 		List<TaskTag> tags = null; 
+		WrapOutControl control = null;
 		
 		if ( StringUtils.isEmpty( projectId ) ) {
 			check = false;
@@ -80,7 +84,11 @@ public class ActionViewUncompletedListNextWithFilter extends BaseAction {
 				resultObject = (ResultObject) element.getObjectValue();
 				result.setCount( resultObject.getTotal() );
 				result.setData( resultObject.getWos() );
-			} else {				
+			} else {
+				Business business = null;
+				try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+					business = new Business(bc);
+				}
 				try {
 					
 					Long total = taskQueryService.countWithFilter( effectivePerson, queryFilter );
@@ -93,6 +101,36 @@ public class ActionViewUncompletedListNextWithFilter extends BaseAction {
 							if( ListTools.isNotEmpty( tags )) {
 								wo.setTags( WoTaskTag.copier.copy( tags ));
 							}
+							try {
+								control = new WrapOutControl();
+								if( business.isManager(effectivePerson) 
+										|| effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson() )
+										|| wo.getManageablePersonList().contains( effectivePerson.getDistinguishedName() )){
+									control.setDelete( true );
+									control.setEdit( true );
+									control.setSortable( true );
+									control.setChangeExecutor(true);
+								}else{
+									control.setDelete( false );
+									control.setEdit( false );
+									control.setSortable( false );
+									control.setChangeExecutor(false);
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getExecutor())){
+									control.setChangeExecutor( true );
+								}
+								if(effectivePerson.getDistinguishedName().equalsIgnoreCase( wo.getCreatorPerson())){
+									control.setFounder( true );
+								}else{
+									control.setFounder( false );
+								}
+								wo.setControl(control);
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new TaskQueryException(e, "根据指定flag查询工作任务权限信息时发生异常。flag:" + wo.getId());
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
 						}
 					}
 
@@ -310,6 +348,9 @@ public class ActionViewUncompletedListNextWithFilter extends BaseAction {
 		@FieldDescribe("任务标签")
 		private List<WoTaskTag> tags = null;
 		
+		@FieldDescribe("任务权限")
+		private WrapOutControl control = null;	
+		
 		public List<WoTaskTag> getTags() {
 			return tags;
 		}
@@ -328,6 +369,14 @@ public class ActionViewUncompletedListNextWithFilter extends BaseAction {
 			this.rank = rank;
 		}
 
+		public WrapOutControl getControl() {
+			return control;
+		}
+
+		public void setControl(WrapOutControl control) {
+			this.control = control;
+		}
+		
 		private static final long serialVersionUID = -5076990764713538973L;
 
 		public static List<String> Excludes = new ArrayList<String>();

+ 63 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/task/WrapOutControl.java

@@ -0,0 +1,63 @@
+package com.x.teamwork.assemble.control.jaxrs.task;
+
+import com.x.base.core.project.annotation.FieldDescribe;
+
+public class WrapOutControl {
+	
+	@FieldDescribe("是否可删除")
+	private Boolean delete = false;
+	
+	@FieldDescribe("是否可编辑")
+	private Boolean edit = false;
+	
+	@FieldDescribe("是否可排序")
+	private Boolean sortable = true;
+	
+	@FieldDescribe("是否可变更负责人")
+	private Boolean changeExecutor = false;
+	
+	@FieldDescribe("是否创始人")
+	private Boolean founder = false;
+	
+	public Boolean getDelete() {
+		return delete;
+	}
+
+	public void setDelete(Boolean delete) {
+		this.delete = delete;
+	}
+	
+	public Boolean getEdit() {
+		return edit;
+	}
+
+	public void setEdit(Boolean edit) {
+		this.edit = edit;
+	}
+	
+	public Boolean getSortable() {
+		return sortable;
+	}
+
+	public void setSortable(Boolean sortable) {
+		this.sortable = sortable;
+	}
+	
+	
+	public Boolean getChangeExecutor() {
+		return changeExecutor;
+	}
+
+	public void setChangeExecutor(Boolean changeExecutor) {
+		this.changeExecutor = changeExecutor;
+	}
+	
+	public Boolean getFounder() {
+		return founder;
+	}
+
+	public void setFounder(Boolean founder) {
+		this.founder = founder;
+	}
+	
+}

+ 108 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionDelete.java

@@ -0,0 +1,108 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoId;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.teamwork.core.entity.Dynamic;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.TaskListTemplate;
+
+public class ActionDelete extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionDelete.class);
+
+	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson, String flag) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		TaskListTemplate taskListTemplate = null;
+		Boolean check = true;
+		Wo wo = new Wo();
+
+		if ( StringUtils.isEmpty( flag ) ) {
+			check = false;
+			Exception exception = new TaskListTemplateFlagForQueryEmptyException();
+			result.error( exception );
+		}
+
+		if( Boolean.TRUE.equals( check ) ){
+			try {
+				taskListTemplate = taskListTemplateQueryService.get(flag);
+				if ( taskListTemplate == null) {
+					check = false;
+					Exception exception = new TaskListTemplateNotExistsException(flag);
+					result.error( exception );
+				}
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new TaskListTemplateQueryException(e, "根据指定flag查询项目模板对应的泳道信息对象时发生异常。flag:" + flag);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		
+		if( Boolean.TRUE.equals( check ) ){
+			try {
+				taskListTemplatePersistService.delete(flag, effectivePerson );
+				
+				// 更新缓存
+				ApplicationCache.notify( ProjectTemplate.class );
+				ApplicationCache.notify( TaskListTemplate.class );
+				
+				wo.setId( taskListTemplate.getId() );
+				
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new TaskListTemplateQueryException(e, "根据指定flag删除项目模板对应的泳道信息对象时发生异常。flag:" + flag);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		result.setData( wo );
+		return result;
+	}
+
+	public static class Wo extends WoId {
+		
+		@FieldDescribe("操作引起的动态内容")
+		List<WoDynamic> dynamics = new ArrayList<>();
+
+		public List<WoDynamic> getDynamics() {
+			return dynamics;
+		}
+
+		public void setDynamics(List<WoDynamic> dynamics) {
+			this.dynamics = dynamics;
+		}
+		
+	}
+	
+	public static class WoDynamic extends Dynamic{
+
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static WrapCopier<Dynamic, WoDynamic> copier = WrapCopierFactory.wo( Dynamic.class, WoDynamic.class, null, JpaObject.FieldsInvisible);
+		
+		private Long rank = 0L;
+
+		public Long getRank() {
+			return rank;
+		}
+
+		public void setRank(Long rank) {
+			this.rank = rank;
+		}		
+	}
+}

+ 87 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionGet.java

@@ -0,0 +1,87 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.TaskListTemplate;
+
+import net.sf.ehcache.Element;
+
+public class ActionGet extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionGet.class);
+
+	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson, String id ) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		Wo wo = null;
+		TaskListTemplate taskListTemplate = null;
+		Boolean check = true;
+
+		if ( StringUtils.isEmpty( id ) ) {
+			check = false;
+			Exception exception = new TaskListTemplateFlagForQueryEmptyException();
+			result.error( exception );
+		}
+
+		String cacheKey = ApplicationCache.concreteCacheKey( id ,effectivePerson);
+		Element element = taskListTemplateCache.get( cacheKey );
+
+		if ((null != element) && (null != element.getObjectValue())) {
+			wo = (Wo) element.getObjectValue();
+			result.setData( wo );
+		} else {
+			if( Boolean.TRUE.equals( check ) ){
+				try {
+					taskListTemplate = taskListTemplateQueryService.get( id );
+					if ( taskListTemplate == null) {
+						check = false;
+						Exception exception = new TaskListTemplateNotExistsException( id );
+						result.error( exception );
+					}
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new TaskListTemplateQueryException(e, "根据指定flag查询项目模板对应的泳道信息对象时发生异常。id:" + id );
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+			}
+			
+			if( Boolean.TRUE.equals( check ) ){
+				try {
+					wo = Wo.copier.copy( taskListTemplate );					
+					taskListTemplateCache.put(new Element(cacheKey, wo));
+					result.setData(wo);
+				} catch (Exception e) {
+					Exception exception = new TaskListTemplateQueryException(e, "将查询出来的项目模板对应的泳道信息对象转换为可输出的数据信息时发生异常。");
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+			}
+		}
+		return result;
+	}
+
+	public static class Wo extends TaskListTemplate {
+		
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static List<String> Excludes = new ArrayList<String>();
+
+		static WrapCopier<TaskListTemplate, Wo> copier = WrapCopierFactory.wo( TaskListTemplate.class, Wo.class, null, ListTools.toList(JpaObject.FieldsInvisible));		
+
+	}
+}

+ 81 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionList.java

@@ -0,0 +1,81 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.tools.SortTools;
+import com.x.teamwork.core.entity.ProjectGroup;
+
+import net.sf.ehcache.Element;
+
+public class ActionList extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionList.class);
+
+	@SuppressWarnings("unchecked")
+	protected ActionResult<List<Wo>> execute(HttpServletRequest request, EffectivePerson effectivePerson ) throws Exception {
+		ActionResult<List<Wo>> result = new ActionResult<>();
+		List<Wo> wos = null;
+		List<ProjectGroup> projectGroups = null;
+		Boolean check = true;
+
+		String cacheKey = ApplicationCache.concreteCacheKey( "list.my", effectivePerson.getDistinguishedName() );
+		/*Element element = projectGroupCache.get( cacheKey );
+		
+		if ((null != element) && (null != element.getObjectValue())) {
+			wos = (List<Wo>) element.getObjectValue();
+			result.setData( wos );
+		} else {
+			if( Boolean.TRUE.equals( check ) ){
+				try {
+					projectGroups = projectGroupQueryService.listGroupByPerson( effectivePerson.getDistinguishedName() );
+					if( ListTools.isNotEmpty( projectGroups )) {
+						wos = Wo.copier.copy( projectGroups );
+						
+						SortTools.asc( wos, "createTime");
+						
+						projectGroupCache.put(new Element(cacheKey, wos));
+						result.setData(wos);
+					}
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new ProjectTemplateQueryException(e, "根据用户拥有的项目组信息列表时发生异常。");
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+			}
+		}*/
+		return result;
+	}
+
+	public static class Wo extends ProjectGroup {
+		
+		private Long rank;
+
+		public Long getRank() {
+			return rank;
+		}
+
+		public void setRank(Long rank) {
+			this.rank = rank;
+		}
+
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static List<String> Excludes = new ArrayList<String>();
+
+		static WrapCopier<ProjectGroup, Wo> copier = WrapCopierFactory.wo( ProjectGroup.class, Wo.class, null, ListTools.toList(JpaObject.FieldsInvisible));
+
+	}
+}

+ 114 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionListWithFilter.java

@@ -0,0 +1,114 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.tools.SortTools;
+import com.x.teamwork.core.entity.ProjectGroup;
+
+import net.sf.ehcache.Element;
+
+public class ActionListWithFilter extends BaseAction {
+
+	private static  Logger logger = LoggerFactory.getLogger(ActionListWithFilter.class);
+
+	@SuppressWarnings("unchecked")
+	protected ActionResult<List<Wo>> execute(HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
+		ActionResult<List<Wo>> result = new ActionResult<>();
+		List<ProjectGroup> projectGroups = null;
+		List<Wo> wos = null;
+		Wi wi = null;
+		Boolean check = true;
+
+		try {
+			wi = this.convertToWrapIn( jsonElement, Wi.class );
+		} catch (Exception e) {
+			check = false;
+			Exception exception = new TaskListTemplateQueryException(e, "系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString() );
+			result.error(exception);
+			logger.error(e, effectivePerson, request, null);
+		}
+		
+		String cacheKey = ApplicationCache.concreteCacheKey( getStringListHeyx( wi.getIds()) );
+		/*Element element = projectGroupCache.get( cacheKey );
+
+		if ((null != element) && (null != element.getObjectValue())) {
+			wos = (List<Wo>) element.getObjectValue();
+			result.setData( wos );
+		} else {
+			if( Boolean.TRUE.equals( check ) ){
+				try {
+					projectGroups = projectGroupQueryService.list( wi.getIds() );
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new ProjectTemplateQueryException(e, "系统通过指定的ID列表查询项目组信息列表时发生异常。JSON:" + jsonElement.toString() );
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
+				}
+				
+			}
+			
+			if( Boolean.TRUE.equals( check ) ){
+				if( ListTools.isNotEmpty( projectGroups )) {
+					wos = Wo.copier.copy( projectGroups );					
+					SortTools.asc( wos, "createTime");					
+					projectGroupCache.put(new Element(cacheKey, wos));
+					result.setData(wos);
+				}	
+			}
+		}*/
+		return result;
+	}	
+
+	public static class Wi {
+
+		@FieldDescribe("项目组ID列表")
+		private List<String> ids;
+
+		public List<String> getIds() {
+			return ids;
+		}
+
+		public void setIds(List<String> ids) {
+			this.ids = ids;
+		}
+	}
+
+	public static class Wo extends ProjectGroup {
+		
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static List<String> Excludes = new ArrayList<String>();
+
+		static WrapCopier<ProjectGroup, Wo> copier = WrapCopierFactory.wo( ProjectGroup.class, Wo.class, null, ListTools.toList(JpaObject.FieldsInvisible));		
+
+	}
+	
+	private String getStringListHeyx( List<String> list ) {
+		StringBuffer content = new StringBuffer();
+		if( ListTools.isNotEmpty( list )) {
+			SortTools.asc( list );
+			for( String str : list ) {
+				content.append( str );
+			}
+			return DigestUtils.sha1Hex(content.toString() );
+		}
+		return "null";
+	}
+	
+}

+ 206 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/ActionSave.java

@@ -0,0 +1,206 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoId;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.teamwork.assemble.control.service.BatchOperationPersistService;
+import com.x.teamwork.assemble.control.service.BatchOperationProcessService;
+import com.x.teamwork.core.entity.Dynamic;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.TaskListTemplate;
+
+public class ActionSave extends BaseAction {
+
+	private static  Logger logger = LoggerFactory.getLogger(ActionSave.class);
+
+	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		TaskListTemplate template = null;
+		TaskListTemplate old_template = null;
+		Wi wi = null;
+		Wo wo = new Wo();
+		Boolean check = true;
+
+		try {
+			wi = this.convertToWrapIn( jsonElement, Wi.class );
+		} catch (Exception e) {
+			check = false;
+			Exception exception = new TaskListTemplatePersistException(e, "系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString());
+			result.error(exception);
+			logger.error(e, effectivePerson, request, null);
+		}
+		
+		
+		if( Boolean.TRUE.equals( check ) ){
+			old_template = taskListTemplateQueryService.get( wi.getId() );
+		}
+		
+		if( Boolean.TRUE.equals( check ) ){
+			try {
+				template = taskListTemplatePersistService.save( Wi.copier.copy(wi), effectivePerson );
+				
+				// 更新缓存
+				ApplicationCache.notify( ProjectTemplate.class );
+				ApplicationCache.notify( TaskListTemplate.class );			
+				
+				wo.setId( template.getId() );
+				
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new TaskListTemplatePersistException(e, "项目信息保存时发生异常。");
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		
+		if( Boolean.TRUE.equals( check ) ){
+			try {					
+				new BatchOperationPersistService().addOperation( 
+						BatchOperationProcessService.OPT_OBJ_PROJECT, 
+						BatchOperationProcessService.OPT_TYPE_PERMISSION,  template.getId(),  template.getId(), "刷新文档权限:ID=" +   template.getId() );
+			} catch (Exception e) {
+				logger.error(e, effectivePerson, request, null);
+			}	
+		}
+		
+		result.setData( wo );
+		return result;
+	}	
+
+	public static class Wi {
+		
+		@FieldDescribe("数据库主键,自动生成,非必填.")
+		private String id;
+		
+		@FieldDescribe("工作任务列表(泳道)名称")
+		private String name;
+		
+		@FieldDescribe("所属模板ID.")
+		private String projectTemplate;
+
+		@FieldDescribe("排序号,非必填")
+		private Integer order;
+
+		@FieldDescribe("列表描述,非必填")
+		private String memo;
+
+		@FieldDescribe("创建者,非必填")
+		private String creatorPerson = null;
+
+		private Boolean deleted = false;
+		
+		public static WrapCopier<Wi, TaskListTemplate> copier = WrapCopierFactory.wi( Wi.class, TaskListTemplate.class, null, null );
+		
+		private String owner = null;
+		
+		public String getId() {
+			return id;
+		}
+
+		public void setId(String id) {
+			this.id = id;
+		}
+
+		public String getProjectTemplate() {
+			return projectTemplate;
+		}
+
+		public void setProjectTemplate(String projectTemplate) {
+			this.projectTemplate = projectTemplate;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public Integer getOrder() {
+			return order;
+		}
+
+		public void setOrder(Integer order) {
+			this.order = order;
+		}
+
+		public String getMemo() {
+			return memo;
+		}
+
+		public void setMemo(String memo) {
+			this.memo = memo;
+		}
+
+		public String getCreatorPerson() {
+			return creatorPerson;
+		}
+
+		public void setCreatorPerson(String creatorPerson) {
+			this.creatorPerson = creatorPerson;
+		}
+		
+		public String getOwner() {
+			return owner;
+		}
+
+		public void setOwner(String owner) {
+			this.owner = owner;
+		}
+		public Boolean getDeleted() {
+			return deleted;
+		}
+
+		public void setDeleted(Boolean deleted) {
+			this.deleted = deleted;
+		}
+
+	}
+
+public static class Wo extends WoId {
+		
+		@FieldDescribe("操作引起的动态内容")
+		List<WoDynamic> dynamics = new ArrayList<>();
+
+		public List<WoDynamic> getDynamics() {
+			return dynamics;
+		}
+
+		public void setDynamics(List<WoDynamic> dynamics) {
+			this.dynamics = dynamics;
+		}
+		
+	}
+	
+	public static class WoDynamic extends Dynamic{
+
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static WrapCopier<Dynamic, WoDynamic> copier = WrapCopierFactory.wo( Dynamic.class, WoDynamic.class, null, JpaObject.FieldsInvisible);
+		
+		private Long rank = 0L;
+
+		public Long getRank() {
+			return rank;
+		}
+
+		public void setRank(Long rank) {
+			this.rank = rank;
+		}		
+	}
+	
+}

+ 25 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/BaseAction.java

@@ -0,0 +1,25 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.teamwork.assemble.control.service.DynamicPersistService;
+import com.x.teamwork.assemble.control.service.SystemConfigQueryService;
+import com.x.teamwork.assemble.control.service.TaskListTemplatePersistService;
+import com.x.teamwork.assemble.control.service.TaskListTemplateQueryService;
+import com.x.teamwork.core.entity.TaskListTemplate;
+
+import net.sf.ehcache.Ehcache;
+
+public class BaseAction extends StandardJaxrsAction {
+
+	protected Ehcache taskListTemplateCache = ApplicationCache.instance().getCache( TaskListTemplate.class );
+	
+	protected 	TaskListTemplateQueryService taskListTemplateQueryService = new TaskListTemplateQueryService();
+	
+	protected 	TaskListTemplatePersistService taskListTemplatePersistService = new TaskListTemplatePersistService();
+	
+	protected 	DynamicPersistService dynamicPersistService = new DynamicPersistService();
+	
+	protected 	SystemConfigQueryService systemConfigQueryService = new SystemConfigQueryService();
+	
+}

+ 92 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplateAction.java

@@ -0,0 +1,92 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.JaxrsDescribe;
+import com.x.base.core.project.annotation.JaxrsMethodDescribe;
+import com.x.base.core.project.annotation.JaxrsParameterDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.http.HttpMediaType;
+import com.x.base.core.project.jaxrs.ResponseFactory;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+
+@Path("taskListTemplate")
+@JaxrsDescribe("项目模板对应的泳道信息管理")
+public class TaskListTemplateAction extends StandardJaxrsAction {
+
+	private Logger logger = LoggerFactory.getLogger(TaskListTemplateAction.class);
+	
+	@JaxrsMethodDescribe(value = "根据ID查询项目模板对应的泳道信息.", action = ActionGet.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void get(@Suspended final AsyncResponse asyncResponse, 
+			@Context HttpServletRequest request, 
+			@JaxrsParameterDescribe("项目组ID") @PathParam("id") String id ) {
+		ActionResult<ActionGet.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionGet().execute( request, effectivePerson, id );
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+	
+	@JaxrsMethodDescribe(value = "创建或者更新一个项目模板对应的泳道信息.", action = ActionSave.class)
+	@POST
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void save(@Suspended final AsyncResponse asyncResponse, 
+			@Context HttpServletRequest request, 
+			@JaxrsParameterDescribe("需要保存的项目模板对应的泳道信息") JsonElement jsonElement ) {
+		ActionResult<ActionSave.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionSave().execute(request, effectivePerson, jsonElement);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+	
+	@JaxrsMethodDescribe(value = "根据标识删除项目模板对应的泳道信息.", action = ActionDelete.class)
+	@DELETE
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void delete(@Suspended final AsyncResponse asyncResponse, 
+			@Context HttpServletRequest request, 
+			@JaxrsParameterDescribe("标识") @PathParam("id") String id ) {
+		ActionResult<ActionDelete.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionDelete().execute(request, effectivePerson, id);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+}

+ 12 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplateFlagForQueryEmptyException.java

@@ -0,0 +1,12 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import com.x.base.core.project.exception.PromptException;
+
+class TaskListTemplateFlagForQueryEmptyException extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	TaskListTemplateFlagForQueryEmptyException() {
+		super("查询的项目模板对应的泳道信息ID为空,无法继续查询数据。" );
+	}
+}

+ 12 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplateNotExistsException.java

@@ -0,0 +1,12 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import com.x.base.core.project.exception.PromptException;
+
+class TaskListTemplateNotExistsException extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	TaskListTemplateNotExistsException( String id ) {
+		super("指定ID的项目模板对应的泳道信息不存在。ID:" + id );
+	}
+}

+ 20 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplatePersistException.java

@@ -0,0 +1,20 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import com.x.base.core.project.exception.PromptException;
+
+class TaskListTemplatePersistException extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	TaskListTemplatePersistException( Throwable e ) {
+		super("系统在保存项目模板对应的泳道信息时发生异常。" , e );
+	}
+	
+	TaskListTemplatePersistException( Throwable e, String message ) {
+		super("系统在保存项目模板对应的泳道信息时发生异常。Message:" + message, e );
+	}
+	
+	TaskListTemplatePersistException( String message ) {
+		super("系统在保存项目模板对应的泳道信息时发生异常。Message:" + message );
+	}
+}

+ 16 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/jaxrs/taskListTemplate/TaskListTemplateQueryException.java

@@ -0,0 +1,16 @@
+package com.x.teamwork.assemble.control.jaxrs.taskListTemplate;
+
+import com.x.base.core.project.exception.PromptException;
+
+class TaskListTemplateQueryException extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	TaskListTemplateQueryException( Throwable e ) {
+		super("系统在查询项目模板对应的泳道信息时发生异常。" , e );
+	}
+	
+	TaskListTemplateQueryException( Throwable e, String message ) {
+		super("系统在查询项目模板对应的泳道信息时发生异常。Message:" + message, e );
+	}
+}

+ 32 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/DynamicPersistService.java

@@ -15,6 +15,7 @@ import com.x.teamwork.core.entity.Dynamic;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.ProjectExtFieldRele;
 import com.x.teamwork.core.entity.ProjectGroup;
+import com.x.teamwork.core.entity.ProjectTemplate;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskDetail;
 import com.x.teamwork.core.entity.TaskList;
@@ -174,6 +175,37 @@ public class DynamicPersistService {
 		return dynamic;
 	}
 	
+	/**
+	 * 保存项目模板创建或者更新动态信息
+	 * @param old_object
+	 * @param object
+	 * @param effectivePerson
+	 * @param content
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Dynamic> projectTemplateSaveDynamic( ProjectTemplate old_object, ProjectTemplate object, EffectivePerson effectivePerson, String content ) throws Exception {
+		if ( object == null) {
+			throw new Exception("object is null.");
+		}
+		if ( effectivePerson == null ) {
+			throw new Exception("effectivePerson is null.");
+		}
+		List<Dynamic> dynamics = dynamicService.getProjectTemplateSaveDynamic( old_object, object, effectivePerson );	
+		List<Dynamic> result = new ArrayList<>();
+		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {			
+			if( ListTools.isNotEmpty( dynamics )) {
+				 for( Dynamic dynamic : dynamics ) {
+					 dynamic = dynamicService.save( emc, dynamic, content );
+					 result.add( dynamic );
+				 }
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+		return result;
+	}
+	
 	/**
 	 * 保存动态信息
 	 * @param object_old
@@ -307,7 +339,6 @@ public class DynamicPersistService {
 			throw new Exception("effectivePerson is null.");
 		}
 		List<Dynamic> result = new ArrayList<>();
-		List<Dynamic> dynamics = null;
 
 		//记录一个添加子任务转换的动态信息
 		result.add(dynamicService.getTaskTransformDynamic( parentTask, subTask, effectivePerson));

+ 65 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/DynamicService.java

@@ -21,6 +21,7 @@ import com.x.teamwork.core.entity.DynamicDetail;
 import com.x.teamwork.core.entity.Project;
 import com.x.teamwork.core.entity.ProjectExtFieldRele;
 import com.x.teamwork.core.entity.ProjectGroup;
+import com.x.teamwork.core.entity.ProjectTemplate;
 import com.x.teamwork.core.entity.Task;
 import com.x.teamwork.core.entity.TaskDetail;
 import com.x.teamwork.core.entity.TaskList;
@@ -239,6 +240,29 @@ class DynamicService {
 		return dynamic;
 	}
 	
+	/**
+	 * 根据参数组织一个新的ProjectTemplate操作动态信息
+	 * @param objectType
+	 * @param title
+	 * @param description
+	 * @param viewUrl
+	 * @param optType
+	 * @param object
+	 * @param effectivePerson
+	 * @param personal
+	 * @return
+	 */
+	private Dynamic composeNewDynamic( String objectType, String title, String description, String viewUrl, String optType, ProjectTemplate object,  EffectivePerson effectivePerson, Boolean personal) {
+		Dynamic dynamic = composeNewSimpleDynamic(objectType, title, description, viewUrl, optType, effectivePerson, personal );
+		dynamic.setProjectId( object.getId() );
+		dynamic.setProjectTitle( object.getTitle() );
+		dynamic.setTaskId( ""  );
+		dynamic.setTaskTitle( null );
+		dynamic.setBundle( object.getId() );
+		dynamic.setTarget( object.getOwner() );
+		return dynamic;
+	}
+	
 	/**
 	 * 根据参数组织一个新的ProjectExtFieldRele操作动态信息
 	 * @param objectType
@@ -562,6 +586,47 @@ class DynamicService {
 		return composeNewDynamic( objectType, title, description, viewUrl, optType, object, effectivePerson, false );
 	}
 	
+	/**
+	 * 保存项目模板创建或者更新动态信息
+	 * @param object_old
+	 * @param object
+	 * @param effectivePerson
+	 * @return
+	 */
+	protected List<Dynamic> getProjectTemplateSaveDynamic( ProjectTemplate object_old, ProjectTemplate object, EffectivePerson effectivePerson ) {
+		List<Dynamic> dynamics = new ArrayList<>();
+		String objectType =  "PROJECTTEMPLATE";
+		String viewUrl = null;
+		String title =  null;
+		String optType = "UPDATE_PROJECTTEMPLATE";
+		String description = null;
+		if( object_old != null ) {
+			if( !object_old.getTitle().equalsIgnoreCase( object.getTitle() )) { //变更了名称
+				title =  "项目模板信息标题变更";
+				optType = "UPDATE_TITLE";
+				description = effectivePerson.getName() + "变更了项目模板信息的标题为:" + object.getTitle();
+				dynamics.add( composeNewDynamic( objectType, title, description, viewUrl, optType, object, effectivePerson, false ) ); 
+			}
+			if( !object_old.getOwner().equalsIgnoreCase( object.getOwner() )) {//变更了所有人
+				title =  "项目模板所有人变更";
+				optType = "UPDATE_EXECUTOR";
+				if( StringUtils.isNotEmpty(  object.getOwner() ) &&  object.getOwner().split( "@" ).length > 1 ) {
+					description = effectivePerson.getName() + "变更了项目模板所有人为:" + object.getOwner().split( "@" )[0] + "。";					
+				}else {
+					description = effectivePerson.getName() + "变更了项目模板所有人为:" + object.getOwner() + "。";
+				}
+				
+				dynamics.add( composeNewDynamic( objectType, title, description, viewUrl, optType, object, effectivePerson, false ) );
+			}
+		}else {//创建项目
+			title =  "项目模板信息创建";
+			optType = "CREATE";
+			description = effectivePerson.getName() + "创建了新的项目模板信息:" + object.getTitle() + "。";
+			dynamics.add( composeNewDynamic( objectType, title, description, viewUrl, optType, object, effectivePerson, false ) );
+		}
+		return dynamics;
+	}
+	
 	/**
 	 * 组织项目工作任务列表保存操作动态
 	 * @param object_old

+ 26 - 1
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/ProjectQueryService.java

@@ -293,7 +293,7 @@ public class ProjectQueryService {
 	}
 
 	/**
-	 * 根据条件查询项目ID列表,最大查询2000条
+	 * 根据条件查询项目ID列表,最大查询2000条,查询未删除
 	 * @param effectivePerson
 	 * @param i
 	 * @param queryFilter
@@ -318,4 +318,29 @@ public class ProjectQueryService {
 			throw e;
 		}
 	}	
+	/**
+	 * 根据条件查询项目ID列表,最大查询2000条
+	 * @param effectivePerson
+	 * @param i
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception 
+	 */
+	public List<String> listAllProjectIds(EffectivePerson effectivePerson, int maxCount, QueryFilter queryFilter) throws Exception {
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		String personName = effectivePerson.getDistinguishedName();
+		if( maxCount ==  0) {
+			maxCount = 1000;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson( personName );
+			identityNames = userManagerService.listIdentitiesWithPerson( personName );
+			return projectService.listAllViewableProjectIds( emc, maxCount, personName,  identityNames, unitNames, groupNames, queryFilter );
+		} catch (Exception e) {
+			throw e;
+		}
+	}	
 }

+ 146 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/ProjectTemplatePersistService.java

@@ -0,0 +1,146 @@
+package com.x.teamwork.assemble.control.service;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.teamwork.assemble.common.date.DateOperation;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.ProjectTemplate;
+
+/**
+ * 对项目信息查询的服务
+ * 
+ * @author O2LEE
+ */
+public class ProjectTemplatePersistService {
+
+	private ProjectTemplateService projectTemplateService = new ProjectTemplateService();
+	private UserManagerService userManagerService = new UserManagerService();
+	
+	public void delete( String flag, EffectivePerson currentPerson ) throws Exception {
+		if ( StringUtils.isEmpty( flag )) {
+			throw new Exception("flag is empty.");
+		}
+		Boolean hasDeletePermission = false;
+		Business business = null;
+		try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+			business = new Business(bc);
+		}
+		if( business.isManager(currentPerson) ) {
+			hasDeletePermission = true;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ProjectTemplate projectTemplate = projectTemplateService.get(emc, flag);
+			//管理员可以删除,创建者可以删除
+			if( !hasDeletePermission ) {
+				//看看是不是项目创建者
+				if( projectTemplate.getOwner().equalsIgnoreCase( currentPerson.getDistinguishedName() )) {
+					hasDeletePermission = true;
+				}
+			}
+			if( !hasDeletePermission ) {
+				throw new Exception("projectTemplate delete permission denied.");
+			}else {
+				projectTemplateService.delete( emc, flag );
+			}			
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	public ProjectTemplate save( ProjectTemplate project, EffectivePerson effectivePerson ) throws Exception {
+		if ( project == null) {
+			throw new Exception("project is null.");
+		}
+		if( StringUtils.isEmpty( project.getTitle() )) {
+			project.setTitle("无标题项目("+ DateOperation.getNowDateTime() +")");
+		}	
+		if( project.getTitle().length() > 70 ) {
+			project.setTitle( project.getTitle().substring(0, 70) + "..." );
+		}
+		if( StringUtils.isEmpty( project.getOwner()) ) {
+			project.setOwner(effectivePerson.getDistinguishedName());
+		}
+
+		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {			
+			project = projectTemplateService.save( emc, project );			
+		} catch (Exception e) {
+			throw e;
+		}
+		return project;
+	}
+	
+	/**
+	 * 模板创建泳道
+	 * @param id
+	 * @param effectivePerson
+	 * @return
+	 * @throws Exception 
+	 */
+	public void createTaskList( ProjectTemplate template ,String person) throws Exception {
+		if ( template == null) {
+			throw new Exception("ProjectTemplate is empty!");
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			projectTemplateService.createDefaultTaskListForProjectTemplate(emc, person , template);
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	/**
+	 * 保存或者更新项目的图标信息
+	 * @param projectId
+	 * @param icon
+	 * @throws Exception
+	 */
+	public void saveProjectIcon( String projectId, String icon ) throws Exception {
+		if ( StringUtils.isEmpty( projectId )) {
+			throw new Exception("projectId is empty!");
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Project project = emc.find( projectId, Project.class );
+			if( project == null ) {
+				throw new Exception("Project not exists.id:" + projectId );
+			}else {
+				emc.beginTransaction( Project.class );
+				if( StringUtils.isEmpty( icon )) {
+					project.setIcon( null );
+				}else {
+					project.setIcon(icon);
+				}
+				emc.check( project, CheckPersistType.all );	
+				emc.commit();
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	/**
+	 * 查询用户是否拥有创建项目的权限
+	 * 根据配置的权限来确定项目创建权限
+	 * @param effectivePerson
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean checkPermissionForPersist( EffectivePerson effectivePerson, String project_creator_config ) throws Exception {
+		//根据配置为全员可以创建项目
+		if( "ALL".equalsIgnoreCase( project_creator_config )) {
+			return true;
+		}
+		//系统管理员可以创建项目
+		if( effectivePerson.isManager() ) {
+			return true;
+		}
+		//工作任务系统管理员可以创建项目
+		if( userManagerService.isHasPlatformRole( effectivePerson.getDistinguishedName(), "TeamWorkManager" )) {
+			return true;
+		}
+		return false;
+	}	
+}

+ 347 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/ProjectTemplateQueryService.java

@@ -0,0 +1,347 @@
+package com.x.teamwork.assemble.control.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.ProjectDetail;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.tools.filter.QueryFilter;
+import com.x.teamwork.core.entity.tools.filter.term.EqualsTerm;
+import com.x.teamwork.core.entity.tools.filter.term.InTerm;
+
+/**
+ * 对项目信息查询的服务
+ * 
+ * @author O2LEE
+ */
+public class ProjectTemplateQueryService {
+
+	private ProjectTemplateService projectTemplateService = new ProjectTemplateService();
+	private UserManagerService userManagerService = new UserManagerService();
+	
+	/**
+	 * 根据项目的标识查询项目信息
+	 * @param id
+	 * @return
+	 * @throws Exception
+	 */
+	public ProjectTemplate get( String id ) throws Exception {
+		if ( StringUtils.isEmpty( id )) {
+			return null;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return projectTemplateService.get(emc, id );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	public ProjectDetail getDetail(String id) throws Exception {
+		if ( StringUtils.isEmpty( id )) {
+			return null;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return projectTemplateService.getDetail(emc, id);
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	public String getDescription(String id) throws Exception {
+		if ( StringUtils.isEmpty( id )) {
+			return null;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ProjectDetail detail = projectTemplateService.getDetail(emc, id );
+			if( detail != null ) {
+				return detail.getDescription();
+			}else {
+				return "";
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	/**
+	 * 根据ID列表查询项目信息列表
+	 * @param ids
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> list(List<String> ids) throws Exception {
+		if (ListTools.isEmpty( ids )) {
+			return null;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return emc.list( Project.class,  ids );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	public List<String> listAllProjectIds() throws Exception {		
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return projectTemplateService.listAllProjectIds( emc );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	/**
+	 * 根据过滤条件查询符合要求的项目信息列表
+	 * @param effectivePerson
+	 * @param pageSize
+	 * @param pageNum
+	 * @param orderField
+	 * @param orderType
+	 * @param group  项目分组
+	 * @param title
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> listWithProjectIdsFilter( Integer pageSize, Integer pageNum, String orderField, String orderType, List<String> projectIds ) throws Exception {
+		List<Project> projectList = null;
+		List<Project> result = new ArrayList<>();
+		Integer maxCount = 20;
+		Integer startNumber = 0;		
+		
+		if( pageNum == 0 ) { pageNum = 1; }
+		if( pageSize == 0 ) { pageSize = 20; }
+		maxCount = pageSize * pageNum;
+		startNumber = pageSize * ( pageNum -1 );
+		
+		if( StringUtils.isEmpty( orderField ) ) { 
+			orderField = "createTime";
+		}
+		if( StringUtils.isEmpty( orderType ) ) { 
+			orderType = "desc";
+		}
+		QueryFilter queryFilter = new QueryFilter();
+		queryFilter.addInTerm( new InTerm("id", new ArrayList<>(projectIds) ));
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			
+			projectList = projectTemplateService.listWithFilter( emc, maxCount, orderField, orderType, null, null, null, null, queryFilter );
+			
+			if( ListTools.isNotEmpty( projectList )) {
+				for( int i = 0; i<projectList.size(); i++ ) {
+					if( i >= startNumber ) {
+						result.add( projectList.get( i ));
+					}
+				}
+			}			
+		} catch (Exception e) {
+			throw e;
+		}
+		return result;
+	}	
+	
+	/**
+	 * 根据项目ID列表查询项目信息列表,根据上一条的sequnce查询指定数量的信息
+	 * @param pageSize
+	 * @param lastId
+	 * @param orderField
+	 * @param orderType
+	 * @param projectIds
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> listWithProjectIdFilter( Integer pageSize, String lastId, String orderField, String orderType, List<String> projectIds ) throws Exception {
+		Project project = null;
+		if( pageSize == 0 ) { pageSize = 20; }
+		if( StringUtils.isEmpty( orderField ) ) { 
+			orderField = "createTime";
+		}
+		if( StringUtils.isEmpty( orderType ) ) { 
+			orderType = "desc";
+		}
+		QueryFilter queryFilter = new QueryFilter();
+		queryFilter.addInTerm( new InTerm("id", new ArrayList<>(projectIds) ));
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			if( lastId != null ) {
+				project = emc.find( lastId, Project.class );
+			}
+			if( project != null ) {
+				return projectTemplateService.listWithFilter(emc, pageSize, project.getSequence(), orderField, orderType, null, null, null, null, queryFilter );
+			}else {
+				return projectTemplateService.listWithFilter(emc, pageSize, null, orderField, orderType, null, null, null, null, queryFilter );
+			}	
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	/**
+	 * 判断用户是否为指定项目的管理员
+	 * @param projectId
+	 * @param distinguishedName
+	 * @return
+	 * @throws Exception 
+	 */
+	public Boolean isProjectManager(String projectId, String distinguishedName) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Project project = emc.find( projectId, Project.class );
+			if( ListTools.isNotEmpty( project.getManageablePersonList() )){
+				if( distinguishedName.equalsIgnoreCase( project.getCreatorPerson() )) {
+					return true;
+				}
+				if( distinguishedName.equalsIgnoreCase( project.getExecutor() )) {
+					return true;
+				}
+				if( project.getManageablePersonList().contains( distinguishedName )) {
+					return true;
+				}
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+		return false;
+	}
+
+	/**
+	 * 判断用户是项目参与者
+	 * @param projectId
+	 * @param distinguishedName
+	 * @return
+	 * @throws Exception 
+	 */
+	public Boolean isProjectParticipant( String projectId, String personName ) throws Exception {		
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson(personName);
+			identityNames = userManagerService.listIdentitiesWithPerson(personName);
+			
+			Project project = emc.find( projectId, Project.class );
+
+			if( project.getParticipantPersonList().contains( personName )) {
+				return true;
+			}
+			project.getParticipantIdentityList().retainAll( identityNames );
+			if( ListTools.isNotEmpty( project.getParticipantIdentityList() )) {
+				return true;
+			}
+			project.getParticipantUnitList().retainAll( unitNames );
+			if( ListTools.isNotEmpty( project.getParticipantUnitList() )) {
+				return true;
+			}
+			project.getParticipantGroupList().retainAll( groupNames );
+			if( ListTools.isNotEmpty( project.getParticipantGroupList() )) {
+				return true;
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+		return false;
+	}
+	
+	/**
+	 * 判断用户是否拥有指定项目的访问权限
+	 * @param appId
+	 * @param distinguishedName
+	 * @return
+	 * @throws Exception 
+	 */
+	public Boolean isProjectViewer(String appId, String personName ) throws Exception {
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson(personName);
+			identityNames = userManagerService.listIdentitiesWithPerson(personName);
+			
+			Project project = emc.find( appId, Project.class );
+			if( personName.equalsIgnoreCase( project.getCreatorPerson() )) {
+				return true;
+			}
+			if( personName.equalsIgnoreCase( project.getExecutor() )) {
+				return true;
+			}	
+			if( project.getManageablePersonList().contains( personName )) {
+				return true;
+			}				
+			if( project.getParticipantPersonList().contains( personName )) {
+				return true;
+			}
+			project.getParticipantIdentityList().retainAll( identityNames );
+			if( ListTools.isNotEmpty( project.getParticipantIdentityList() )) {
+				return true;
+			}
+			project.getParticipantUnitList().retainAll( unitNames );
+			if( ListTools.isNotEmpty( project.getParticipantUnitList() )) {
+				return true;
+			}
+			project.getParticipantGroupList().retainAll( groupNames );
+			if( ListTools.isNotEmpty( project.getParticipantGroupList() )) {
+				return true;
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+		return false;
+	}
+
+	/**
+	 * 根据条件查询项目ID列表,最大查询2000条,查询未删除
+	 * @param effectivePerson
+	 * @param i
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception 
+	 */
+	public List<String> listAllViewableProjectIds(EffectivePerson effectivePerson, int maxCount, QueryFilter queryFilter) throws Exception {
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		String personName = effectivePerson.getDistinguishedName();
+		if( maxCount ==  0) {
+			maxCount = 1000;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson( personName );
+			identityNames = userManagerService.listIdentitiesWithPerson( personName );
+			queryFilter.addEqualsTerm( new EqualsTerm( "deleted", false ) );
+			return projectTemplateService.listAllViewableProjectIds( emc, maxCount, personName,  identityNames, unitNames, groupNames, queryFilter );
+		} catch (Exception e) {
+			throw e;
+		}
+	}	
+	/**
+	 * 根据条件查询项目ID列表,最大查询2000条
+	 * @param effectivePerson
+	 * @param i
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception 
+	 */
+	public List<String> listAllProjectIds(EffectivePerson effectivePerson, int maxCount, QueryFilter queryFilter) throws Exception {
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		String personName = effectivePerson.getDistinguishedName();
+		if( maxCount ==  0) {
+			maxCount = 1000;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson( personName );
+			identityNames = userManagerService.listIdentitiesWithPerson( personName );
+			return projectTemplateService.listAllViewableProjectIds( emc, maxCount, personName,  identityNames, unitNames, groupNames, queryFilter );
+		} catch (Exception e) {
+			throw e;
+		}
+	}	
+}

+ 290 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/ProjectTemplateService.java

@@ -0,0 +1,290 @@
+package com.x.teamwork.assemble.control.service;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.entity.annotation.CheckRemoveType;
+import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.ProjectDetail;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.Review;
+import com.x.teamwork.core.entity.Task;
+import com.x.teamwork.core.entity.TaskDetail;
+import com.x.teamwork.core.entity.TaskGroupRele;
+import com.x.teamwork.core.entity.TaskList;
+import com.x.teamwork.core.entity.TaskListRele;
+import com.x.teamwork.core.entity.TaskListTemplate;
+import com.x.teamwork.core.entity.tools.filter.QueryFilter;
+
+class ProjectTemplateService {
+
+	/**
+	 * 根据项目的标识查询项目的信息
+	 * @param emc
+	 * @param flag  主要是ID
+	 * @return
+	 * @throws Exception 
+	 */
+	protected ProjectTemplate get(EntityManagerContainer emc, String flag) throws Exception {
+		Business business = new Business( emc );
+		return business.projectTemplateFactory().get( flag );
+	}
+	
+	protected ProjectDetail getDetail(EntityManagerContainer emc, String id) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().getDetail( id );
+	}
+	
+	/**
+	 * 根据过滤条件查询符合要求的项目信息列表
+	 * @param emc
+	 * @param maxCount
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param group  项目分组
+	 * @param title
+	 * @return
+	 * @throws Exception
+	 */
+	protected List<Project> listWithFilter( EntityManagerContainer emc, Integer maxCount, String orderField, String orderType, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter ) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().listWithFilter(maxCount, orderField, orderType, personName, identityNames, unitNames, groupNames, queryFilter);
+	}
+	
+	/**
+	 * 根据条件查询符合条件的项目信息ID,根据上一条的sequnce查询指定数量的信息
+	 * @param emc
+	 * @param maxCount
+	 * @param sequnce
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param group   项目分组
+	 * @param title
+	 * @return
+	 * @throws Exception
+	 */
+	protected List<Project> listWithFilter( EntityManagerContainer emc, Integer maxCount, String sequnce, String orderField, String orderType, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter ) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().listWithFilter(maxCount, sequnce, orderField, orderType, personName, identityNames, unitNames, groupNames, queryFilter);
+	}
+
+	/**
+	 * 向数据库持久化项目信息
+	 * @param emc
+	 * @param projectDetail 
+	 * @param project
+	 * @return
+	 * @throws Exception 
+	 */
+	protected ProjectTemplate save( EntityManagerContainer emc, ProjectTemplate object) throws Exception {
+		ProjectTemplate projectTemplate = null;
+		if( StringUtils.isEmpty( object.getId() )  ){
+			object.setId( Project.createId() );
+		}
+		
+		projectTemplate = emc.find( object.getId(), ProjectTemplate.class );
+		
+		emc.beginTransaction( Project.class );
+		emc.beginTransaction( ProjectDetail.class );
+		
+		if( projectTemplate == null ){ // 保存一个新的对象
+			projectTemplate = new ProjectTemplate();
+			object.copyTo( projectTemplate );
+			if( StringUtils.isNotEmpty( object.getId() ) ){
+				projectTemplate.setId( object.getId() );
+			}
+			emc.persist( projectTemplate, CheckPersistType.all);
+		}else{ //对象已经存在,更新对象信息
+			if( StringUtils.isNotEmpty( projectTemplate.getOwner() )) {
+				object.setOwner( projectTemplate.getOwner() );
+			}
+			object.copyTo( projectTemplate, JpaObject.FieldsUnmodify  );
+			emc.check( projectTemplate, CheckPersistType.all );	
+		}
+		emc.commit();
+		return projectTemplate;
+	}
+
+	/**
+	 * 根据项目模板标识删除项目模板信息
+	 * @param emc
+	 * @param id
+	 * @throws Exception 
+	 */
+	protected void delete(EntityManagerContainer emc, String id ) throws Exception {
+		Business business = new Business( emc );
+		ProjectTemplate projectTemplate = emc.find( id, ProjectTemplate.class );
+		if( projectTemplate != null ) {
+			emc.beginTransaction( TaskListTemplate.class );
+			emc.beginTransaction( ProjectTemplate.class );
+			if( projectTemplate != null ) {
+				//emc.remove( projectTemplate , CheckRemoveType.all );
+				//改为软删除
+				projectTemplate.setDeleted(true);
+				emc.check( projectTemplate , CheckPersistType.all );
+			}
+			//还需要删除所有的TaskListTemplate
+			List<TaskListTemplate> TaskListTemplates = business.taskListTemplateFactory().list(projectTemplate.getId());
+			if( ListTools.isNotEmpty(TaskListTemplates)) {
+				for( TaskListTemplate TaskListTemplate : TaskListTemplates ) {
+					//emc.remove( task , CheckRemoveType.all );
+					TaskListTemplate.setDeleted(true);
+					emc.check( TaskListTemplate , CheckPersistType.all );
+				}
+			}
+			emc.commit();
+		}
+	}
+	/**
+	 * 根据工作任务标识删除工作任务信息(物理删除)
+	 * @param emc
+	 * @param flag 主要是ID
+	 * @throws Exception 
+	 */
+	public void remove( EntityManagerContainer emc, String flag ) throws Exception {
+		emc.beginTransaction( Task.class );
+		emc.beginTransaction( Review.class );
+		emc.beginTransaction( TaskDetail.class );
+		emc.beginTransaction( TaskListRele.class );
+		emc.beginTransaction( TaskGroupRele.class );
+		removeTaskWithChildren( emc, flag);		
+		emc.commit();
+	}
+	/**
+	 * 根据工作任务标识删除工作任务信息( 物理删除 )
+	 * @param emc
+	 * @param id
+	 * @throws Exception 
+	 */
+	private void removeTaskWithChildren( EntityManagerContainer emc, String id ) throws Exception {
+		Business business = new Business( emc );
+		
+		//还需要递归删除所有的下级Task
+		List<String> childrenIds = business.taskFactory().listByParent( id );
+		if( ListTools.isNotEmpty( childrenIds )) {
+			for( String _id : childrenIds ) {
+				removeTaskWithChildren( emc, _id );
+			}
+		}
+		
+		//任务列表中的关联信息
+		List<TaskListRele> listReles = business.taskListFactory().listReleWithTask(  id );
+		if( ListTools.isNotEmpty( listReles )) {
+			for( TaskListRele taskListRele : listReles ) {
+				emc.remove( taskListRele , CheckRemoveType.all );
+			}
+		}
+		
+		//删除任务组关联信息
+		List<TaskGroupRele> groupReles = business.taskGroupReleFactory().listTaskReleWithTask( id );
+		if( ListTools.isNotEmpty( groupReles )) {
+			for( TaskGroupRele taskGroupRele : groupReles ) {
+				emc.remove( taskGroupRele , CheckRemoveType.all );
+			}
+		}
+		
+		Task task = emc.find( id, Task.class );
+		TaskDetail taskDetail = emc.find( id, TaskDetail.class );
+		List<Review> reviewList = null;
+		List<List<String>> reviewIdBatchs = null;
+		List<String> reviewIds = business.reviewFactory().listReviewByTask( id, 9999 );
+		if( ListTools.isNotEmpty( reviewIds )) {
+			reviewIdBatchs = ListTools.batch( reviewIds, 1000 );
+		}
+		if( ListTools.isNotEmpty( reviewIdBatchs )) {
+			for( List<String> batch : reviewIdBatchs ) {
+				reviewList = emc.list( Review.class, batch );
+				if( ListTools.isNotEmpty( reviewList )) {
+					for( Review review : reviewList ) {
+						//emc.remove( review, CheckRemoveType.all );
+						//改为软删除
+						review.setDeleted(true);
+						emc.check( review, CheckPersistType.all );
+					}
+				}
+			}
+		}
+		if( task != null ) {
+			//emc.remove( task , CheckRemoveType.all );
+			//改为软删除
+			task.setDeleted(true);
+			emc.check( task, CheckPersistType.all );	
+		}
+		if( taskDetail != null ) {
+			emc.remove( taskDetail , CheckRemoveType.all );
+		}
+	}
+	
+	/**
+	 * 创建模板的工作任务列表
+	 * @param emc
+	 * @param person
+	 * @param template
+	 * @return
+	 * @throws Exception
+	 */
+	public void createDefaultTaskListForProjectTemplate( EntityManagerContainer emc, String person, ProjectTemplate template) throws Exception {		
+		TaskListTemplate taskList = null;
+		List<String> taskListsTemplate = template.getTaskList();
+		
+		if( !ListTools.isEmpty( taskListsTemplate )) {
+			emc.beginTransaction( TaskList.class );
+			for( String taskListTemplate: taskListsTemplate ) {
+				taskList = composeTaskListObject( template.getId(), taskListTemplate, 1, "SYSTEM", person, "" );
+				emc.persist( taskList, CheckPersistType.all );
+			}
+			
+			emc.commit();
+		}
+	}
+	
+	private TaskListTemplate  composeTaskListObject( String projectTemplateId, String listName, int orderNum, String creatorName, String owner, String memo ) {
+		TaskListTemplate taskTemplateList = new TaskListTemplate();		
+		taskTemplateList.setId( TaskListTemplate.createId() );
+		taskTemplateList.setName( listName );
+		taskTemplateList.setProjectTemplate( projectTemplateId );
+		taskTemplateList.setMemo( memo );
+		
+		taskTemplateList.setOrder( orderNum );
+		taskTemplateList.setCreatorPerson( creatorName );
+		taskTemplateList.setOwner( owner );
+		taskTemplateList.setDeleted(false);
+		return taskTemplateList;
+	}
+
+	/**
+	 * 根据条件查询项目ID列表,最大查询2000条
+	 * @param emc
+	 * @param maxCount
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public List<String> listAllViewableProjectIds(EntityManagerContainer emc, int maxCount, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().listAllViewableProjectIds(maxCount, personName, identityNames, unitNames, groupNames, queryFilter);
+	}
+
+	public List<String> listAllProjectIds(EntityManagerContainer emc ) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().listAllProjectIds();
+	}	
+}

+ 129 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/TaskListTemplatePersistService.java

@@ -0,0 +1,129 @@
+package com.x.teamwork.assemble.control.service;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.teamwork.assemble.common.date.DateOperation;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.TaskListTemplate;
+
+/**
+ * 对项目信息查询的服务
+ * 
+ * @author O2LEE
+ */
+public class TaskListTemplatePersistService {
+
+	private TaskListTemplateService taskListTemplateService = new TaskListTemplateService();
+	private UserManagerService userManagerService = new UserManagerService();
+	
+	public void delete( String flag, EffectivePerson currentPerson ) throws Exception {
+		if ( StringUtils.isEmpty( flag )) {
+			throw new Exception("flag is empty.");
+		}
+		Boolean hasDeletePermission = false;
+		Business business = null;
+		try (EntityManagerContainer bc = EntityManagerContainerFactory.instance().create()) {
+			business = new Business(bc);
+		}
+		if( business.isManager(currentPerson) ) {
+			hasDeletePermission = true;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			TaskListTemplate taskListTemplate = taskListTemplateService.get(emc, flag);
+			//管理员可以删除,创建者可以删除
+			if( !hasDeletePermission ) {
+				//看看是不是项目创建者
+				if( taskListTemplate.getOwner().equalsIgnoreCase( currentPerson.getDistinguishedName() )) {
+					hasDeletePermission = true;
+				}
+			}
+			if( !hasDeletePermission ) {
+				throw new Exception("taskListTemplate delete permission denied.");
+			}else {
+				taskListTemplateService.delete( emc, flag );
+			}			
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	public TaskListTemplate save( TaskListTemplate taskListTemplate, EffectivePerson effectivePerson ) throws Exception {
+		if ( taskListTemplate == null) {
+			throw new Exception("taskListTemplate is null.");
+		}
+		if( StringUtils.isEmpty( taskListTemplate.getName() )) {
+			taskListTemplate.setName("无标题项目("+ DateOperation.getNowDateTime() +")");
+		}	
+		if( taskListTemplate.getName().length() > 70 ) {
+			taskListTemplate.setName( taskListTemplate.getName().substring(0, 70) + "..." );
+		}
+		if( StringUtils.isEmpty( taskListTemplate.getOwner()) ) {
+			taskListTemplate.setOwner(effectivePerson.getDistinguishedName());
+		}
+
+		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {			
+			taskListTemplate = taskListTemplateService.save( emc, taskListTemplate );			
+		} catch (Exception e) {
+			throw e;
+		}
+		return taskListTemplate;
+	}
+	
+	/**
+	 * 保存或者更新项目的图标信息
+	 * @param projectId
+	 * @param icon
+	 * @throws Exception
+	 */
+	public void saveProjectIcon( String projectId, String icon ) throws Exception {
+		if ( StringUtils.isEmpty( projectId )) {
+			throw new Exception("projectId is empty!");
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Project project = emc.find( projectId, Project.class );
+			if( project == null ) {
+				throw new Exception("Project not exists.id:" + projectId );
+			}else {
+				emc.beginTransaction( Project.class );
+				if( StringUtils.isEmpty( icon )) {
+					project.setIcon( null );
+				}else {
+					project.setIcon(icon);
+				}
+				emc.check( project, CheckPersistType.all );	
+				emc.commit();
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	/**
+	 * 查询用户是否拥有创建项目的权限
+	 * 根据配置的权限来确定项目创建权限
+	 * @param effectivePerson
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean checkPermissionForPersist( EffectivePerson effectivePerson, String project_creator_config ) throws Exception {
+		//根据配置为全员可以创建项目
+		if( "ALL".equalsIgnoreCase( project_creator_config )) {
+			return true;
+		}
+		//系统管理员可以创建项目
+		if( effectivePerson.isManager() ) {
+			return true;
+		}
+		//工作任务系统管理员可以创建项目
+		if( userManagerService.isHasPlatformRole( effectivePerson.getDistinguishedName(), "TeamWorkManager" )) {
+			return true;
+		}
+		return false;
+	}	
+}

+ 322 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/TaskListTemplateQueryService.java

@@ -0,0 +1,322 @@
+package com.x.teamwork.assemble.control.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.ProjectDetail;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.TaskListTemplate;
+import com.x.teamwork.core.entity.tools.filter.QueryFilter;
+import com.x.teamwork.core.entity.tools.filter.term.EqualsTerm;
+import com.x.teamwork.core.entity.tools.filter.term.InTerm;
+
+/**
+ * 对项目信息查询的服务
+ * 
+ * @author O2LEE
+ */
+public class TaskListTemplateQueryService {
+
+	private TaskListTemplateService taskListTemplateService = new TaskListTemplateService();
+	private UserManagerService userManagerService = new UserManagerService();
+	
+	/**
+	 * 根据项目的标识查询项目信息
+	 * @param id
+	 * @return
+	 * @throws Exception
+	 */
+	public TaskListTemplate get( String id ) throws Exception {
+		if ( StringUtils.isEmpty( id )) {
+			return null;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return taskListTemplateService.get(emc, id );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+
+	/**
+	 * 根据ID列表查询项目信息列表
+	 * @param ids
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> list(List<String> ids) throws Exception {
+		if (ListTools.isEmpty( ids )) {
+			return null;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return emc.list( Project.class,  ids );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	public List<String> listAllProjectIds() throws Exception {		
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return taskListTemplateService.listAllProjectIds( emc );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	/**
+	 * 根据过滤条件查询符合要求的项目信息列表
+	 * @param effectivePerson
+	 * @param pageSize
+	 * @param pageNum
+	 * @param orderField
+	 * @param orderType
+	 * @param group  项目分组
+	 * @param title
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> listWithProjectIdsFilter( Integer pageSize, Integer pageNum, String orderField, String orderType, List<String> projectIds ) throws Exception {
+		List<Project> projectList = null;
+		List<Project> result = new ArrayList<>();
+		Integer maxCount = 20;
+		Integer startNumber = 0;		
+		
+		if( pageNum == 0 ) { pageNum = 1; }
+		if( pageSize == 0 ) { pageSize = 20; }
+		maxCount = pageSize * pageNum;
+		startNumber = pageSize * ( pageNum -1 );
+		
+		if( StringUtils.isEmpty( orderField ) ) { 
+			orderField = "createTime";
+		}
+		if( StringUtils.isEmpty( orderType ) ) { 
+			orderType = "desc";
+		}
+		QueryFilter queryFilter = new QueryFilter();
+		queryFilter.addInTerm( new InTerm("id", new ArrayList<>(projectIds) ));
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			
+			projectList = taskListTemplateService.listWithFilter( emc, maxCount, orderField, orderType, null, null, null, null, queryFilter );
+			
+			if( ListTools.isNotEmpty( projectList )) {
+				for( int i = 0; i<projectList.size(); i++ ) {
+					if( i >= startNumber ) {
+						result.add( projectList.get( i ));
+					}
+				}
+			}			
+		} catch (Exception e) {
+			throw e;
+		}
+		return result;
+	}	
+	
+	/**
+	 * 根据项目ID列表查询项目信息列表,根据上一条的sequnce查询指定数量的信息
+	 * @param pageSize
+	 * @param lastId
+	 * @param orderField
+	 * @param orderType
+	 * @param projectIds
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Project> listWithProjectIdFilter( Integer pageSize, String lastId, String orderField, String orderType, List<String> projectIds ) throws Exception {
+		Project project = null;
+		if( pageSize == 0 ) { pageSize = 20; }
+		if( StringUtils.isEmpty( orderField ) ) { 
+			orderField = "createTime";
+		}
+		if( StringUtils.isEmpty( orderType ) ) { 
+			orderType = "desc";
+		}
+		QueryFilter queryFilter = new QueryFilter();
+		queryFilter.addInTerm( new InTerm("id", new ArrayList<>(projectIds) ));
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			if( lastId != null ) {
+				project = emc.find( lastId, Project.class );
+			}
+			if( project != null ) {
+				return taskListTemplateService.listWithFilter(emc, pageSize, project.getSequence(), orderField, orderType, null, null, null, null, queryFilter );
+			}else {
+				return taskListTemplateService.listWithFilter(emc, pageSize, null, orderField, orderType, null, null, null, null, queryFilter );
+			}	
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+	/**
+	 * 判断用户是否为指定项目的管理员
+	 * @param projectId
+	 * @param distinguishedName
+	 * @return
+	 * @throws Exception 
+	 */
+	public Boolean isProjectManager(String projectId, String distinguishedName) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Project project = emc.find( projectId, Project.class );
+			if( ListTools.isNotEmpty( project.getManageablePersonList() )){
+				if( distinguishedName.equalsIgnoreCase( project.getCreatorPerson() )) {
+					return true;
+				}
+				if( distinguishedName.equalsIgnoreCase( project.getExecutor() )) {
+					return true;
+				}
+				if( project.getManageablePersonList().contains( distinguishedName )) {
+					return true;
+				}
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+		return false;
+	}
+
+	/**
+	 * 判断用户是项目参与者
+	 * @param projectId
+	 * @param distinguishedName
+	 * @return
+	 * @throws Exception 
+	 */
+	public Boolean isProjectParticipant( String projectId, String personName ) throws Exception {		
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson(personName);
+			identityNames = userManagerService.listIdentitiesWithPerson(personName);
+			
+			Project project = emc.find( projectId, Project.class );
+
+			if( project.getParticipantPersonList().contains( personName )) {
+				return true;
+			}
+			project.getParticipantIdentityList().retainAll( identityNames );
+			if( ListTools.isNotEmpty( project.getParticipantIdentityList() )) {
+				return true;
+			}
+			project.getParticipantUnitList().retainAll( unitNames );
+			if( ListTools.isNotEmpty( project.getParticipantUnitList() )) {
+				return true;
+			}
+			project.getParticipantGroupList().retainAll( groupNames );
+			if( ListTools.isNotEmpty( project.getParticipantGroupList() )) {
+				return true;
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+		return false;
+	}
+	
+	/**
+	 * 判断用户是否拥有指定项目的访问权限
+	 * @param appId
+	 * @param distinguishedName
+	 * @return
+	 * @throws Exception 
+	 */
+	public Boolean isProjectViewer(String appId, String personName ) throws Exception {
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson(personName);
+			identityNames = userManagerService.listIdentitiesWithPerson(personName);
+			
+			Project project = emc.find( appId, Project.class );
+			if( personName.equalsIgnoreCase( project.getCreatorPerson() )) {
+				return true;
+			}
+			if( personName.equalsIgnoreCase( project.getExecutor() )) {
+				return true;
+			}	
+			if( project.getManageablePersonList().contains( personName )) {
+				return true;
+			}				
+			if( project.getParticipantPersonList().contains( personName )) {
+				return true;
+			}
+			project.getParticipantIdentityList().retainAll( identityNames );
+			if( ListTools.isNotEmpty( project.getParticipantIdentityList() )) {
+				return true;
+			}
+			project.getParticipantUnitList().retainAll( unitNames );
+			if( ListTools.isNotEmpty( project.getParticipantUnitList() )) {
+				return true;
+			}
+			project.getParticipantGroupList().retainAll( groupNames );
+			if( ListTools.isNotEmpty( project.getParticipantGroupList() )) {
+				return true;
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+		return false;
+	}
+
+	/**
+	 * 根据条件查询项目ID列表,最大查询2000条,查询未删除
+	 * @param effectivePerson
+	 * @param i
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception 
+	 */
+	public List<String> listAllViewableProjectIds(EffectivePerson effectivePerson, int maxCount, QueryFilter queryFilter) throws Exception {
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		String personName = effectivePerson.getDistinguishedName();
+		if( maxCount ==  0) {
+			maxCount = 1000;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson( personName );
+			identityNames = userManagerService.listIdentitiesWithPerson( personName );
+			queryFilter.addEqualsTerm( new EqualsTerm( "deleted", false ) );
+			return taskListTemplateService.listAllViewableProjectIds( emc, maxCount, personName,  identityNames, unitNames, groupNames, queryFilter );
+		} catch (Exception e) {
+			throw e;
+		}
+	}	
+	/**
+	 * 根据条件查询项目ID列表,最大查询2000条
+	 * @param effectivePerson
+	 * @param i
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception 
+	 */
+	public List<String> listAllProjectIds(EffectivePerson effectivePerson, int maxCount, QueryFilter queryFilter) throws Exception {
+		List<String> unitNames = null;
+		List<String> groupNames = null;
+		List<String> identityNames = null;
+		String personName = effectivePerson.getDistinguishedName();
+		if( maxCount ==  0) {
+			maxCount = 1000;
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			unitNames = userManagerService.listUnitNamesWithPerson( personName );
+			groupNames = userManagerService.listGroupNamesByPerson( personName );
+			identityNames = userManagerService.listIdentitiesWithPerson( personName );
+			return taskListTemplateService.listAllViewableProjectIds( emc, maxCount, personName,  identityNames, unitNames, groupNames, queryFilter );
+		} catch (Exception e) {
+			throw e;
+		}
+	}	
+}

+ 290 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/TaskListTemplateService.java

@@ -0,0 +1,290 @@
+package com.x.teamwork.assemble.control.service;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.entity.annotation.CheckRemoveType;
+import com.x.base.core.project.tools.ListTools;
+import com.x.teamwork.assemble.control.Business;
+import com.x.teamwork.core.entity.Project;
+import com.x.teamwork.core.entity.ProjectDetail;
+import com.x.teamwork.core.entity.ProjectTemplate;
+import com.x.teamwork.core.entity.Review;
+import com.x.teamwork.core.entity.Task;
+import com.x.teamwork.core.entity.TaskDetail;
+import com.x.teamwork.core.entity.TaskGroupRele;
+import com.x.teamwork.core.entity.TaskList;
+import com.x.teamwork.core.entity.TaskListRele;
+import com.x.teamwork.core.entity.TaskListTemplate;
+import com.x.teamwork.core.entity.tools.filter.QueryFilter;
+
+class TaskListTemplateService {
+
+	/**
+	 * 根据项目的标识查询项目的信息
+	 * @param emc
+	 * @param flag  主要是ID
+	 * @return
+	 * @throws Exception 
+	 */
+	protected TaskListTemplate get(EntityManagerContainer emc, String flag) throws Exception {
+		Business business = new Business( emc );
+		return business.taskListTemplateFactory().get( flag ); 
+	}
+	
+	protected ProjectDetail getDetail(EntityManagerContainer emc, String id) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().getDetail( id );
+	}
+	
+	/**
+	 * 根据过滤条件查询符合要求的项目信息列表
+	 * @param emc
+	 * @param maxCount
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param group  项目分组
+	 * @param title
+	 * @return
+	 * @throws Exception
+	 */
+	protected List<Project> listWithFilter( EntityManagerContainer emc, Integer maxCount, String orderField, String orderType, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter ) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().listWithFilter(maxCount, orderField, orderType, personName, identityNames, unitNames, groupNames, queryFilter);
+	}
+	
+	/**
+	 * 根据条件查询符合条件的项目信息ID,根据上一条的sequnce查询指定数量的信息
+	 * @param emc
+	 * @param maxCount
+	 * @param sequnce
+	 * @param orderField
+	 * @param orderType
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param group   项目分组
+	 * @param title
+	 * @return
+	 * @throws Exception
+	 */
+	protected List<Project> listWithFilter( EntityManagerContainer emc, Integer maxCount, String sequnce, String orderField, String orderType, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter ) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().listWithFilter(maxCount, sequnce, orderField, orderType, personName, identityNames, unitNames, groupNames, queryFilter);
+	}
+
+	/**
+	 * 向数据库持久化项目信息
+	 * @param emc
+	 * @param projectDetail 
+	 * @param project
+	 * @return
+	 * @throws Exception 
+	 */
+	protected TaskListTemplate save( EntityManagerContainer emc, TaskListTemplate object) throws Exception {
+		TaskListTemplate taskListTemplate = null;
+		if( StringUtils.isEmpty( object.getId() )  ){
+			object.setId( Project.createId() );
+		}
+		
+		taskListTemplate = emc.find( object.getId(), TaskListTemplate.class );
+		
+		emc.beginTransaction( Project.class );
+		emc.beginTransaction( ProjectDetail.class );
+		
+		if( taskListTemplate == null ){ // 保存一个新的对象
+			taskListTemplate = new TaskListTemplate();
+			object.copyTo( taskListTemplate );
+			if( StringUtils.isNotEmpty( object.getId() ) ){
+				taskListTemplate.setId( object.getId() );
+			}
+			emc.persist( taskListTemplate, CheckPersistType.all);
+		}else{ //对象已经存在,更新对象信息
+			if( StringUtils.isNotEmpty( taskListTemplate.getOwner() )) {
+				object.setOwner( taskListTemplate.getOwner() );
+			}
+			object.copyTo( taskListTemplate, JpaObject.FieldsUnmodify  );
+			emc.check( taskListTemplate, CheckPersistType.all );	
+		}
+		emc.commit();
+		return taskListTemplate;
+	}
+
+	/**
+	 * 根据项目模板标识删除项目模板信息
+	 * @param emc
+	 * @param id
+	 * @throws Exception 
+	 */
+	protected void delete(EntityManagerContainer emc, String id ) throws Exception {
+		Business business = new Business( emc );
+		TaskListTemplate taskListTemplate = emc.find( id, TaskListTemplate.class );
+		if( taskListTemplate != null ) {
+			emc.beginTransaction( TaskListTemplate.class );
+			emc.beginTransaction( ProjectTemplate.class );
+			if( taskListTemplate != null ) {
+				//emc.remove( projectTemplate , CheckRemoveType.all );
+				//改为软删除
+				taskListTemplate.setDeleted(true);
+				emc.check( taskListTemplate , CheckPersistType.all );
+			}
+			//还需要删除所有的TaskListTemplate
+			List<TaskListTemplate> TaskListTemplates = business.taskListTemplateFactory().list(taskListTemplate.getId());
+			if( ListTools.isNotEmpty(TaskListTemplates)) {
+				for( TaskListTemplate TaskListTemplate : TaskListTemplates ) {
+					//emc.remove( task , CheckRemoveType.all );
+					TaskListTemplate.setDeleted(true);
+					emc.check( TaskListTemplate , CheckPersistType.all );
+				}
+			}
+			emc.commit();
+		}
+	}
+	/**
+	 * 根据工作任务标识删除工作任务信息(物理删除)
+	 * @param emc
+	 * @param flag 主要是ID
+	 * @throws Exception 
+	 */
+	public void remove( EntityManagerContainer emc, String flag ) throws Exception {
+		emc.beginTransaction( Task.class );
+		emc.beginTransaction( Review.class );
+		emc.beginTransaction( TaskDetail.class );
+		emc.beginTransaction( TaskListRele.class );
+		emc.beginTransaction( TaskGroupRele.class );
+		removeTaskWithChildren( emc, flag);		
+		emc.commit();
+	}
+	/**
+	 * 根据工作任务标识删除工作任务信息( 物理删除 )
+	 * @param emc
+	 * @param id
+	 * @throws Exception 
+	 */
+	private void removeTaskWithChildren( EntityManagerContainer emc, String id ) throws Exception {
+		Business business = new Business( emc );
+		
+		//还需要递归删除所有的下级Task
+		List<String> childrenIds = business.taskFactory().listByParent( id );
+		if( ListTools.isNotEmpty( childrenIds )) {
+			for( String _id : childrenIds ) {
+				removeTaskWithChildren( emc, _id );
+			}
+		}
+		
+		//任务列表中的关联信息
+		List<TaskListRele> listReles = business.taskListFactory().listReleWithTask(  id );
+		if( ListTools.isNotEmpty( listReles )) {
+			for( TaskListRele taskListRele : listReles ) {
+				emc.remove( taskListRele , CheckRemoveType.all );
+			}
+		}
+		
+		//删除任务组关联信息
+		List<TaskGroupRele> groupReles = business.taskGroupReleFactory().listTaskReleWithTask( id );
+		if( ListTools.isNotEmpty( groupReles )) {
+			for( TaskGroupRele taskGroupRele : groupReles ) {
+				emc.remove( taskGroupRele , CheckRemoveType.all );
+			}
+		}
+		
+		Task task = emc.find( id, Task.class );
+		TaskDetail taskDetail = emc.find( id, TaskDetail.class );
+		List<Review> reviewList = null;
+		List<List<String>> reviewIdBatchs = null;
+		List<String> reviewIds = business.reviewFactory().listReviewByTask( id, 9999 );
+		if( ListTools.isNotEmpty( reviewIds )) {
+			reviewIdBatchs = ListTools.batch( reviewIds, 1000 );
+		}
+		if( ListTools.isNotEmpty( reviewIdBatchs )) {
+			for( List<String> batch : reviewIdBatchs ) {
+				reviewList = emc.list( Review.class, batch );
+				if( ListTools.isNotEmpty( reviewList )) {
+					for( Review review : reviewList ) {
+						//emc.remove( review, CheckRemoveType.all );
+						//改为软删除
+						review.setDeleted(true);
+						emc.check( review, CheckPersistType.all );
+					}
+				}
+			}
+		}
+		if( task != null ) {
+			//emc.remove( task , CheckRemoveType.all );
+			//改为软删除
+			task.setDeleted(true);
+			emc.check( task, CheckPersistType.all );	
+		}
+		if( taskDetail != null ) {
+			emc.remove( taskDetail , CheckRemoveType.all );
+		}
+	}
+	
+	/**
+	 * 创建模板的工作任务列表
+	 * @param emc
+	 * @param person
+	 * @param template
+	 * @return
+	 * @throws Exception
+	 */
+	public void createDefaultTaskListForProjectTemplate( EntityManagerContainer emc, String person, ProjectTemplate template) throws Exception {		
+		TaskListTemplate taskList = null;
+		List<String> taskListsTemplate = template.getTaskList();
+		
+		if( !ListTools.isEmpty( taskListsTemplate )) {
+			emc.beginTransaction( TaskList.class );
+			for( String taskListTemplate: taskListsTemplate ) {
+				taskList = composeTaskListObject( template.getId(), taskListTemplate, 1, "SYSTEM", person, "" );
+				emc.persist( taskList, CheckPersistType.all );
+			}
+			
+			emc.commit();
+		}
+	}
+	
+	private TaskListTemplate  composeTaskListObject( String projectTemplateId, String listName, int orderNum, String creatorName, String owner, String memo ) {
+		TaskListTemplate taskTemplateList = new TaskListTemplate();		
+		taskTemplateList.setId( TaskListTemplate.createId() );
+		taskTemplateList.setName( listName );
+		taskTemplateList.setProjectTemplate( projectTemplateId );
+		taskTemplateList.setMemo( memo );
+		
+		taskTemplateList.setOrder( orderNum );
+		taskTemplateList.setCreatorPerson( creatorName );
+		taskTemplateList.setOwner( owner );
+		taskTemplateList.setDeleted(false);
+		return taskTemplateList;
+	}
+
+	/**
+	 * 根据条件查询项目ID列表,最大查询2000条
+	 * @param emc
+	 * @param maxCount
+	 * @param personName
+	 * @param identityNames
+	 * @param unitNames
+	 * @param groupNames
+	 * @param queryFilter
+	 * @return
+	 * @throws Exception
+	 */
+	public List<String> listAllViewableProjectIds(EntityManagerContainer emc, int maxCount, String personName, List<String> identityNames, List<String> unitNames, List<String> groupNames, QueryFilter queryFilter) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().listAllViewableProjectIds(maxCount, personName, identityNames, unitNames, groupNames, queryFilter);
+	}
+
+	public List<String> listAllProjectIds(EntityManagerContainer emc ) throws Exception {
+		Business business = new Business( emc );
+		return business.projectFactory().listAllProjectIds();
+	}	
+}

+ 4 - 0
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/service/TaskQueryService.java

@@ -233,9 +233,12 @@ public class TaskQueryService {
 				if( taskIds_all_tmp == null ) {
 					taskIds_all_tmp = new ArrayList<>();
 				}
+				System.out.println("w:taskIds_all_tmp="+taskIds_all_tmp.size());
+				
 				for( String str : taskIds_all_tmp ) {
 					taskIds_all.add( str );
 				}
+				System.out.println("w:taskIds_all="+taskIds_all.size());
 				//查询默认的TaskGroup
 				taskGroupList = taskGroupService.listGroupByPersonAndProject( emc, personName, projectId);
 				if( ListTools.isNotEmpty( taskGroupList )) {
@@ -247,6 +250,7 @@ public class TaskQueryService {
 						if( taskIds_forTaskList == null ) {
 							taskIds_forTaskList = new ArrayList<>();
 						}
+						System.out.println("默认泳道:taskIds_forTaskList="+taskIds_forTaskList.size());
 						taskIds_all.removeAll( taskIds_forTaskList );
 					}
 				}

+ 5 - 3
o2server/x_teamwork_assemble_control/src/main/java/com/x/teamwork/assemble/control/timertask/Timertask_CheckAllTaskOverTime.java

@@ -37,6 +37,7 @@ public class Timertask_CheckAllTaskOverTime extends AbstractJob {
 		Date now = new Date();
 		List<String> projectIds = null;
 		List<String> taskIds = null;
+		logger.info("Timertask_CheckAllTaskOverTime -> Check task excute start.");
 		try {
 			projectIds = projectQueryService.listAllProjectIds();
 		} catch (Exception e) {
@@ -53,11 +54,12 @@ public class Timertask_CheckAllTaskOverTime extends AbstractJob {
 							for( String taskId : taskIds ) {
 								task = emc.find( taskId, Task.class );
 								if( task != null ) {
-									logger.debug("Timertask_CheckAllTaskOverTime check  task:" +  task.getName());
+									//logger.info("Timertask_CheckAllTaskOverTime check  task:" +  task.getName());
 									
 									if( task.getEndTime()  != null && !TaskStatuType.completed.name().equalsIgnoreCase( task.getWorkStatus() )) {
 										if( task.getEndTime().before( now ) && !task.getOvertime()) {
 											//超时了,打上标识,并且发送提醒
+											logger.info("Timertask_CheckAllTaskOverTime check  task:"+task.getName()+"超时,打上标识,并发送提醒");
 											emc.beginTransaction( Task.class );
 											task.setOvertime( true );
 											emc.check( task, CheckPersistType.all );
@@ -86,7 +88,7 @@ public class Timertask_CheckAllTaskOverTime extends AbstractJob {
 											}																
 										}
 										if( task.getEndTime().after( now ) && task.getOvertime()) {
-											logger.debug("超时变未超时,打上标识,不发送提醒");
+											logger.info("Timertask_CheckAllTaskOverTime check  task:"+task.getName()+"超时变未超时,打上标识,不发送提醒");
 											//超时变未超时,打上标识,不发送提醒
 											emc.beginTransaction( Task.class );
 											task.setOvertime( false );
@@ -132,6 +134,6 @@ public class Timertask_CheckAllTaskOverTime extends AbstractJob {
 				}
 			}
 		}
-		logger.debug("Timertask_BatchOperationTask -> batch operations timer task excute completed.");
+		logger.info("Timertask_CheckAllTaskOverTime -> Check task excute completed.");
 	}
 }

+ 4 - 0
o2server/x_teamwork_core_entity/src/main/java/com/x/teamwork/core/entity/PersistenceProperties.java

@@ -56,6 +56,10 @@ public final class PersistenceProperties extends AbstractPersistenceProperties {
 		public static final String table = "TEW_TASKLIST";
 	}
 	
+	public static class TaskListTemplate {
+		public static final String table = "TEW_TASKLISTTEMPLATE";
+	}
+	
 	public static class TaskRelevance {
 		public static final String table = "TEW_TASKRELEVANCE";
 	}	

+ 14 - 0
o2server/x_teamwork_core_entity/src/main/java/com/x/teamwork/core/entity/ProjectTemplate.java

@@ -119,6 +119,12 @@ public class ProjectTemplate extends SliceJpaObject {
 	@ElementIndex(name = TABLE + IndexNameMiddle + taskList_FIELDNAME + ElementIndexNameSuffix)
 	@CheckPersist(allowEmpty = true)
 	private List<String> taskList;
+	
+	public static final String deleted_FIELDNAME = "deleted";
+	@FieldDescribe("是否已经删除")
+	@Column( name = ColumnNamePrefix + deleted_FIELDNAME)
+	@Index( name = TABLE + IndexNameMiddle + deleted_FIELDNAME )
+	private Boolean deleted = false;
 
 	public String getTitle() {
 		return title;
@@ -175,6 +181,14 @@ public class ProjectTemplate extends SliceJpaObject {
 	public void setTaskList(List<String> taskList) {
 		this.taskList = taskList;
 	}
+	
+	public Boolean getDeleted() {
+		return deleted;
+	}
+
+	public void setDeleted(Boolean deleted) {
+		this.deleted = deleted;
+	}
 
 	
 }

+ 167 - 0
o2server/x_teamwork_core_entity/src/main/java/com/x/teamwork/core/entity/TaskListTemplate.java

@@ -0,0 +1,167 @@
+package com.x.teamwork.core.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.openjpa.persistence.jdbc.Index;
+
+import com.x.base.core.entity.AbstractPersistenceProperties;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.SliceJpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.ContainerEntity;
+import com.x.base.core.project.annotation.FieldDescribe;
+
+/**
+ * 工作任务列表(泳道)
+ *
+ */
+@ContainerEntity
+@Entity
+@Table(name = PersistenceProperties.TaskListTemplate.table, uniqueConstraints = {
+		@UniqueConstraint(name = PersistenceProperties.TaskListTemplate.table + JpaObject.IndexNameMiddle
+				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
+						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class TaskListTemplate extends SliceJpaObject {
+
+	private static final long serialVersionUID = 3856138316794473794L;
+	private static final String TABLE = PersistenceProperties.TaskListTemplate.table;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@FieldDescribe("数据库主键,自动生成.")
+	@Id
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
+	private String id = createId();
+
+	public void onPersist() throws Exception {
+	}
+	/*
+	 * =========================================================================
+	 * ========= 以上为 JpaObject 默认字段
+	 * =========================================================================
+	 * =========
+	 */
+
+	/*
+	 * =========================================================================
+	 * ========= 以下为具体不同的业务及数据表字段要求
+	 * =========================================================================
+	 * =========
+	 */
+	public static final String name_FIELDNAME = "name";
+	@FieldDescribe("工作任务列表(泳道)名称")
+	@Column( length = JpaObject.length_96B, name = ColumnNamePrefix + name_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + name_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private String name;
+	
+	public static final String projectTemplate_FIELDNAME = "projectTemplate";
+	@FieldDescribe("所属模板ID.")
+	@Column(length = length_id, name = ColumnNamePrefix + projectTemplate_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + projectTemplate_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private String projectTemplate;
+	
+	public static final String order_FIELDNAME = "order";
+	@FieldDescribe("排序号")
+	@Column( name = ColumnNamePrefix + order_FIELDNAME )
+	private Integer order = 0;
+	
+	public static final String memo_FIELDNAME = "memo";
+	@FieldDescribe("列表描述")
+	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + memo_FIELDNAME)
+	@Index( name = TABLE + IndexNameMiddle + memo_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String memo;	
+	
+	public static final String creatorPerson_FIELDNAME = "creatorPerson";
+	@FieldDescribe("创建者,可能为System,如果由系统创建。")
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + creatorPerson_FIELDNAME)
+	@Index( name = TABLE + IndexNameMiddle + creatorPerson_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String creatorPerson;
+	
+	public static final String owner_FIELDNAME = "owner";
+	@FieldDescribe("拥有者")
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + owner_FIELDNAME)
+	@Index( name = TABLE + IndexNameMiddle + owner_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String owner;
+
+	public static final String deleted_FIELDNAME = "deleted";
+	@FieldDescribe("是否已经删除")
+	@Column( name = ColumnNamePrefix + deleted_FIELDNAME)
+	@Index( name = TABLE + IndexNameMiddle + deleted_FIELDNAME )
+	private Boolean deleted = false;
+	
+	
+
+	public Boolean getDeleted() {
+		return deleted;
+	}
+
+	public void setDeleted(Boolean deleted) {
+		this.deleted = deleted;
+	}
+
+	public String getProjectTemplate() {
+		return projectTemplate;
+	}
+
+	public void setProjectTemplate(String projectTemplate) {
+		this.projectTemplate = projectTemplate;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Integer getOrder() {
+		return order;
+	}
+
+	public void setOrder(Integer order) {
+		this.order = order;
+	}
+
+	public String getMemo() {
+		return memo;
+	}
+
+	public void setMemo(String memo) {
+		this.memo = memo;
+	}
+
+	public String getCreatorPerson() {
+		return creatorPerson;
+	}
+
+	public void setCreatorPerson(String creatorPerson) {
+		this.creatorPerson = creatorPerson;
+	}
+
+	public String getOwner() {
+		return owner;
+	}
+
+	public void setOwner(String owner) {
+		this.owner = owner;
+	}	
+}