Răsfoiți Sursa

修改并行合拆分worklog实现方式

roo00 6 ani în urmă
părinte
comite
358dec963e
46 a modificat fișierele cu 2271 adăugiri și 617 ștergeri
  1. 213 445
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/Business.java
  2. 27 1
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/factory/content/JobFactory.java
  3. 2 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/ActionApplication.java
  4. 10 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/ControlJaxrsFilter.java
  5. 148 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/attachment/ActionListWithWorkOrWorkCompleted.java
  6. 19 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/attachment/AttachmentAction.java
  7. 197 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/control/ActionGetWorkOrWorkCompleted.java
  8. 112 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/control/BaseAction.java
  9. 10 9
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/control/ControlAction.java
  10. 15 11
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/ActionGet.java
  11. 43 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/ActionGetMobile.java
  12. 89 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/ActionGetWithWorkOrWorkCompleted.java
  13. 89 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/ActionGetWithWorkOrWorkCompletedMobile.java
  14. 59 3
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/FormAction.java
  15. 61 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/readcompleted/ActionListWithWorkOrWorkCompleted.java
  16. 20 1
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/readcompleted/ReadCompletedAction.java
  17. 23 19
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/task/ActionListWithJob.java
  18. 18 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/task/TaskAction.java
  19. 61 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/taskcompleted/ActionListWithWorkOrWorkCompleted.java
  20. 19 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/taskcompleted/TaskCompletedAction.java
  21. 0 10
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/warp/BaseAction.java
  22. 71 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionCallback.java
  23. 336 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionGetWithWorkOrWorkCompleted.java
  24. 2 1
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageDeleteRelativeWork.java
  25. 2 1
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageDeleteSingleWork.java
  26. 2 1
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageGet.java
  27. 2 1
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageGetAssignment.java
  28. 2 1
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageListRelative.java
  29. 47 33
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/BaseAction.java
  30. 0 13
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ExceptionAccessDenied.java
  31. 19 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/WorkAction.java
  32. 254 0
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/worklog/ActionListWithWorkOrWorkCompleted.java
  33. 0 13
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/worklog/ExceptionAccessDenied.java
  34. 19 7
      o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/worklog/WorkLogAction.java
  35. 2 0
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/content/WorkCompleted.java
  36. 0 1
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/element/Manual.java
  37. 42 18
      o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/element/util/WorkLogTree.java
  38. 152 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/ActionCallback.java
  39. 12 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/ExceptionSplittingCannotCallback.java
  40. 18 0
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/WorkAction.java
  41. 2 4
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/AbstractBaseProcessor.java
  42. 4 3
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/AbstractProcessor.java
  43. 2 3
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/choice/ChoiceProcessor.java
  44. 11 5
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/merge/MergeProcessor.java
  45. 28 11
      o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/parallel/ParallelProcessor.java
  46. 7 2
      o2server/x_query_assemble_surface/src/main/java/com/x/query/assemble/surface/jaxrs/view/BaseAction.java

+ 213 - 445
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/Business.java

@@ -407,451 +407,6 @@ public class Business {
 		return file;
 	}
 
-	// public Control getControlOfWorkComplex(EffectivePerson effectivePerson,
-	// Work work) throws Exception {
-	// Control control = new Control();
-	// Activity activity = this.getActivity(work);
-	// List<Task> taskList = task().listWithWorkObject(work);
-	// Task task = null;
-	// for (int i = 0; i < taskList.size(); i++) {
-	// Task o = taskList.get(i);
-	// if (StringUtils.equals(o.getPerson(),
-	// effectivePerson.getDistinguishedName())) {
-	// task = o;
-	// break;
-	// }
-	// }
-	// List<Read> readList = read().listWithWorkObject(work);
-	// Read read = null;
-	// for (int i = 0; i < readList.size(); i++) {
-	// Read o = readList.get(i);
-	// if (StringUtils.equals(o.getPerson(),
-	// effectivePerson.getDistinguishedName())) {
-	// read = o;
-	// break;
-	// }
-	// }
-	// Application application = application().pick(work.getApplication());
-	// Process process = process().pick(work.getProcess());
-	// Long taskCompletedCount =
-	// taskCompleted().countWithPersonWithWork(effectivePerson.getDistinguishedName(),
-	// work);
-	// Long readCompletedCount =
-	// readCompleted().countWithPersonWithWork(effectivePerson.getDistinguishedName(),
-	// work);
-	// Long reviewCount =
-	// review().countWithPersonWithWork(effectivePerson.getDistinguishedName(),
-	// work);
-	// /* 工作是否可以打开(管理员 或 有task,taskCompleted,read,readCompleted,review的人) */
-	// control.setAllowVisit(false);
-	// /* 工作是否可以流转(有task的人) */
-	// control.setAllowProcessing(false);
-	// /* 工作是否可以处理待阅(有read的人) */
-	// control.setAllowReadProcessing(false);
-	// /* 工作是否可保存(管理员 或者 有本人的task) */
-	// control.setAllowSave(false);
-	// /* 工作是否可重置(有本人待办 并且 活动设置允许重置 */
-	// control.setAllowReset(false);
-	// /* 工作是否可以撤回(当前人是上一个处理人 并且 还没有其他人处理过) */
-	// control.setAllowRetract(false);
-	// /* 工作是否可调度(管理员 并且 此活动在流程设计中允许调度) */
-	// control.setAllowReroute(false);
-	// /* 工作是否可删除(管理员 或者 此活动在流程设计中允许删除且当前待办人是文件的创建者) */
-	// control.setAllowDelete(false);
-	// /* 设置allowVisit */
-	// if ((null != task) || (null != read) || (taskCompletedCount > 0) ||
-	// (readCompletedCount > 0)
-	// || (reviewCount > 0)) {
-	// control.setAllowVisit(true);
-	// } else if (effectivePerson.isUser(work.getCreatorPerson())) {
-	// control.setAllowVisit(true);
-	// } else if (this.canManageApplicationOrProcess(effectivePerson,
-	// application, process)) {
-	// control.setAllowVisit(true);
-	// }
-	// /* 设置allowProcessing */
-	// if (null != task) {
-	// control.setAllowProcessing(true);
-	// }
-	// /* 设置allowReadProcessing */
-	// if (null != read) {
-	// control.setAllowReadProcessing(true);
-	// }
-	// /* 设置 allowSave */
-	// if (null != task) {
-	// control.setAllowSave(true);
-	// } else if (this.canManageApplicationOrProcess(effectivePerson,
-	// application, process)) {
-	// control.setAllowSave(true);
-	// }
-	// /* 设置 allowReset */
-	// if (Objects.equals(activity.getActivityType(), ActivityType.manual)
-	// && BooleanUtils.isTrue(((Manual) activity).getAllowReset()) && null !=
-	// task) {
-	// control.setAllowReset(true);
-	// }
-	// /* 设置 allowRetract */
-	// if (Objects.equals(activity.getActivityType(), ActivityType.manual)
-	// && BooleanUtils.isTrue(((Manual) activity).getAllowRetract())) {
-	// /* 标志文件还没有处理过 */
-	// if (0 ==
-	// taskCompleted().countWithPersonWithActivityToken(effectivePerson.getDistinguishedName(),
-	// work.getActivityToken())) {
-	// /* 找到到达当前活动的workLog */
-	// WorkLog workLog =
-	// workLog().getWithArrivedActivityTokenObject(work.getActivityToken());
-	// if (null != workLog) {
-	// /* 查找上一个环节的已办,如果只有一个,且正好是当前人的,那么可以召回 */
-	// List<TaskCompleted> taskCompletedList = taskCompleted()
-	// .listWithActivityTokenObject(workLog.getFromActivityToken());
-	// if (taskCompletedList.size() == 1 &&
-	// StringUtils.equals(effectivePerson.getDistinguishedName(),
-	// taskCompletedList.get(0).getPerson())) {
-	// control.setAllowRetract(true);
-	// }
-	// }
-	// }
-	// }
-	// /* 设置 allowReroute */
-	// if (effectivePerson.isManager()) {
-	// /** 管理员可以调度 */
-	// control.setAllowReroute(true);
-	// } else if (organization().person().hasRole(effectivePerson,
-	// RoleDefinition.ProcessPlatformManager)) {
-	// /** 有流程管理角色的可以 */
-	// control.setAllowReroute(true);
-	// } else if (BooleanUtils.isTrue(activity.getAllowReroute())) {
-	// /** 如果活动设置了可以调度 */
-	// if ((null != process) &&
-	// effectivePerson.isUser(process.getControllerList())) {
-	// /** 如果是流程的管理员那么可以调度 */
-	// control.setAllowReroute(true);
-	// } else if ((null != application) &&
-	// effectivePerson.isUser(application.getControllerList())) {
-	// /** 如果是应用的管理员那么可以调度 */
-	// control.setAllowReroute(true);
-	// }
-	// }
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// } else if (Objects.equals(activity.getActivityType(),
-	// ActivityType.manual)
-	// && BooleanUtils.isTrue(((Manual) activity).getAllowDeleteWork())) {
-	// if (null != task && StringUtils.equals(work.getCreatorPerson(),
-	// effectivePerson.getDistinguishedName())) {
-	// control.setAllowDelete(true);
-	// }
-	// }
-	// return control;
-	// }
-	//
-	// /* 列表中简式权限 */
-	// public Control geatControlOfWorkList(EffectivePerson effectivePerson,
-	// Work work) throws Exception {
-	// Control control = new Control();
-	// /* 工作是否可以打开 */
-	// control.setAllowVisit(false);
-	// /* 工作是否可以直接流转work(是管理员,并且没有任何task) */
-	// control.setAllowProcessing(false);
-	// /* 是否可调度(管理员 并且 此活动在流程设计中允许调度) */
-	// control.setAllowReroute(false);
-	// /* 是否可删除(管理员 或者(此活动在流程设计中允许删除 并且 拟稿人是待办人)) */
-	// control.setAllowDelete(false);
-	// /* 活动节点可能为空 */
-	// Activity activity = this.getActivity(work);
-	// List<Task> taskList = task().listWithWorkObject(work);
-	// Task task = null;
-	// for (int i = 0; i < taskList.size(); i++) {
-	// Task o = taskList.get(i);
-	// if (StringUtils.equals(o.getPerson(),
-	// effectivePerson.getDistinguishedName())) {
-	// task = o;
-	// break;
-	// }
-	// }
-	// List<Read> readList = read().listWithWorkObject(work);
-	// Read read = null;
-	// for (int i = 0; i < readList.size(); i++) {
-	// Read o = readList.get(i);
-	// if (StringUtils.equals(o.getPerson(),
-	// effectivePerson.getDistinguishedName())) {
-	// read = o;
-	// break;
-	// }
-	// }
-	// Application application = application().pick(work.getApplication());
-	// Process process = process().pick(work.getProcess());
-	// Long taskCompletedCount =
-	// taskCompleted().countWithPersonWithWork(effectivePerson.getDistinguishedName(),
-	// work);
-	// Long readCompletedCount =
-	// readCompleted().countWithPersonWithWork(effectivePerson.getDistinguishedName(),
-	// work);
-	// Long reviewCount =
-	// review().countWithPersonWithWork(effectivePerson.getDistinguishedName(),
-	// work);
-	// /* 设置 allowVisit */
-	// if ((null != task) || (null != read) || (taskCompletedCount > 0) ||
-	// (readCompletedCount > 0)
-	// || (reviewCount > 0) ||
-	// this.canManageApplicationOrProcess(effectivePerson, application, process)
-	// || effectivePerson.isUser(work.getCreatorPerson())) {
-	// control.setAllowVisit(true);
-	// }
-	// /* 设置 allowProcessing */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// if (ListTools.isEmpty(taskList)) {
-	// control.setAllowProcessing(true);
-	// }
-	// }
-	// /* 设置 allowReroute */
-	// if (effectivePerson.isManager()) {
-	// /** 管理员可以调度 */
-	// control.setAllowReroute(true);
-	// } else if (organization().person().hasRole(effectivePerson,
-	// RoleDefinition.ProcessPlatformManager)) {
-	// /** 有流程管理角色的可以 */
-	// control.setAllowReroute(true);
-	// } else if (BooleanUtils.isTrue(activity.getAllowReroute())) {
-	// /** 如果活动设置了可以调度 */
-	// if ((null != process) &&
-	// effectivePerson.isUser(process.getControllerList())) {
-	// /** 如果是流程的管理员那么可以调度 */
-	// control.setAllowReroute(true);
-	// } else if ((null != application) &&
-	// effectivePerson.isUser(application.getControllerList())) {
-	// /** 如果是应用的管理员那么可以调度 */
-	// control.setAllowReroute(true);
-	// }
-	// }
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// } else if ((null != activity) &&
-	// Objects.equals(activity.getActivityType(), ActivityType.manual)
-	// && BooleanUtils.isTrue(((Manual) activity).getAllowDeleteWork())) {
-	// if (null != task && StringUtils.equals(work.getCreatorPerson(),
-	// effectivePerson.getDistinguishedName())) {
-	// control.setAllowDelete(true);
-	// }
-	// }
-	// return control;
-	// }
-
-	// public Control getControlOfTask(EffectivePerson effectivePerson, Task
-	// task) throws Exception {
-	// Control control = new Control();
-	// /* 是否可以直接流转(管理员),正常处理必须到complex界面. */
-	// control.setAllowProcessing(false);
-	// /* 是否可以重置处理人(管理员 或(本人待办并且活动设置允许重置)) */
-	// control.setAllowReset(false);
-	// /* 是否可删除(管理员) */
-	// control.setAllowDelete(false);
-	// Activity activity = this.getActivity(task.getActivity(),
-	// task.getActivityType());
-	// Application application = application().pick(task.getApplication());
-	// Process process = process().pick(task.getProcess());
-	// /* 设置allowProcessing */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowProcessing(true);
-	// }
-	// /* 设置 allowReset */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowReset(true);
-	// } else if (effectivePerson.isUser(task.getPerson())) {
-	// if (Objects.equals(activity.getActivityType(), ActivityType.manual)
-	// && BooleanUtils.isTrue(((Manual) activity).getAllowReset()) && null !=
-	// task) {
-	// control.setAllowReset(true);
-	// }
-	// }
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// }
-	// return control;
-	// }
-
-	// public Control getControlOfTaskCompleted(EffectivePerson effectivePerson,
-	// TaskCompleted taskCompleted)
-	// throws Exception {
-	// Control control = new Control();
-	// /* 是否可删除(管理员) */
-	// control.setAllowDelete(false);
-	// Application application =
-	// application().pick(taskCompleted.getApplication());
-	// Process process = process().pick(taskCompleted.getProcess());
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// }
-	// return control;
-	// }
-
-	// public Control getControlOfRead(EffectivePerson effectivePerson, Read
-	// read) throws Exception {
-	// Control control = new Control();
-	// /* 是否允许标志为已阅(管理员 或 待阅人本人) */
-	// control.setAllowProcessing(false);
-	// /* 是否允许重置待阅的处理人,只有管理员可以 */
-	// control.setAllowReadReset(false);
-	// /* 是否可删除(管理员) */
-	// control.setAllowDelete(false);
-	// Application application = application().pick(read.getApplication());
-	// Process process = process().pick(read.getProcess());
-	// /* 设置allowProcessing */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowProcessing(true);
-	// } else if (effectivePerson.isUser(read.getPerson())) {
-	// control.setAllowProcessing(true);
-	// }
-	// /* 设置 allowReadReset */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowReadReset(true);
-	// }
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// }
-	// return control;
-	//
-	// }
-
-	// public Control getControlOfReadCompleted(EffectivePerson effectivePerson,
-	// ReadCompleted readCompleted)
-	// throws Exception {
-	// Control control = new Control();
-	// // 是否可删除(管理员)
-	// control.setAllowDelete(false);
-	// Application application =
-	// application().pick(readCompleted.getApplication());
-	// Process process = process().pick(readCompleted.getProcess());
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// }
-	// return control;
-	// }
-
-	// public Control getControlOfReview(EffectivePerson effectivePerson, Review
-	// review) throws Exception {
-	// Control control = new Control();
-	// // 是否可删除(管理员)
-	// control.setAllowDelete(false);
-	// Application application = application().pick(review.getApplication());
-	// Process process = process().pick(review.getProcess());
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// }
-	// return control;
-	// }
-
-	// public Control getControlOfWorkCompleted(EffectivePerson effectivePerson,
-	// WorkCompleted workCompleted)
-	// throws Exception {
-	// Control control = new Control();
-	// /* 完成工作是否可见:管理员或者有taskCompleted,或者有read,或者有readCompleted或者有review */
-	// control.setAllowVisit(false);
-	// /* 完成工作是否有待阅需要处理:当前人是否有待阅 */
-	// control.setAllowReadProcessing(false);
-	// /* 完成工作是否可以删除:管理员 */
-	// control.setAllowDelete(false);
-	// Application application =
-	// application().pick(workCompleted.getApplication());
-	// Process process = process().pick(workCompleted.getProcess());
-	// /* 设置 allowViist */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowVisit(true);
-	// } else if (effectivePerson.isUser(workCompleted.getCreatorPerson())) {
-	// control.setAllowVisit(true);
-	// } else if
-	// (taskCompleted().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowVisit(true);
-	// } else if
-	// (read().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowVisit(true);
-	// } else if
-	// (readCompleted().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowVisit(true);
-	// } else if
-	// (review().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowVisit(true);
-	// }
-	// /* 设置 allowReadProcessing */
-	// if
-	// (read().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowReadProcessing(true);
-	// }
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// }
-	// return control;
-	// }
-
-	// public Control getControlOfWorkCompletedList(EffectivePerson
-	// effectivePerson, WorkCompleted workCompleted)
-	// throws Exception {
-	// Control control = new Control();
-	// /* 完成工作是否可见:管理员或者有taskCompleted,或者有read,或者有readCompleted或者有review */
-	// control.setAllowVisit(false);
-	// /* 完成工作是否可以删除:管理员 */
-	// control.setAllowDelete(false);
-	// Application application =
-	// application().pick(workCompleted.getApplication());
-	// Process process = process().pick(workCompleted.getProcess());
-	// /* 设置 allowViist */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowVisit(true);
-	// } else if (effectivePerson.isUser(workCompleted.getCreatorPerson())) {
-	// control.setAllowVisit(true);
-	// } else if
-	// (taskCompleted().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowVisit(true);
-	// } else if
-	// (read().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowVisit(true);
-	// } else if
-	// (readCompleted().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowVisit(true);
-	// } else if
-	// (review().countWithPersonWithWorkCompleted(effectivePerson.getDistinguishedName(),
-	// workCompleted) > 0) {
-	// control.setAllowVisit(true);
-	// }
-	// /* 设置 allowDelete */
-	// if (this.canManageApplicationOrProcess(effectivePerson, application,
-	// process)) {
-	// control.setAllowDelete(true);
-	// }
-	// return control;
-	// }
-
 	public Activity getActivity(Work work) throws Exception {
 		return this.getActivity(work.getActivity(), work.getActivityType());
 	}
@@ -923,6 +478,13 @@ public class Business {
 		return false;
 	}
 
+	public Boolean canManageApplicationOrProcess(EffectivePerson effectivePerson, String applicationId,
+			String processId) throws Exception {
+		Application application = this.application().pick(applicationId);
+		Process process = this.process().pick(processId);
+		return this.canManageApplicationOrProcess(effectivePerson, application, process);
+	}
+
 	public Boolean canManageApplicationOrProcess(EffectivePerson effectivePerson, Application application,
 			Process process) throws Exception {
 		if (effectivePerson.isManager()) {
@@ -1347,6 +909,212 @@ public class Business {
 		return false;
 	}
 
+	public boolean readable(EffectivePerson effectivePerson, Work work) throws Exception {
+		if (null == work) {
+			return false;
+		}
+		if (effectivePerson.isUser(work.getCreatorPerson())) {
+			return true;
+		}
+		if (effectivePerson.isManager()) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(TaskCompleted.class, TaskCompleted.person_FIELDNAME,
+				effectivePerson.getDistinguishedName(), TaskCompleted.job_FIELDNAME, work.getJob()) > 0) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(ReadCompleted.class, ReadCompleted.person_FIELDNAME,
+				effectivePerson.getDistinguishedName(), ReadCompleted.job_FIELDNAME, work.getJob()) > 0) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(Task.class, Task.person_FIELDNAME, effectivePerson.getDistinguishedName(),
+				Task.job_FIELDNAME, work.getJob()) > 0) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(Read.class, Read.person_FIELDNAME, effectivePerson.getDistinguishedName(),
+				Read.job_FIELDNAME, work.getJob()) > 0) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(Review.class, Review.person_FIELDNAME, effectivePerson.getDistinguishedName(),
+				Review.job_FIELDNAME, work.getJob()) > 0) {
+			return true;
+		}
+		if (organization().person().hasRole(effectivePerson, OrganizationDefinition.Manager,
+				OrganizationDefinition.ProcessPlatformManager)) {
+			return true;
+		}
+		Application application = this.application().pick(work.getApplication());
+		if (null != application) {
+			if (effectivePerson.isUser(application.getControllerList())) {
+				return true;
+			}
+		}
+		Process process = this.process().pick(work.getProcess());
+		if (null != process) {
+			if (effectivePerson.isUser(process.getControllerList())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public boolean readable(EffectivePerson effectivePerson, WorkCompleted workCompleted) throws Exception {
+		if (null == workCompleted) {
+			return false;
+		}
+		if (effectivePerson.isUser(workCompleted.getCreatorPerson())) {
+			return true;
+		}
+		if (effectivePerson.isManager()) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(TaskCompleted.class, TaskCompleted.person_FIELDNAME,
+				effectivePerson.getDistinguishedName(), TaskCompleted.job_FIELDNAME, workCompleted.getJob()) > 0) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(ReadCompleted.class, ReadCompleted.person_FIELDNAME,
+				effectivePerson.getDistinguishedName(), ReadCompleted.job_FIELDNAME, workCompleted.getJob()) > 0) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(Read.class, Read.person_FIELDNAME, effectivePerson.getDistinguishedName(),
+				Read.job_FIELDNAME, workCompleted.getJob()) > 0) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(Review.class, Review.person_FIELDNAME, effectivePerson.getDistinguishedName(),
+				Review.job_FIELDNAME, workCompleted.getJob()) > 0) {
+			return true;
+		}
+		if (organization().person().hasRole(effectivePerson, OrganizationDefinition.Manager,
+				OrganizationDefinition.ProcessPlatformManager)) {
+			return true;
+		}
+		Application application = this.application().pick(workCompleted.getApplication());
+		if (null != application) {
+			if (effectivePerson.isUser(application.getControllerList())) {
+				return true;
+			}
+		}
+		Process process = this.process().pick(workCompleted.getProcess());
+		if (null != process) {
+			if (effectivePerson.isUser(process.getControllerList())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public boolean readableWithWorkOrWorkCompleted(EffectivePerson effectivePerson, String workOrWorkCompleted)
+			throws Exception {
+		Work work = emc.fetch(workOrWorkCompleted, Work.class, ListTools.toList(Work.job_FIELDNAME,
+				Work.application_FIELDNAME, Work.process_FIELDNAME, Work.creatorPerson_FIELDNAME));
+		WorkCompleted workCompleted = null;
+		String job = null;
+		String creatorPerson = null;
+		String applicationId = null;
+		String processId = null;
+		if (null == work) {
+			workCompleted = emc.fetch(workOrWorkCompleted, WorkCompleted.class, ListTools.toList(Work.job_FIELDNAME,
+					Work.application_FIELDNAME, Work.process_FIELDNAME, Work.creatorPerson_FIELDNAME));
+			if (null == workCompleted) {
+				List<WorkCompleted> os = emc.fetchEqual(WorkCompleted.class,
+						ListTools.toList(WorkCompleted.job_FIELDNAME, WorkCompleted.application_FIELDNAME,
+								WorkCompleted.process_FIELDNAME, WorkCompleted.creatorPerson_FIELDNAME),
+						WorkCompleted.work_FIELDNAME, workOrWorkCompleted);
+				if (os.size() == 1) {
+					workCompleted = os.get(0);
+				}
+			}
+			if (null != workCompleted) {
+				job = workCompleted.getJob();
+				creatorPerson = workCompleted.getCreatorPerson();
+				applicationId = workCompleted.getApplication();
+				processId = workCompleted.getProcess();
+			}
+		} else {
+			job = work.getJob();
+			creatorPerson = work.getCreatorPerson();
+			applicationId = work.getApplication();
+			processId = work.getProcess();
+		}
+		if (StringUtils.isEmpty(job)) {
+			return false;
+		}
+		if (effectivePerson.isUser(creatorPerson)) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(TaskCompleted.class, TaskCompleted.person_FIELDNAME,
+				effectivePerson.getDistinguishedName(), TaskCompleted.job_FIELDNAME, job) == 0) {
+			if (emc.countEqualAndEqual(ReadCompleted.class, ReadCompleted.person_FIELDNAME,
+					effectivePerson.getDistinguishedName(), ReadCompleted.job_FIELDNAME, job) == 0) {
+				if (emc.countEqualAndEqual(Task.class, Task.person_FIELDNAME, effectivePerson.getDistinguishedName(),
+						Task.job_FIELDNAME, job) == 0) {
+					if (emc.countEqualAndEqual(Read.class, Read.person_FIELDNAME,
+							effectivePerson.getDistinguishedName(), Read.job_FIELDNAME, job) == 0) {
+						if (emc.countEqualAndEqual(Review.class, Review.person_FIELDNAME,
+								effectivePerson.getDistinguishedName(), Review.job_FIELDNAME, job) == 0) {
+							Application application = application().pick(applicationId);
+							Process process = process().pick(processId);
+							if (!canManageApplicationOrProcess(effectivePerson, application, process)) {
+								return false;
+							}
+						}
+					}
+				}
+			}
+		}
+		return true;
+	}
+
+	public boolean readableWithJob(EffectivePerson effectivePerson, String job) throws Exception {
+		String creatorPerson = null;
+		String applicationId = null;
+		String processId = null;
+		List<Work> works = emc.fetchEqual(Work.class,
+				ListTools.toList(Work.application_FIELDNAME, Work.process_FIELDNAME, Work.creatorPerson_FIELDNAME),
+				Work.job_FIELDNAME, job);
+		if (works.isEmpty()) {
+			List<WorkCompleted> workCompleteds = emc.fetchEqual(
+					WorkCompleted.class, ListTools.toList(WorkCompleted.application_FIELDNAME,
+							WorkCompleted.process_FIELDNAME, WorkCompleted.creatorPerson_FIELDNAME),
+					WorkCompleted.job_FIELDNAME, job);
+			if (workCompleteds.isEmpty()) {
+				return false;
+			} else {
+				creatorPerson = workCompleteds.get(0).getCreatorPerson();
+				applicationId = workCompleteds.get(0).getApplication();
+				processId = workCompleteds.get(0).getProcess();
+			}
+		} else {
+			creatorPerson = works.get(0).getCreatorPerson();
+			applicationId = works.get(0).getApplication();
+			processId = works.get(0).getProcess();
+		}
+		if (effectivePerson.isUser(creatorPerson)) {
+			return true;
+		}
+		if (emc.countEqualAndEqual(TaskCompleted.class, TaskCompleted.person_FIELDNAME,
+				effectivePerson.getDistinguishedName(), TaskCompleted.job_FIELDNAME, job) == 0) {
+			if (emc.countEqualAndEqual(ReadCompleted.class, ReadCompleted.person_FIELDNAME,
+					effectivePerson.getDistinguishedName(), ReadCompleted.job_FIELDNAME, job) == 0) {
+				if (emc.countEqualAndEqual(Task.class, Task.person_FIELDNAME, effectivePerson.getDistinguishedName(),
+						Task.job_FIELDNAME, job) == 0) {
+					if (emc.countEqualAndEqual(Read.class, Read.person_FIELDNAME,
+							effectivePerson.getDistinguishedName(), Read.job_FIELDNAME, job) == 0) {
+						if (emc.countEqualAndEqual(Review.class, Review.person_FIELDNAME,
+								effectivePerson.getDistinguishedName(), Review.job_FIELDNAME, job) == 0) {
+							Application application = application().pick(applicationId);
+							Process process = process().pick(processId);
+							if (!canManageApplicationOrProcess(effectivePerson, application, process)) {
+								return false;
+							}
+						}
+					}
+				}
+			}
+		}
+		return true;
+	}
+
 	public boolean controllerable(Business business, EffectivePerson effectivePerson, Application application,
 			Process process, Attachment attachment) throws Exception {
 		if (ListTools.isEmpty(attachment.getControllerIdentityList(), attachment.getControllerUnitList())) {

+ 27 - 1
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/factory/content/JobFactory.java

@@ -1,7 +1,14 @@
 package com.x.processplatform.assemble.surface.factory.content;
 
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.tools.ListTools;
 import com.x.processplatform.assemble.surface.AbstractFactory;
 import com.x.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.content.WorkCompleted;
 
 public class JobFactory extends AbstractFactory {
 
@@ -13,4 +20,23 @@ public class JobFactory extends AbstractFactory {
 		Business business = this.business();
 		return (business.work().countWithJob(job) + business.workCompleted().countWithJob(job)) > 1 ? true : false;
 	}
-}
+
+	public String findWithWorkOrWorkCompleted(String workOrWorkCompleted) throws Exception {
+		Work work = this.entityManagerContainer().fetch(workOrWorkCompleted, Work.class,
+				ListTools.toList(Work.job_FIELDNAME));
+		if (null != work) {
+			return work.getJob();
+		}
+		WorkCompleted workCompleted = this.entityManagerContainer().fetch(workOrWorkCompleted, WorkCompleted.class,
+				ListTools.toList(WorkCompleted.job_FIELDNAME));
+		if (null != workCompleted) {
+			return workCompleted.getJob();
+		}
+		List<WorkCompleted> os = this.entityManagerContainer().fetchEqual(WorkCompleted.class,
+				ListTools.toList(Work.job_FIELDNAME), WorkCompleted.work_FIELDNAME, workOrWorkCompleted);
+		if (os.size() == 1) {
+			return os.get(0).getJob();
+		}
+		return null;
+	}
+}

+ 2 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/ActionApplication.java

@@ -8,6 +8,7 @@ import com.x.base.core.project.jaxrs.AbstractActionApplication;
 import com.x.processplatform.assemble.surface.jaxrs.application.ApplicationAction;
 import com.x.processplatform.assemble.surface.jaxrs.applicationdict.ApplicationDictAction;
 import com.x.processplatform.assemble.surface.jaxrs.attachment.AttachmentAction;
+import com.x.processplatform.assemble.surface.jaxrs.control.ControlAction;
 import com.x.processplatform.assemble.surface.jaxrs.data.DataAction;
 import com.x.processplatform.assemble.surface.jaxrs.file.FileAction;
 import com.x.processplatform.assemble.surface.jaxrs.form.FormAction;
@@ -57,6 +58,7 @@ public class ActionApplication extends AbstractActionApplication {
 		classes.add(FormAction.class);
 		classes.add(UtilAction.class);
 		classes.add(WorkLogAction.class);
+		classes.add(ControlAction.class);
 		return classes;
 	}
 }

+ 10 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/ControlJaxrsFilter.java

@@ -0,0 +1,10 @@
+package com.x.processplatform.assemble.surface.jaxrs;
+
+import javax.servlet.annotation.WebFilter;
+
+import com.x.base.core.project.jaxrs.CipherManagerUserJaxrsFilter;
+
+@WebFilter(urlPatterns = "/jaxrs/control/*", asyncSupported = true)
+public class ControlJaxrsFilter extends CipherManagerUserJaxrsFilter {
+
+}

+ 148 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/attachment/ActionListWithWorkOrWorkCompleted.java

@@ -0,0 +1,148 @@
+package com.x.processplatform.assemble.surface.jaxrs.attachment;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+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;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+import com.x.base.core.project.gson.GsonPropertyObject;
+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.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.Attachment;
+
+class ActionListWithWorkOrWorkCompleted extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionListWithWorkOrWorkCompleted.class);
+
+	ActionResult<List<Wo>> execute(EffectivePerson effectivePerson, String workOrWorkCompleted) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<List<Wo>> result = new ActionResult<>();
+
+			Business business = new Business(emc);
+
+			if (!business.readableWithWorkOrWorkCompleted(effectivePerson, workOrWorkCompleted)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+
+			List<String> identities = business.organization().identity().listWithPerson(effectivePerson);
+
+			List<String> units = business.organization().unit().listWithPerson(effectivePerson);
+
+			final String job = business.job().findWithWorkOrWorkCompleted(workOrWorkCompleted);
+
+			List<Wo> wos = this.list(business, job);
+
+			for (Wo wo : wos) {
+				this.read(wo, identities, units);
+				this.edit(wo, identities, units);
+				this.control(wo, effectivePerson, identities, units);
+			}
+
+			wos = wos.stream().sorted(Comparator.comparing(Wo::getCreateTime)).collect(Collectors.toList());
+
+			result.setData(wos);
+			return result;
+		}
+	}
+
+	private void read(Wo wo, List<String> identities, List<String> units) throws Exception {
+		if (ListTools.isEmpty(wo.getReadIdentityList()) && ListTools.isEmpty(wo.getReadUnitList())) {
+			wo.getControl().setAllowRead(true);
+		} else {
+			if (ListTools.containsAny(identities, wo.getReadIdentityList())
+					|| ListTools.containsAny(identities, wo.getReadUnitList())) {
+				wo.getControl().setAllowRead(true);
+			}
+		}
+	}
+
+	private void edit(Wo wo, List<String> identities, List<String> units) throws Exception {
+		if (ListTools.isEmpty(wo.getEditIdentityList()) && ListTools.isEmpty(wo.getEditUnitList())) {
+			wo.getControl().setAllowEdit(true);
+		} else {
+			if (ListTools.containsAny(identities, wo.getEditIdentityList())
+					|| ListTools.containsAny(identities, wo.getEditUnitList())) {
+				wo.getControl().setAllowEdit(true);
+			}
+		}
+	}
+
+	private void control(Wo wo, EffectivePerson effectivePerson, List<String> identities, List<String> units)
+			throws Exception {
+		if (ListTools.containsAny(identities, wo.getControllerIdentityList())
+				|| ListTools.containsAny(identities, wo.getControllerUnitList())) {
+			wo.getControl().setAllowControl(true);
+		}
+		if (effectivePerson.isUser(wo.getPerson())) {
+			wo.getControl().setAllowControl(true);
+		}
+	}
+
+	private List<Wo> list(Business business, String job) throws Exception {
+		List<Attachment> os = business.entityManagerContainer().listEqual(Attachment.class, Attachment.job_FIELDNAME,
+				job);
+		List<Wo> wos = Wo.copier.copy(os);
+		return wos;
+	}
+
+	public static class Wo extends Attachment {
+
+		private static final long serialVersionUID = -7666329770246726197L;
+
+		static WrapCopier<Attachment, Wo> copier = WrapCopierFactory.wo(Attachment.class, Wo.class, null,
+				JpaObject.FieldsInvisible);
+
+		private WoControl control = new WoControl();
+
+		public WoControl getControl() {
+			return control;
+		}
+
+		public void setControl(WoControl control) {
+			this.control = control;
+		}
+
+	}
+
+	public static class WoControl extends GsonPropertyObject {
+
+		private Boolean allowRead = false;
+		private Boolean allowEdit = false;
+		private Boolean allowControl = false;
+
+		public Boolean getAllowRead() {
+			return allowRead;
+		}
+
+		public void setAllowRead(Boolean allowRead) {
+			this.allowRead = allowRead;
+		}
+
+		public Boolean getAllowEdit() {
+			return allowEdit;
+		}
+
+		public void setAllowEdit(Boolean allowEdit) {
+			this.allowEdit = allowEdit;
+		}
+
+		public Boolean getAllowControl() {
+			return allowControl;
+		}
+
+		public void setAllowControl(Boolean allowControl) {
+			this.allowControl = allowControl;
+		}
+
+	}
+
+}

+ 19 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/attachment/AttachmentAction.java

@@ -129,6 +129,25 @@ public class AttachmentAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
 	}
 
+	@JaxrsMethodDescribe(value = "根据工作或已完成工作获取Attachment列表.", action = ActionListWithWorkOrWorkCompleted.class)
+	@GET
+	@Path("list/workorworkcompleted/{workOrWorkCompleted}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void listWithWorkOrWorkCompleted(@Suspended final AsyncResponse asyncResponse,
+			@Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作或已完成工作标识") @PathParam("workOrWorkCompleted") String workOrWorkCompleted) {
+		ActionResult<List<ActionListWithWorkOrWorkCompleted.Wo>> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionListWithWorkOrWorkCompleted().execute(effectivePerson, workOrWorkCompleted);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
 	@JaxrsMethodDescribe(value = "删除指定work下的附件.", action = ActionDelete.class)
 	@DELETE
 	@Path("{id}/work/{workId}")

+ 197 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/control/ActionGetWorkOrWorkCompleted.java

@@ -0,0 +1,197 @@
+package com.x.processplatform.assemble.surface.jaxrs.control;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.BooleanUtils;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+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.PropertyTools;
+import com.x.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.Read;
+import com.x.processplatform.core.entity.content.Task;
+import com.x.processplatform.core.entity.content.TaskCompleted;
+import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.content.WorkCompleted;
+import com.x.processplatform.core.entity.content.WorkLog;
+import com.x.processplatform.core.entity.element.Activity;
+import com.x.processplatform.core.entity.element.ActivityType;
+import com.x.processplatform.core.entity.element.Manual;
+import com.x.processplatform.core.entity.element.util.WorkLogTree;
+import com.x.processplatform.core.entity.element.util.WorkLogTree.Node;
+
+class ActionGetWorkOrWorkCompleted extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionGetWorkOrWorkCompleted.class);
+
+	private Boolean canManageApplicationOrProcess = null;
+
+	private WorkLogTree workLogTree = null;
+
+	private Boolean hasReadWithJob = null;
+
+	private Boolean hasTaskWithWork = null;
+
+	private Map<String, Boolean> hasTaskCompletedWithActivityToken = new HashMap<>();
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String workOrWorkCompleted) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<Wo> result = new ActionResult<>();
+
+			Business business = new Business(emc);
+
+			if (!business.readableWithWorkOrWorkCompleted(effectivePerson, workOrWorkCompleted)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+
+			Wo wo = null;
+
+			Work work = emc.find(workOrWorkCompleted, Work.class);
+
+			if (null != work) {
+				wo = this.work(business, effectivePerson, work);
+			} else {
+				wo = this.workCompleted(business, effectivePerson, emc.flag(workOrWorkCompleted, WorkCompleted.class));
+			}
+
+			result.setData(wo);
+			return result;
+		}
+	}
+
+	private Wo workCompleted(Business business, EffectivePerson effectivePerson, WorkCompleted workCompleted)
+			throws Exception {
+		Wo wo = new Wo();
+		wo.setAllowVisit(true);
+		wo.setAllowReadProcessing(this.hasReadWithJob(business, effectivePerson, workCompleted.getJob()));
+		wo.setAllowRollback(this.canManageApplicationOrProcess(business, effectivePerson,
+				workCompleted.getApplication(), workCompleted.getProcess()));
+		return wo;
+	}
+
+	private Wo work(Business business, EffectivePerson effectivePerson, Work work) throws Exception {
+
+		Wo wo = new Wo();
+
+		Activity activity = business.getActivity(work);
+
+		/* 是否可以看到 */
+		wo.setAllowVisit(true);
+		/* 是否可以直接流转 */
+		wo.setAllowProcessing(this.hasTaskWithWork(business, effectivePerson, work.getId()));
+		/* 是否可以处理待阅 */
+		wo.setAllowReadProcessing(this.hasReadWithJob(business, effectivePerson, work.getJob()));
+		/* 是否可以保存数据 */
+		wo.setAllowSave(
+				this.canManageApplicationOrProcess(business, effectivePerson, work.getApplication(), work.getProcess())
+						|| this.hasTaskWithWork(business, effectivePerson, work.getId()));
+		/* 是否可以重置处理人 */
+		wo.setAllowReset(PropertyTools.getOrElse(activity, Manual.allowReset_FIELDNAME, Boolean.class, false)
+				&& wo.getAllowSave());
+
+		/* 是否可以调度 */
+		wo.setAllowReroute(PropertyTools.getOrElse(activity, Manual.allowReroute_FIELDNAME, Boolean.class, false)
+				&& this.canManageApplicationOrProcess(business, effectivePerson, work.getApplication(),
+						work.getProcess()));
+
+		/* 是否可以删除 */
+		wo.setAllowDelete(PropertyTools.getOrElse(activity, Manual.allowDeleteWork_FIELDNAME, Boolean.class, false)
+				&& wo.getAllowSave());
+
+		/* 是否可以增加会签分支 */
+		if (PropertyTools.getOrElse(activity, Manual.allowAddSplit_FIELDNAME, Boolean.class, false)) {
+			Node node = this.workLogTree(business, work.getJob()).location(work);
+			if (null != node) {
+				Node up = node.upTo(ActivityType.manual, ActivityType.agent, ActivityType.choice, ActivityType.delay,
+						ActivityType.embed, ActivityType.invoke);
+				if (null != up) {
+					wo.setAllowAddSplit(
+							this.hasTaskCompletedWithActivityToken(business, effectivePerson, work.getActivityToken())
+									&& BooleanUtils.isTrue(work.getSplitting()));
+				}
+			}
+		}
+		/* 是否可以召回 */
+		if (PropertyTools.getOrElse(activity, Manual.allowRetract_FIELDNAME, Boolean.class, false)) {
+			Node node = this.workLogTree(business, work.getJob()).location(work);
+			if (null != node) {
+				Node up = node.upTo(ActivityType.manual, ActivityType.agent, ActivityType.choice, ActivityType.delay,
+						ActivityType.embed, ActivityType.invoke);
+				if (null != up) {
+					wo.setAllowRetract(
+							this.hasTaskCompletedWithActivityToken(business, effectivePerson, work.getActivityToken())
+									&& this.canManageApplicationOrProcess(business, effectivePerson,
+											work.getApplication(), work.getProcess()));
+				}
+			}
+		}
+		/* 是否可以回滚 */
+		wo.setAllowRollback(PropertyTools.getOrElse(activity, Manual.allowRollback_FIELDNAME, Boolean.class, false)
+				&& this.canManageApplicationOrProcess(business, effectivePerson, work.getApplication(),
+						work.getProcess()));
+		/* 是否可以看到 */
+		wo.setAllowVisit(true);
+
+		return wo;
+
+	}
+
+	private boolean hasTaskCompletedWithActivityToken(Business business, EffectivePerson effectivePerson,
+			String activityToken) throws Exception {
+		Boolean o = this.hasTaskCompletedWithActivityToken.get(activityToken);
+		if (null == o) {
+			o = business.entityManagerContainer().countEqualAndEqual(TaskCompleted.class,
+					TaskCompleted.person_FIELDNAME, effectivePerson.getDistinguishedName(),
+					TaskCompleted.activityToken_FIELDNAME, activityToken) > 0;
+			this.hasTaskCompletedWithActivityToken.put(activityToken, o);
+		}
+		return o;
+	}
+
+	private boolean hasTaskWithWork(Business business, EffectivePerson effectivePerson, String work) throws Exception {
+		if (null == this.hasTaskWithWork) {
+			this.hasTaskWithWork = business.entityManagerContainer().countEqualAndEqual(Task.class,
+					Task.person_FIELDNAME, effectivePerson.getDistinguishedName(), Task.work_FIELDNAME, work) > 0;
+		}
+		return this.hasTaskWithWork;
+	}
+
+	private boolean hasReadWithJob(Business business, EffectivePerson effectivePerson, String job) throws Exception {
+		if (null == this.hasReadWithJob) {
+			this.hasReadWithJob = business.entityManagerContainer().countEqualAndEqual(Read.class,
+					Read.person_FIELDNAME, effectivePerson.getDistinguishedName(), Read.job_FIELDNAME, job) > 0;
+		}
+		return this.hasReadWithJob;
+	}
+
+	private WorkLogTree workLogTree(Business business, String job) throws Exception {
+		if (null == this.workLogTree) {
+			this.workLogTree = new WorkLogTree(business.entityManagerContainer().fetchEqual(WorkLog.class,
+					ListTools.toList(WorkLog.arrivedActivityToken_FIELDNAME, WorkLog.arrivedActivityType_FIELDNAME,
+							WorkLog.fromActivityToken_FIELDNAME, WorkLog.fromActivityType_FIELDNAME),
+					WorkLog.job_FIELDNAME, job));
+		}
+		return this.workLogTree;
+	}
+
+	private boolean canManageApplicationOrProcess(Business business, EffectivePerson effectivePerson,
+			String application, String process) throws Exception {
+		if (null == canManageApplicationOrProcess) {
+			this.canManageApplicationOrProcess = business.canManageApplicationOrProcess(effectivePerson, application,
+					process);
+		}
+		return this.canManageApplicationOrProcess;
+	}
+
+	public static class Wo extends Control {
+
+	}
+
+}

+ 112 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/control/BaseAction.java

@@ -0,0 +1,112 @@
+package com.x.processplatform.assemble.surface.jaxrs.control;
+
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+
+abstract class BaseAction extends StandardJaxrsAction {
+
+	public static class Control extends GsonPropertyObject {
+		/* 是否可以看到 */
+		private Boolean allowVisit = false;
+		/* 是否可以直接流转 */
+		private Boolean allowProcessing = false;
+		/* 是否可以处理待阅 */
+		private Boolean allowReadProcessing = false;
+		/* 是否可以保存数据 */
+		private Boolean allowSave = false;
+		/* 是否可以重置处理人 */
+		private Boolean allowReset = false;
+		/* 是否可以调度 */
+		private Boolean allowReroute = false;
+		/* 是否可以删除 */
+		private Boolean allowDelete = false;
+		/* 是否可以增加会签分支 */
+		private Boolean allowAddSplit = false;
+		/* 是否可以召回 */
+		private Boolean allowRetract = false;
+		/* 是否可以回滚 */
+		private Boolean allowRollback = false;
+
+		public Boolean getAllowSave() {
+			return allowSave;
+		}
+
+		public void setAllowSave(Boolean allowSave) {
+			this.allowSave = allowSave;
+		}
+
+		public Boolean getAllowReset() {
+			return allowReset;
+		}
+
+		public void setAllowReset(Boolean allowReset) {
+			this.allowReset = allowReset;
+		}
+
+		public Boolean getAllowRetract() {
+			return allowRetract;
+		}
+
+		public void setAllowRetract(Boolean allowRetract) {
+			this.allowRetract = allowRetract;
+		}
+
+		public Boolean getAllowReroute() {
+			return allowReroute;
+		}
+
+		public void setAllowReroute(Boolean allowReroute) {
+			this.allowReroute = allowReroute;
+		}
+
+		public Boolean getAllowProcessing() {
+			return allowProcessing;
+		}
+
+		public void setAllowProcessing(Boolean allowProcessing) {
+			this.allowProcessing = allowProcessing;
+		}
+
+		public Boolean getAllowDelete() {
+			return allowDelete;
+		}
+
+		public void setAllowDelete(Boolean allowDelete) {
+			this.allowDelete = allowDelete;
+		}
+
+		public Boolean getAllowVisit() {
+			return allowVisit;
+		}
+
+		public void setAllowVisit(Boolean allowVisit) {
+			this.allowVisit = allowVisit;
+		}
+
+		public Boolean getAllowReadProcessing() {
+			return allowReadProcessing;
+		}
+
+		public void setAllowReadProcessing(Boolean allowReadProcessing) {
+			this.allowReadProcessing = allowReadProcessing;
+		}
+
+		public Boolean getAllowAddSplit() {
+			return allowAddSplit;
+		}
+
+		public void setAllowAddSplit(Boolean allowAddSplit) {
+			this.allowAddSplit = allowAddSplit;
+		}
+
+		public Boolean getAllowRollback() {
+			return allowRollback;
+		}
+
+		public void setAllowRollback(Boolean allowRollback) {
+			this.allowRollback = allowRollback;
+		}
+
+	}
+
+}

+ 10 - 9
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/warp/WrapAction.java → o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/control/ControlAction.java

@@ -1,4 +1,4 @@
-package com.x.processplatform.assemble.surface.jaxrs.warp;
+package com.x.processplatform.assemble.surface.jaxrs.control;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
@@ -22,23 +22,24 @@ 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("wrap")
-@JaxrsDescribe("包装接口")
-public class WrapAction extends StandardJaxrsAction {
+@Path("control")
+@JaxrsDescribe("权限接口")
+public class ControlAction extends StandardJaxrsAction {
 
-	private static Logger logger = LoggerFactory.getLogger(WrapAction.class);
+	private static Logger logger = LoggerFactory.getLogger(ControlAction.class);
 
-	@JaxrsMethodDescribe(value = "列示指定流程当前用户的Task对象,上一页.", action = ActionGetWorkOrWorkCompleted.class)
+	@JaxrsMethodDescribe(value = "根据工作或完成工作获取权限.", action = ActionGetWorkOrWorkCompleted.class)
 	@GET
-	@Path("work/or/workcompleted/{flag}")
+	@Path("workorworkcompleted/{workOrWorkCompleted}")
 	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
 	@Consumes(MediaType.APPLICATION_JSON)
 	public void getWorkOrWorkCompleted(@Suspended final AsyncResponse asyncResponse,
-			@Context HttpServletRequest request, @JaxrsParameterDescribe("标识") @PathParam("flag") String flag) {
+			@Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作或已完成工作标识") @PathParam("workOrWorkCompleted") String workOrWorkCompleted) {
 		ActionResult<ActionGetWorkOrWorkCompleted.Wo> result = new ActionResult<>();
 		EffectivePerson effectivePerson = this.effectivePerson(request);
 		try {
-			result = new ActionGetWorkOrWorkCompleted().execute(effectivePerson, flag);
+			result = new ActionGetWorkOrWorkCompleted().execute(effectivePerson, workOrWorkCompleted);
 		} catch (Exception e) {
 			logger.error(e, effectivePerson, request, null);
 			result.error(e);

+ 15 - 11
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/ActionGet.java

@@ -2,10 +2,8 @@ package com.x.processplatform.assemble.surface.jaxrs.form;
 
 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;
 import com.x.base.core.project.exception.ExceptionEntityNotExist;
+import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.processplatform.assemble.surface.Business;
@@ -13,26 +11,32 @@ import com.x.processplatform.core.entity.element.Form;
 
 class ActionGet extends BaseAction {
 
-	ActionResult<Wo> execute(EffectivePerson effectivePerson, String id) throws Exception {
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String flag) throws Exception {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			ActionResult<Wo> result = new ActionResult<>();
 			Business business = new Business(emc);
-			Form form = business.form().pick(id);
+			Form form = business.form().pick(flag);
 			if (null == form) {
-				throw new ExceptionEntityNotExist(id, Form.class);
+				throw new ExceptionEntityNotExist(flag, Form.class);
 			}
-			Wo wo = Wo.copier.copy(form);
+			Wo wo = new Wo();
+			wo.setData(form.getDataOrMobileData());
 			result.setData(wo);
 			return result;
 		}
 	}
 
-	public static class Wo extends Form {
+	public static class Wo extends GsonPropertyObject {
 
-		private static final long serialVersionUID = 1541438199059150837L;
+		private String data;
 
-		static WrapCopier<Form, Wo> copier = WrapCopierFactory.wo(Form.class, Wo.class, null,
-				JpaObject.FieldsInvisible);
+		public String getData() {
+			return data;
+		}
+
+		public void setData(String data) {
+			this.data = data;
+		}
 
 	}
 

+ 43 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/ActionGetMobile.java

@@ -0,0 +1,43 @@
+package com.x.processplatform.assemble.surface.jaxrs.form;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.exception.ExceptionEntityNotExist;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.element.Form;
+
+class ActionGetMobile extends BaseAction {
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String flag) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<Wo> result = new ActionResult<>();
+			Business business = new Business(emc);
+			Form form = business.form().pick(flag);
+			if (null == form) {
+				throw new ExceptionEntityNotExist(flag, Form.class);
+			}
+			Wo wo = new Wo();
+			wo.setData(form.getMobileDataOrData());
+			result.setData(wo);
+			return result;
+		}
+	}
+
+	public static class Wo extends GsonPropertyObject {
+
+		private String data;
+
+		public String getData() {
+			return data;
+		}
+
+		public void setData(String data) {
+			this.data = data;
+		}
+
+	}
+
+}

+ 89 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/ActionGetWithWorkOrWorkCompleted.java

@@ -0,0 +1,89 @@
+package com.x.processplatform.assemble.surface.jaxrs.form;
+
+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.exception.ExceptionAccessDenied;
+import com.x.base.core.project.gson.GsonPropertyObject;
+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.PropertyTools;
+import com.x.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.content.WorkCompleted;
+import com.x.processplatform.core.entity.element.Activity;
+import com.x.processplatform.core.entity.element.Form;
+
+class ActionGetWithWorkOrWorkCompleted extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionGetWithWorkOrWorkCompleted.class);
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String workOrWorkCompleted) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			
+			ActionResult<Wo> result = new ActionResult<>();
+
+			Business business = new Business(emc);
+
+			if (!business.readableWithWorkOrWorkCompleted(effectivePerson, workOrWorkCompleted)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+
+			Wo wo = null;
+
+			Work work = emc.find(workOrWorkCompleted, Work.class);
+
+			if (null != work) {
+				wo = this.work(business, work);
+			} else {
+				wo = this.workCompleted(business, emc.flag(workOrWorkCompleted, WorkCompleted.class));
+			}
+			result.setData(wo);
+			return result;
+		}
+	}
+
+	private Wo work(Business business, Work work) throws Exception {
+		Wo wo = new Wo();
+		String id = work.getForm();
+		if (StringUtils.isEmpty(id)) {
+			Activity activity = business.getActivity(work);
+			id = PropertyTools.getOrElse(activity, Activity.form_FIELDNAME, String.class, "");
+		}
+		if (StringUtils.isEmpty(id)) {
+			Form form = business.form().pick(id);
+			if (null != form) {
+				wo.setData(form.getDataOrMobileData());
+			}
+		}
+		return wo;
+	}
+
+	private Wo workCompleted(Business business, WorkCompleted workCompleted) throws Exception {
+		Wo wo = new Wo();
+		if (StringUtils.isNotEmpty(workCompleted.getFormData())) {
+			wo.setData(workCompleted.getFormData());
+		} else {
+			wo.setData(workCompleted.getFormMobileData());
+		}
+		return wo;
+	}
+
+	public static class Wo extends GsonPropertyObject {
+
+		private String data;
+
+		public String getData() {
+			return data;
+		}
+
+		public void setData(String data) {
+			this.data = data;
+		}
+
+	}
+
+}

+ 89 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/ActionGetWithWorkOrWorkCompletedMobile.java

@@ -0,0 +1,89 @@
+package com.x.processplatform.assemble.surface.jaxrs.form;
+
+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.exception.ExceptionAccessDenied;
+import com.x.base.core.project.gson.GsonPropertyObject;
+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.PropertyTools;
+import com.x.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.content.WorkCompleted;
+import com.x.processplatform.core.entity.element.Activity;
+import com.x.processplatform.core.entity.element.Form;
+
+class ActionGetWithWorkOrWorkCompletedMobile extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionGetWithWorkOrWorkCompletedMobile.class);
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String workOrWorkCompleted) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			
+			ActionResult<Wo> result = new ActionResult<>();
+
+			Business business = new Business(emc);
+
+			if (!business.readableWithWorkOrWorkCompleted(effectivePerson, workOrWorkCompleted)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+
+			Wo wo = null;
+
+			Work work = emc.find(workOrWorkCompleted, Work.class);
+
+			if (null != work) {
+				wo = this.work(business, work);
+			} else {
+				wo = this.workCompleted(business, emc.flag(workOrWorkCompleted, WorkCompleted.class));
+			}
+			result.setData(wo);
+			return result;
+		}
+	}
+
+	private Wo work(Business business, Work work) throws Exception {
+		Wo wo = new Wo();
+		String id = work.getForm();
+		if (StringUtils.isEmpty(id)) {
+			Activity activity = business.getActivity(work);
+			id = PropertyTools.getOrElse(activity, Activity.form_FIELDNAME, String.class, "");
+		}
+		if (StringUtils.isEmpty(id)) {
+			Form form = business.form().pick(id);
+			if (null != form) {
+				wo.setData(form.getDataOrMobileData());
+			}
+		}
+		return wo;
+	}
+
+	private Wo workCompleted(Business business, WorkCompleted workCompleted) throws Exception {
+		Wo wo = new Wo();
+		if (StringUtils.isNotEmpty(workCompleted.getFormData())) {
+			wo.setData(workCompleted.getFormData());
+		} else {
+			wo.setData(workCompleted.getFormMobileData());
+		}
+		return wo;
+	}
+
+	public static class Wo extends GsonPropertyObject {
+
+		private String data;
+
+		public String getData() {
+			return data;
+		}
+
+		public void setData(String data) {
+			this.data = data;
+		}
+
+	}
+
+}

+ 59 - 3
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/form/FormAction.java

@@ -28,17 +28,73 @@ public class FormAction extends StandardJaxrsAction {
 
 	private static Logger logger = LoggerFactory.getLogger(FormAction.class);
 
+	@JaxrsMethodDescribe(value = "根据工作或完成工作标识获取表单.", action = ActionGetWithWorkOrWorkCompleted.class)
+	@GET
+	@Path("workorworkcompleted/{workOrWorkCompleted}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void getWithWorkOrWorkCompleted(@Suspended final AsyncResponse asyncResponse,
+			@Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作或完成工作标识") @PathParam("workOrWorkCompleted") String workOrWorkCompleted) {
+		ActionResult<ActionGetWithWorkOrWorkCompleted.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionGetWithWorkOrWorkCompleted().execute(effectivePerson, workOrWorkCompleted);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+	
+	@JaxrsMethodDescribe(value = "根据工作或完成工作标识获取移动表单.", action = ActionGetWithWorkOrWorkCompletedMobile.class)
+	@GET
+	@Path("workorworkcompleted/{workOrWorkCompleted}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void getWithWorkOrWorkCompletedMobile(@Suspended final AsyncResponse asyncResponse,
+			@Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作或完成工作标识") @PathParam("workOrWorkCompleted") String workOrWorkCompleted) {
+		ActionResult<ActionGetWithWorkOrWorkCompletedMobile.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionGetWithWorkOrWorkCompletedMobile().execute(effectivePerson, workOrWorkCompleted);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
 	@JaxrsMethodDescribe(value = "获取表单.", action = ActionGet.class)
 	@GET
-	@Path("{id}")
+	@Path("{flag}")
 	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
 	@Consumes(MediaType.APPLICATION_JSON)
 	public void get(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
-			@JaxrsParameterDescribe("表单标识") @PathParam("id") String id) {
+			@JaxrsParameterDescribe("表单标识") @PathParam("flag") String flag) {
 		ActionResult<ActionGet.Wo> result = new ActionResult<>();
 		EffectivePerson effectivePerson = this.effectivePerson(request);
 		try {
-			result = new ActionGet().execute(effectivePerson, id);
+			result = new ActionGet().execute(effectivePerson, flag);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
+	@JaxrsMethodDescribe(value = "获取移动端表单.", action = ActionGetMobile.class)
+	@GET
+	@Path("{flag}/mobile")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void getMobile(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+			@JaxrsParameterDescribe("表单标识") @PathParam("flag") String flag) {
+		ActionResult<ActionGetMobile.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionGetMobile().execute(effectivePerson, flag);
 		} catch (Exception e) {
 			logger.error(e, effectivePerson, request, null);
 			result.error(e);

+ 61 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/readcompleted/ActionListWithWorkOrWorkCompleted.java

@@ -0,0 +1,61 @@
+package com.x.processplatform.assemble.surface.jaxrs.readcompleted;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+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;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+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.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.ReadCompleted;
+
+class ActionListWithWorkOrWorkCompleted extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionListWithWorkOrWorkCompleted.class);
+
+	ActionResult<List<Wo>> execute(EffectivePerson effectivePerson, String workOrWorkCompleted) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<List<Wo>> result = new ActionResult<>();
+
+			Business business = new Business(emc);
+
+			if (!business.readableWithWorkOrWorkCompleted(effectivePerson, workOrWorkCompleted)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+
+			final String job = business.job().findWithWorkOrWorkCompleted(workOrWorkCompleted);
+
+			List<Wo> wos = this.list(business, job);
+
+			wos = wos.stream().sorted(Comparator.comparing(Wo::getCreateTime)).collect(Collectors.toList());
+
+			result.setData(wos);
+			return result;
+		}
+	}
+
+	private List<Wo> list(Business business, String job) throws Exception {
+		List<ReadCompleted> os = business.entityManagerContainer().listEqual(ReadCompleted.class,
+				ReadCompleted.job_FIELDNAME, job);
+		List<Wo> wos = Wo.copier.copy(os);
+		return wos;
+	}
+
+	public static class Wo extends ReadCompleted {
+
+		static final long serialVersionUID = 5610132069178497370L;
+
+		static WrapCopier<ReadCompleted, Wo> copier = WrapCopierFactory.wo(ReadCompleted.class, Wo.class, null,
+				JpaObject.FieldsInvisible);
+
+	}
+
+}

+ 20 - 1
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/readcompleted/ReadCompletedAction.java

@@ -52,6 +52,25 @@ public class ReadCompletedAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
 	}
 
+	@JaxrsMethodDescribe(value = "根据工作或完成工作获取已阅,", action = ActionListWithWorkOrWorkCompleted.class)
+	@GET
+	@Path("list/workorworkcompleted/{workOrWorkCompleted}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void listWithWorkOrWorkCompleted(@Suspended final AsyncResponse asyncResponse,
+			@Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作或完成工作标识") @PathParam("workOrWorkCompleted") String workOrWorkCompleted) {
+		ActionResult<List<ActionListWithWorkOrWorkCompleted.Wo>> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionListWithWorkOrWorkCompleted().execute(effectivePerson, workOrWorkCompleted);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
 	@JaxrsMethodDescribe(value = "列示当前用户的WorkCompleted对象,下一页.", action = ActionListNext.class)
 	@GET
 	@Path("list/{id}/next/{count}")
@@ -222,7 +241,7 @@ public class ReadCompletedAction extends StandardJaxrsAction {
 		}
 		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
 	}
-	
+
 	@JaxrsMethodDescribe(value = "获取可用与filter的分类值,通过输入值进行范围限制.", action = ActionFilterAttributeFilter.class)
 	@POST
 	@Path("filter/attribute/filter")

+ 23 - 19
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/warp/ActionGetWorkOrWorkCompleted.java → o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/task/ActionListWithJob.java

@@ -1,4 +1,9 @@
-package com.x.processplatform.assemble.surface.jaxrs.warp;
+package com.x.processplatform.assemble.surface.jaxrs.task;
+
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
 
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
@@ -6,31 +11,31 @@ 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.exception.ExceptionAccessDenied;
-import com.x.base.core.project.exception.ExceptionEntityNotExist;
 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.processplatform.assemble.surface.Business;
 import com.x.processplatform.core.entity.content.Task;
 
-class ActionGetWorkOrWorkCompleted extends BaseAction {
-
-	private static Logger logger = LoggerFactory.getLogger(ActionGetWorkOrWorkCompleted.class);
+class ActionListWithJob extends BaseAction {
 
-	ActionResult<Wo> execute(EffectivePerson effectivePerson, String id) throws Exception {
+	ActionResult<List<Wo>> execute(EffectivePerson effectivePerson, String job) throws Exception {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			ActionResult<Wo> result = new ActionResult<>();
+
+			ActionResult<List<Wo>> result = new ActionResult<>();
+
 			Business business = new Business(emc);
-			Task task = emc.find(id, Task.class);
-			if (null == task) {
-				throw new ExceptionEntityNotExist(id, Task.class);
-			}
-			if (!business.readable(effectivePerson, task)) {
-				throw new ExceptionAccessDenied(effectivePerson, task);
+
+			if (!business.readableWithJob(effectivePerson, job)) {
+				throw new ExceptionAccessDenied(effectivePerson);
 			}
-			Wo wo = Wo.copier.copy(task);
-			result.setData(wo);
+
+			List<Wo> wos = Wo.copier.copy(emc.listEqual(Task.class, Task.job_FIELDNAME, job));
+
+			wos = wos.stream().sorted(Comparator.comparing(Wo::getStartTime, Comparator.nullsLast(Date::compareTo)))
+					.collect(Collectors.toList());
+
+			result.setData(wos);
+
 			return result;
 		}
 	}
@@ -43,5 +48,4 @@ class ActionGetWorkOrWorkCompleted extends BaseAction {
 				JpaObject.FieldsInvisible);
 
 	}
-
-}
+}

+ 18 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/task/TaskAction.java

@@ -35,6 +35,24 @@ public class TaskAction extends StandardJaxrsAction {
 
 	private static Logger logger = LoggerFactory.getLogger(TaskAction.class);
 
+	@JaxrsMethodDescribe(value = "根据job获取待办.", action = ActionListWithJob.class)
+	@GET
+	@Path("list/job/{job}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void listNext(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+			@JaxrsParameterDescribe("任务标识") @PathParam("job") String job) {
+		ActionResult<List<ActionListWithJob.Wo>> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionListWithJob().execute(effectivePerson, job);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
 	@JaxrsMethodDescribe(value = "列示当前用户创建的Task对象,下一页.", action = ActionListNext.class)
 	@GET
 	@Path("list/{id}/next/{count}")

+ 61 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/taskcompleted/ActionListWithWorkOrWorkCompleted.java

@@ -0,0 +1,61 @@
+package com.x.processplatform.assemble.surface.jaxrs.taskcompleted;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+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;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+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.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.TaskCompleted;
+
+class ActionListWithWorkOrWorkCompleted extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionListWithWorkOrWorkCompleted.class);
+
+	ActionResult<List<Wo>> execute(EffectivePerson effectivePerson, String workOrWorkCompleted) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<List<Wo>> result = new ActionResult<>();
+
+			Business business = new Business(emc);
+
+			if (!business.readableWithWorkOrWorkCompleted(effectivePerson, workOrWorkCompleted)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+
+			final String job = business.job().findWithWorkOrWorkCompleted(workOrWorkCompleted);
+
+			List<Wo> wos = this.list(business, job);
+
+			wos = wos.stream().sorted(Comparator.comparing(Wo::getCreateTime)).collect(Collectors.toList());
+
+			result.setData(wos);
+			return result;
+		}
+	}
+
+	private List<Wo> list(Business business, String job) throws Exception {
+		List<TaskCompleted> os = business.entityManagerContainer().listEqual(TaskCompleted.class,
+				TaskCompleted.job_FIELDNAME, job);
+		List<Wo> wos = Wo.copier.copy(os);
+		return wos;
+	}
+
+	public static class Wo extends TaskCompleted {
+
+		static final long serialVersionUID = 5610132069178497370L;
+
+		static WrapCopier<TaskCompleted, Wo> copier = WrapCopierFactory.wo(TaskCompleted.class, Wo.class, null,
+				JpaObject.FieldsInvisible);
+
+	}
+
+}

+ 19 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/taskcompleted/TaskCompletedAction.java

@@ -53,6 +53,25 @@ public class TaskCompletedAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
 	}
 
+	@JaxrsMethodDescribe(value = "根据工作或完成工作获取已办,", action = ActionListWithWorkOrWorkCompleted.class)
+	@GET
+	@Path("list/workorworkcompleted/{workOrWorkCompleted}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void listWithWorkOrWorkCompleted(@Suspended final AsyncResponse asyncResponse,
+			@Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作或完成工作标识") @PathParam("workOrWorkCompleted") String workOrWorkCompleted) {
+		ActionResult<List<ActionListWithWorkOrWorkCompleted.Wo>> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionListWithWorkOrWorkCompleted().execute(effectivePerson, workOrWorkCompleted);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
 	@JaxrsMethodDescribe(value = "列示当前用户的WorkCompleted对象,下一页.", action = ActionListNext.class)
 	@GET
 	@Path("list/{id}/next/{count}")

+ 0 - 10
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/warp/BaseAction.java

@@ -1,10 +0,0 @@
-package com.x.processplatform.assemble.surface.jaxrs.warp;
-
-import com.x.base.core.project.jaxrs.StandardJaxrsAction;
-
-abstract class BaseAction extends StandardJaxrsAction {
- 
-	
-	
-
-}

+ 71 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionCallback.java

@@ -0,0 +1,71 @@
+package com.x.processplatform.assemble.surface.jaxrs.work;
+
+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.project.Applications;
+import com.x.base.core.project.x_processplatform_service_processing;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+import com.x.base.core.project.exception.ExceptionEntityNotExist;
+import com.x.base.core.project.gson.GsonPropertyObject;
+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.processplatform.assemble.surface.Business;
+import com.x.processplatform.assemble.surface.ThisApplication;
+import com.x.processplatform.assemble.surface.WorkControl;
+import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.element.Application;
+import com.x.processplatform.core.entity.element.Process;
+
+class ActionCallback extends BaseAction {
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String id, JsonElement jsonElement) throws Exception {
+
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<Wo> result = new ActionResult<>();
+			Business business = new Business(emc);
+			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
+			/* 校验work是否存在 */
+			Work work = emc.find(id, Work.class);
+			if (null == work) {
+				throw new ExceptionEntityNotExist(id, Work.class);
+			}
+			Application application = business.application().pick(work.getApplication());
+			Process process = business.process().pick(work.getProcess());
+
+			if (!business.canManageApplicationOrProcess(effectivePerson, application, process)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+
+			Wo wo = ThisApplication.context().applications().putQuery(x_processplatform_service_processing.class,
+					Applications.joinQueryUri("work", work.getId(), "add", "split"), wi).getData(Wo.class);
+
+			result.setData(wo);
+			return result;
+
+		}
+	}
+
+	public static class Wi extends GsonPropertyObject {
+
+		private String workLogId;
+
+		public String getWorkLogId() {
+			return workLogId;
+		}
+
+		public void setWorkLogId(String workLogId) {
+			this.workLogId = workLogId;
+		}
+
+	}
+
+	public static class WoWorkControl extends WorkControl {
+
+	}
+
+	public static class Wo extends WoId {
+	}
+
+}

+ 336 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionGetWithWorkOrWorkCompleted.java

@@ -0,0 +1,336 @@
+package com.x.processplatform.assemble.surface.jaxrs.work;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+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.entity.dataitem.ItemCategory;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+import com.x.base.core.project.gson.GsonPropertyObject;
+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.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.Data;
+import com.x.processplatform.core.entity.content.Read;
+import com.x.processplatform.core.entity.content.Task;
+import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.content.WorkCompleted;
+import com.x.processplatform.core.entity.element.Activity;
+import com.x.query.core.entity.Item;
+import com.x.query.core.entity.Item_;
+
+class ActionGetWithWorkOrWorkCompleted extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionGetWithWorkOrWorkCompleted.class);
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String workOrWorkCompleted) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<Wo> result = new ActionResult<>();
+			Business business = new Business(emc);
+			if (!business.readableWithWorkOrWorkCompleted(effectivePerson, workOrWorkCompleted)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+			Wo wo = null;
+			Work work = emc.find(workOrWorkCompleted, Work.class);
+			if (null != work) {
+				wo = this.work(business, effectivePerson, work);
+			} else {
+				wo = this.workCompleted(business, effectivePerson, emc.flag(workOrWorkCompleted, WorkCompleted.class));
+			}
+			result.setData(wo);
+			return result;
+		}
+	}
+
+	private Wo work(Business business, EffectivePerson effectivePerson, Work work) throws Exception {
+		Wo wo = new Wo();
+		wo.setWork(gson.toJsonTree(WoWork.copier.copy(work)));
+		wo.setActivity(this.activity(business, work));
+		CompletableFuture<Data> future_data = CompletableFuture.supplyAsync(() -> {
+			return this.data(business, work.getJob());
+		});
+		CompletableFuture<List<WoTask>> future_task = CompletableFuture.supplyAsync(() -> {
+			return this.tasks(business, work.getJob());
+		});
+		CompletableFuture<List<WoRead>> future_read = CompletableFuture.supplyAsync(() -> {
+			return this.reads(business, work.getJob());
+		});
+		wo.setData(future_data.get());
+		wo.setTaskList(future_task.get());
+		wo.setReadList(future_read.get());
+		this.setCurrentReadIndex(effectivePerson, wo);
+		this.setCurrentTaskIndex(effectivePerson, wo);
+		return wo;
+	}
+
+	private Wo workCompleted(Business business, EffectivePerson effectivePerson, WorkCompleted workCompleted)
+			throws Exception {
+		Wo wo = new Wo();
+		wo.setWork(gson.toJsonTree(WoWorkCompleted.copier.copy(workCompleted)));
+		CompletableFuture<Data> future_data = CompletableFuture.supplyAsync(() -> {
+			return this.data(business, workCompleted.getJob());
+		});
+		CompletableFuture<List<WoRead>> future_read = CompletableFuture.supplyAsync(() -> {
+			return this.reads(business, workCompleted.getJob());
+		});
+		wo.setData(future_data.get());
+		wo.setReadList(future_read.get());
+		this.setCurrentReadIndex(effectivePerson, wo);
+		return wo;
+	}
+
+	private Data data(Business business, String job) {
+		try {
+			EntityManager em = business.entityManagerContainer().get(Item.class);
+			CriteriaBuilder cb = em.getCriteriaBuilder();
+			CriteriaQuery<Item> cq = cb.createQuery(Item.class);
+			Root<Item> root = cq.from(Item.class);
+			Predicate p = cb.equal(root.get(Item_.bundle), job);
+			p = cb.and(p, cb.equal(root.get(Item_.itemCategory), ItemCategory.pp));
+			List<Item> list = em.createQuery(cq.where(p)).getResultList();
+			if (list.isEmpty()) {
+				return new Data();
+			} else {
+				JsonElement jsonElement = itemConverter.assemble(list);
+				if (jsonElement.isJsonObject()) {
+					return gson.fromJson(jsonElement, Data.class);
+				} else {
+					/* 如果不是Object强制返回一个Map对象 */
+					return new Data();
+				}
+			}
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return null;
+	}
+
+	private List<WoTask> tasks(Business business, String workId) {
+		try {
+			return business.entityManagerContainer().fetchEqual(Task.class, WoTask.copier, Task.work_FIELDNAME, workId);
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return null;
+	}
+
+	private List<WoRead> reads(Business business, String workId) {
+		try {
+			return business.entityManagerContainer().fetchEqual(Read.class, WoRead.copier, Read.work_FIELDNAME, workId);
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return null;
+	}
+
+	private WoActivity activity(Business business, Work work) throws Exception {
+		WoActivity woActivity = new WoActivity();
+		Activity activity = business.getActivity(work);
+		if (null != activity) {
+			woActivity = WoActivity.copier.copy(activity);
+		}
+		return woActivity;
+	}
+
+	private void setCurrentTaskIndex(EffectivePerson effectivePerson, Wo wo) {
+		for (int i = 0; i < wo.getTaskList().size(); i++) {
+			if (effectivePerson.isUser(wo.getTaskList().get(i).getPerson())) {
+				wo.setCurrentTaskIndex(i);
+				break;
+			}
+		}
+	}
+
+	private void setCurrentReadIndex(EffectivePerson effectivePerson, Wo wo) {
+		for (int i = 0; i < wo.getReadList().size(); i++) {
+			if (effectivePerson.isUser(wo.getReadList().get(i).getPerson())) {
+				wo.setCurrentReadIndex(i);
+				break;
+			}
+		}
+	}
+
+	public static class Wo extends GsonPropertyObject {
+
+		/* work和workCompleted都有 */
+		private JsonElement work;
+		/* work和workCompleted都有 */
+		private Data data;
+		/* work和workCompleted都有 */
+		private List<WoRead> readList;
+		/* work和workCompleted都有 */
+		private Integer currentReadIndex = -1;
+
+		/* 只有work有 */
+		private WoActivity activity;
+		/* 只有work有 */
+		private List<WoTask> taskList;
+		/* 只有work有 */
+		private Integer currentTaskIndex;
+
+		public JsonElement getWork() {
+			return work;
+		}
+
+		public void setWork(JsonElement work) {
+			this.work = work;
+		}
+
+		public List<WoRead> getReadList() {
+			return readList;
+		}
+
+		public void setReadList(List<WoRead> readList) {
+			this.readList = readList;
+		}
+
+		public Integer getCurrentReadIndex() {
+			return currentReadIndex;
+		}
+
+		public void setCurrentReadIndex(Integer currentReadIndex) {
+			this.currentReadIndex = currentReadIndex;
+		}
+
+		public List<WoTask> getTaskList() {
+			return taskList;
+		}
+
+		public void setTaskList(List<WoTask> taskList) {
+			this.taskList = taskList;
+		}
+
+		public Integer getCurrentTaskIndex() {
+			return currentTaskIndex;
+		}
+
+		public void setCurrentTaskIndex(Integer currentTaskIndex) {
+			this.currentTaskIndex = currentTaskIndex;
+		}
+
+		public Data getData() {
+			return data;
+		}
+
+		public void setData(Data data) {
+			this.data = data;
+		}
+
+		public WoActivity getActivity() {
+			return activity;
+		}
+
+		public void setActivity(WoActivity activity) {
+			this.activity = activity;
+		}
+
+	}
+
+	public static class WoWork extends Work {
+
+		private static final long serialVersionUID = 5244996549744746585L;
+
+		static WrapCopier<Work, WoWork> copier = WrapCopierFactory.wo(Work.class, WoWork.class, null,
+				JpaObject.FieldsInvisible);
+
+	}
+
+	public static class WoWorkCompleted extends WorkCompleted {
+
+		private static final long serialVersionUID = -1772642962691214007L;
+
+		static WrapCopier<WorkCompleted, WoWorkCompleted> copier = WrapCopierFactory.wo(WorkCompleted.class,
+				WoWorkCompleted.class, null, ListTools.toList(JpaObject.FieldsInvisible,
+						WorkCompleted.formData_FIELDNAME, WorkCompleted.formMobileData_FIELDNAME));
+	}
+
+	public static class WoTask extends Task {
+
+		private static final long serialVersionUID = 5244996549744746585L;
+
+		static WrapCopier<Task, WoTask> copier = WrapCopierFactory.wo(Task.class, WoTask.class,
+				JpaObject.singularAttributeField(Task.class, true, true), JpaObject.FieldsInvisible);
+
+	}
+
+	public static class WoRead extends Read {
+
+		private static final long serialVersionUID = 5244996549744746585L;
+
+		static WrapCopier<Read, WoRead> copier = WrapCopierFactory.wo(Read.class, WoRead.class,
+				JpaObject.singularAttributeField(Read.class, true, true), JpaObject.FieldsInvisible);
+
+	}
+
+	public static class WoActivity extends GsonPropertyObject {
+
+		static WrapCopier<Activity, WoActivity> copier = WrapCopierFactory.wo(Activity.class, WoActivity.class,
+				JpaObject.singularAttributeField(Activity.class, true, true), JpaObject.FieldsInvisible);
+
+		private String id;
+
+		private String name;
+
+		private String description;
+
+		private String alias;
+
+		private String position;
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public void setDescription(String description) {
+			this.description = description;
+		}
+
+		public String getAlias() {
+			return alias;
+		}
+
+		public void setAlias(String alias) {
+			this.alias = alias;
+		}
+
+		public String getPosition() {
+			return position;
+		}
+
+		public void setPosition(String position) {
+			this.position = position;
+		}
+
+		public String getId() {
+			return id;
+		}
+
+		public void setId(String id) {
+			this.id = id;
+		}
+
+	}
+
+}

+ 2 - 1
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageDeleteRelativeWork.java

@@ -6,6 +6,7 @@ import java.util.List;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.project.x_processplatform_service_processing;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
@@ -32,7 +33,7 @@ class ActionManageDeleteRelativeWork extends BaseAction {
 			Application application = business.application().pick(work.getApplication());
 			// 需要对这个应用的管理权限
 			if (!business.canManageApplicationOrProcess(effectivePerson, application, process)) {
-				throw new ExceptionAccessDenied(effectivePerson.getDistinguishedName());
+				throw new ExceptionAccessDenied(effectivePerson);
 			}
 			List<Wo> wos = ThisApplication.context().applications()
 					.deleteQuery(x_processplatform_service_processing.class,

+ 2 - 1
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageDeleteSingleWork.java

@@ -7,6 +7,7 @@ import java.util.List;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.project.x_processplatform_service_processing;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
@@ -34,7 +35,7 @@ class ActionManageDeleteSingleWork extends BaseAction {
 			Application application = business.application().pick(work.getApplication());
 			// 需要对这个应用的管理权限
 			if (!business.canManageApplicationOrProcess(effectivePerson, application, process)) {
-				throw new ExceptionAccessDenied(effectivePerson.getDistinguishedName());
+				throw new ExceptionAccessDenied(effectivePerson);
 			}
 			ThisApplication.context().applications().deleteQuery(x_processplatform_service_processing.class,
 					"work/" + URLEncoder.encode(work.getId(), DefaultCharset.name));

+ 2 - 1
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageGet.java

@@ -5,6 +5,7 @@ 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;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.processplatform.assemble.surface.Business;
@@ -28,7 +29,7 @@ class ActionManageGet extends BaseAction {
 			Application application = business.application().pick(work.getApplication());
 			// 需要对这个应用的管理权限
 			if (!business.canManageApplicationOrProcess(effectivePerson, application, process)) {
-				throw new ExceptionAccessDenied(effectivePerson.getDistinguishedName());
+				throw new ExceptionAccessDenied(effectivePerson);
 			}
 			Wo wo = Wo.copier.copy(work);
 			/* 添加权限 */

+ 2 - 1
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageGetAssignment.java

@@ -12,6 +12,7 @@ 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.exception.ExceptionAccessDenied;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -42,7 +43,7 @@ class ActionManageGetAssignment extends BaseAction {
 			Application application = business.application().pick(work.getApplication());
 			// 需要对这个应用的管理权限
 			if (!business.canManageApplicationOrProcess(effectivePerson, application, process)) {
-				throw new ExceptionAccessDenied(effectivePerson.getDistinguishedName());
+				throw new ExceptionAccessDenied(effectivePerson);
 			}
 			List<Task> tasks = emc.listEqual(Task.class, Task.work_FIELDNAME, work.getId());
 			List<TaskCompleted> taskCompleteds = emc.listEqual(TaskCompleted.class, TaskCompleted.work_FIELDNAME,

+ 2 - 1
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ActionManageListRelative.java

@@ -11,6 +11,7 @@ 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.exception.ExceptionAccessDenied;
 import com.x.base.core.project.exception.ExceptionWhen;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -33,7 +34,7 @@ class ActionManageListRelative extends BaseAction {
 			Application application = business.application().pick(work.getApplication());
 			// 需要对这个应用的管理权限
 			if (!business.canManageApplicationOrProcess(effectivePerson, application, process)) {
-				throw new ExceptionAccessDenied(effectivePerson.getDistinguishedName());
+				throw new ExceptionAccessDenied(effectivePerson);
 			}
 			List<String> ids = this.listRelative(business, work);
 			for (String str : ids) {

+ 47 - 33
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/BaseAction.java

@@ -281,7 +281,7 @@ abstract class BaseAction extends StandardJaxrsAction {
 
 		private String position;
 
-		//private ActivityType activityType;
+		// private ActivityType activityType;
 
 		private String resetRange;
 
@@ -502,6 +502,8 @@ abstract class BaseAction extends StandardJaxrsAction {
 		private Boolean allowReroute;
 		/* 是否可以删除 */
 		private Boolean allowDelete;
+		/* 是否可以删除 */
+		private Boolean allowAddSplit;
 
 		public Boolean getAllowSave() {
 			return allowSave;
@@ -575,6 +577,14 @@ abstract class BaseAction extends StandardJaxrsAction {
 			this.allowReadReset = allowReadReset;
 		}
 
+		public Boolean getAllowAddSplit() {
+			return allowAddSplit;
+		}
+
+		public void setAllowAddSplit(Boolean allowAddSplit) {
+			this.allowAddSplit = allowAddSplit;
+		}
+
 	}
 
 	public class WoForm extends Form {
@@ -613,19 +623,19 @@ abstract class BaseAction extends StandardJaxrsAction {
 			}
 		});
 
-//		CompletableFuture<Void> future_taskCompleteds = CompletableFuture.runAsync(() -> {
-//			try {
-//				List<TaskCompleted> os = business.entityManagerContainer()
-//						.listEqual(TaskCompleted.class, TaskCompleted.job_FIELDNAME, work.getJob()).stream()
-//						.sorted(Comparator.comparing(TaskCompleted::getStartTime,
-//								Comparator.nullsLast(Date::compareTo)))
-//						.collect(Collectors.toList());
-//				woTaskCompleteds.addAll(WoTaskCompleted.copier.copy(os));
-//			} catch (Exception e) {
-//				logger.error(e);
-//			}
-//		});
-		
+		CompletableFuture<Void> future_taskCompleteds = CompletableFuture.runAsync(() -> {
+			try {
+				List<TaskCompleted> os = business.entityManagerContainer()
+						.listEqual(TaskCompleted.class, TaskCompleted.job_FIELDNAME, work.getJob()).stream()
+						.sorted(Comparator.comparing(TaskCompleted::getStartTime,
+								Comparator.nullsLast(Date::compareTo)))
+						.collect(Collectors.toList());
+				woTaskCompleteds.addAll(WoTaskCompleted.copier.copy(os));
+			} catch (Exception e) {
+				logger.error(e);
+			}
+		});
+
 		CompletableFuture<Void> future_reads = CompletableFuture.runAsync(() -> {
 			try {
 				List<Read> os = business.entityManagerContainer()
@@ -645,18 +655,18 @@ abstract class BaseAction extends StandardJaxrsAction {
 				logger.error(e);
 			}
 		});
-//		CompletableFuture<Void> future_readCompleteds = CompletableFuture.runAsync(() -> {
-//			try {
-//				List<ReadCompleted> os = business.entityManagerContainer()
-//						.listEqual(ReadCompleted.class, ReadCompleted.job_FIELDNAME, work.getJob()).stream()
-//						.sorted(Comparator.comparing(ReadCompleted::getStartTime,
-//								Comparator.nullsLast(Date::compareTo)))
-//						.collect(Collectors.toList());
-//				woReadCompleteds.addAll(WoReadCompleted.copier.copy(os));
-//			} catch (Exception e) {
-//				logger.error(e);
-//			}
-//		});
+		CompletableFuture<Void> future_readCompleteds = CompletableFuture.runAsync(() -> {
+			try {
+				List<ReadCompleted> os = business.entityManagerContainer()
+						.listEqual(ReadCompleted.class, ReadCompleted.job_FIELDNAME, work.getJob()).stream()
+						.sorted(Comparator.comparing(ReadCompleted::getStartTime,
+								Comparator.nullsLast(Date::compareTo)))
+						.collect(Collectors.toList());
+				woReadCompleteds.addAll(WoReadCompleted.copier.copy(os));
+			} catch (Exception e) {
+				logger.error(e);
+			}
+		});
 		CompletableFuture<Void> future_attachments = CompletableFuture.runAsync(() -> {
 			try {
 				List<Attachment> os = business.entityManagerContainer()
@@ -734,9 +744,9 @@ abstract class BaseAction extends StandardJaxrsAction {
 			return o;
 		});
 		future_tasks.get(300, TimeUnit.SECONDS);
-		//future_taskCompleteds.get(300, TimeUnit.SECONDS);
+		future_taskCompleteds.get(300, TimeUnit.SECONDS);
 		future_reads.get(300, TimeUnit.SECONDS);
-		//future_readCompleteds.get(300, TimeUnit.SECONDS);
+		future_readCompleteds.get(300, TimeUnit.SECONDS);
 		future_attachments.get(300, TimeUnit.SECONDS);
 		future_workLogs.get(300, TimeUnit.SECONDS);
 		future_data.get(300, TimeUnit.SECONDS);
@@ -766,6 +776,8 @@ abstract class BaseAction extends StandardJaxrsAction {
 		control.setAllowReroute(false);
 		/** 工作是否可删除(管理员 或者 此活动在流程设计中允许删除且当前待办人是文件的创建者) */
 		control.setAllowDelete(false);
+		/** 是否可以添加拆分分支 */
+		control.setAllowAddSplit(false);
 		/** 设置allowVisit */
 		if ((t.getCurrentTaskIndex() > -1) || (t.getCurrentReadIndex() > -1) || (woTaskCompleteds.stream()
 				.filter(o -> StringUtils.equals(o.getPerson(), effectivePerson.getDistinguishedName())).count() > 0)
@@ -843,10 +855,8 @@ abstract class BaseAction extends StandardJaxrsAction {
 				control.setAllowReroute(true);
 			}
 		}
-		/** 设置 allowDelete */
-		if (business.canManageApplicationOrProcess(effectivePerson, application, process))
-
-		{
+		/* 设置 allowDelete */
+		if (business.canManageApplicationOrProcess(effectivePerson, application, process)) {
 			control.setAllowDelete(true);
 		} else if (Objects.equals(activity.getActivityType(), ActivityType.manual)
 				&& BooleanUtils.isTrue(activity.get(Manual.allowDeleteWork_FIELDNAME, Boolean.class))) {
@@ -855,13 +865,17 @@ abstract class BaseAction extends StandardJaxrsAction {
 				control.setAllowDelete(true);
 			}
 		}
+		/* 设置 allowAddSplit */
+		if (Objects.equals(activity.getActivityType(), ActivityType.manual)
+				&& BooleanUtils.isTrue(activity.get(Manual.allowAddSplit_FIELDNAME, Boolean.class))) {
+			control.setAllowAddSplit(true);
+		}
 		t.setControl(control);
 		return t;
 	}
 
 	private void arrangeWorkLog(Business business, AbstractWo wo, List<WoTaskCompleted> woTaskCompleteds,
 			List<WoReadCompleted> woReadCompleteds) throws Exception {
-
 		ListTools.groupStick(wo.getWorkLogList(), wo.getTaskList(), WorkLog.fromActivityToken_FIELDNAME,
 				Task.activityToken_FIELDNAME, "taskList");
 		ListTools.groupStick(wo.getWorkLogList(), woTaskCompleteds, WorkLog.fromActivityToken_FIELDNAME,

+ 0 - 13
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/ExceptionAccessDenied.java

@@ -1,13 +0,0 @@
-package com.x.processplatform.assemble.surface.jaxrs.work;
-
-import com.x.base.core.project.exception.PromptException;
-
-class ExceptionAccessDenied extends PromptException {
-
-	private static final long serialVersionUID = -5515077418025884395L;
-
-	ExceptionAccessDenied(String person) {
-		super("用户:{} 权限不足.", person);
-	}
-
-}

+ 19 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/work/WorkAction.java

@@ -53,6 +53,25 @@ public class WorkAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
 	}
 
+	@JaxrsMethodDescribe(value = "根据Work或workCompleted取得内容.", action = ActionGetWithWorkOrWorkCompleted.class)
+	@GET
+	@Path("workorworkcompleted/{workOrWorkCompleted}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void getWithWorkOrWorkCompleted(@Suspended final AsyncResponse asyncResponse,
+			@Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作或已完成工作标识") @PathParam("workOrWorkCompleted") String workOrWorkCompleted) {
+		ActionResult<ActionGetWithWorkOrWorkCompleted.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionGetWithWorkOrWorkCompleted().execute(effectivePerson, workOrWorkCompleted);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
 	@JaxrsMethodDescribe(value = "根据Work Id获取组装的Work内容.", action = ActionComplex.class)
 	@GET
 	@Path("{id}/complex")

+ 254 - 0
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/worklog/ActionListWithWorkOrWorkCompleted.java

@@ -0,0 +1,254 @@
+package com.x.processplatform.assemble.surface.jaxrs.worklog;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+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;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+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.processplatform.assemble.surface.Business;
+import com.x.processplatform.core.entity.content.Read;
+import com.x.processplatform.core.entity.content.ReadCompleted;
+import com.x.processplatform.core.entity.content.Review;
+import com.x.processplatform.core.entity.content.Task;
+import com.x.processplatform.core.entity.content.TaskCompleted;
+import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.content.WorkCompleted;
+import com.x.processplatform.core.entity.content.WorkLog;
+import com.x.processplatform.core.entity.element.Application;
+import com.x.processplatform.core.entity.element.Process;
+
+class ActionListWithWorkOrWorkCompleted extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionListWithWorkOrWorkCompleted.class);
+
+	private final static String taskList_FIELDNAME = "taskList";
+	private final static String taskCompletedList_FIELDNAME = "taskCompletedList";
+	private final static String readList_FIELDNAME = "readList";
+	private final static String readCompletedList_FIELDNAME = "readCompletedList";
+
+	ActionResult<List<Wo>> execute(EffectivePerson effectivePerson, String workOrWorkCompleted) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<List<Wo>> result = new ActionResult<>();
+
+			Business business = new Business(emc);
+
+			if (!business.readableWithWorkOrWorkCompleted(effectivePerson, workOrWorkCompleted)) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+
+			final String job = business.job().findWithWorkOrWorkCompleted(workOrWorkCompleted);
+
+			CompletableFuture<List<WoTask>> future_tasks = CompletableFuture.supplyAsync(() -> {
+				return this.tasks(business, job);
+			});
+			CompletableFuture<List<WoTaskCompleted>> future_taskCompleteds = CompletableFuture.supplyAsync(() -> {
+				return this.taskCompleted(business, job);
+			});
+			CompletableFuture<List<WoRead>> future_reads = CompletableFuture.supplyAsync(() -> {
+				return this.reads(business, job);
+			});
+			CompletableFuture<List<WoReadCompleted>> future_readCompleteds = CompletableFuture.supplyAsync(() -> {
+				return this.readCompleteds(business, job);
+			});
+			CompletableFuture<List<Wo>> future_workLogs = CompletableFuture.supplyAsync(() -> {
+				return this.workLogs(business, job);
+			});
+			List<WoTask> tasks = future_tasks.get();
+			List<WoTaskCompleted> taskCompleteds = future_taskCompleteds.get();
+			List<WoRead> reads = future_reads.get();
+			List<WoReadCompleted> readCompleteds = future_readCompleteds.get();
+			List<Wo> wos = future_workLogs.get();
+			ListTools.groupStick(wos, tasks, WorkLog.fromActivityToken_FIELDNAME, Task.activityToken_FIELDNAME,
+					taskList_FIELDNAME);
+			ListTools.groupStick(wos, taskCompleteds, WorkLog.fromActivityToken_FIELDNAME,
+					TaskCompleted.activityToken_FIELDNAME, taskCompletedList_FIELDNAME);
+			ListTools.groupStick(wos, reads, WorkLog.fromActivityToken_FIELDNAME, Read.activityToken_FIELDNAME,
+					readList_FIELDNAME);
+			ListTools.groupStick(wos, readCompleteds, WorkLog.fromActivityToken_FIELDNAME,
+					ReadCompleted.activityToken_FIELDNAME, readCompletedList_FIELDNAME);
+			result.setData(wos);
+			return result;
+		}
+	}
+
+	private List<WoTask> tasks(Business business, String job) {
+		List<WoTask> os = new ArrayList<>();
+		try {
+			os = business.entityManagerContainer().fetchEqual(Task.class, WoTask.copier, WoTask.job_FIELDNAME, job)
+					.stream().sorted(Comparator.comparing(Task::getStartTime, Comparator.nullsLast(Date::compareTo)))
+					.collect(Collectors.toList());
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return os;
+	}
+
+	private List<WoTaskCompleted> taskCompleted(Business business, String job) {
+		List<WoTaskCompleted> os = new ArrayList<>();
+		try {
+			os = business.entityManagerContainer()
+					.fetchEqual(TaskCompleted.class, WoTaskCompleted.copier, TaskCompleted.job_FIELDNAME, job).stream()
+					.sorted(Comparator.comparing(TaskCompleted::getStartTime, Comparator.nullsLast(Date::compareTo)))
+					.collect(Collectors.toList());
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return os;
+	}
+
+	private List<WoRead> reads(Business business, String job) {
+		List<WoRead> os = new ArrayList<>();
+		try {
+			os = business.entityManagerContainer().fetchEqual(Read.class, WoRead.copier, Read.job_FIELDNAME, job)
+					.stream().sorted(Comparator.comparing(Read::getStartTime, Comparator.nullsLast(Date::compareTo)))
+					.collect(Collectors.toList());
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return os;
+	}
+
+	private List<WoReadCompleted> readCompleteds(Business business, String job) {
+		List<WoReadCompleted> os = new ArrayList<>();
+		try {
+			os = business.entityManagerContainer()
+					.fetchEqual(ReadCompleted.class, WoReadCompleted.copier, ReadCompleted.job_FIELDNAME, job).stream()
+					.sorted(Comparator.comparing(ReadCompleted::getStartTime, Comparator.nullsLast(Date::compareTo)))
+					.collect(Collectors.toList());
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return os;
+	}
+
+	private List<Wo> workLogs(Business business, String job) {
+		List<Wo> os = new ArrayList<>();
+		try {
+			os = business.entityManagerContainer().fetchEqual(WorkLog.class, Wo.copier, WorkLog.job_FIELDNAME, job)
+					.stream()
+					.sorted(Comparator.comparing(WorkLog::getCreateTime, Comparator.nullsLast(Date::compareTo)))
+					.collect(Collectors.toList());
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return os;
+	}
+
+	public static class Wo extends WorkLog {
+
+		private static final long serialVersionUID = -7666329770246726197L;
+
+		static WrapCopier<WorkLog, Wo> copier = WrapCopierFactory.wo(WorkLog.class, Wo.class,
+				ListTools.toList(WorkLog.id_FIELDNAME, WorkLog.fromActivity_FIELDNAME,
+						WorkLog.fromActivityType_FIELDNAME, WorkLog.fromActivityName_FIELDNAME,
+						WorkLog.fromActivityAlias_FIELDNAME, WorkLog.fromActivityToken_FIELDNAME,
+						WorkLog.fromTime_FIELDNAME, WorkLog.arrivedActivity_FIELDNAME,
+						WorkLog.arrivedActivityType_FIELDNAME, WorkLog.arrivedActivityName_FIELDNAME,
+						WorkLog.arrivedActivityAlias_FIELDNAME, WorkLog.arrivedActivityToken_FIELDNAME,
+						WorkLog.arrivedTime_FIELDNAME, WorkLog.routeName_FIELDNAME, WorkLog.connected_FIELDNAME,
+						WorkLog.splitting_FIELDNAME),
+				JpaObject.FieldsInvisible);
+
+		private List<WoTask> taskList = new ArrayList<>();
+
+		private List<WoTaskCompleted> taskCompletedList = new ArrayList<>();
+
+		private List<WoRead> readList = new ArrayList<>();
+
+		private List<WoReadCompleted> readCompletedList = new ArrayList<>();
+
+		public List<WoTask> getTaskList() {
+			return taskList;
+		}
+
+		public void setTaskList(List<WoTask> taskList) {
+			this.taskList = taskList;
+		}
+
+		public List<WoTaskCompleted> getTaskCompletedList() {
+			return taskCompletedList;
+		}
+
+		public void setTaskCompletedList(List<WoTaskCompleted> taskCompletedList) {
+			this.taskCompletedList = taskCompletedList;
+		}
+
+		public List<WoRead> getReadList() {
+			return readList;
+		}
+
+		public void setReadList(List<WoRead> readList) {
+			this.readList = readList;
+		}
+
+		public List<WoReadCompleted> getReadCompletedList() {
+			return readCompletedList;
+		}
+
+		public void setReadCompletedList(List<WoReadCompleted> readCompletedList) {
+			this.readCompletedList = readCompletedList;
+		}
+
+	}
+
+	public static class WoTask extends Task {
+
+		private static final long serialVersionUID = 293599148568443301L;
+
+		static WrapCopier<Task, WoTask> copier = WrapCopierFactory.wo(Task.class, WoTask.class,
+				ListTools.toList(Task.id_FIELDNAME, Task.person_FIELDNAME, Task.unit_FIELDNAME,
+						Task.routeName_FIELDNAME, Task.opinion_FIELDNAME, Task.startTime_FIELDNAME,
+						Task.activityName_FIELDNAME),
+				null);
+	}
+
+	public static class WoTaskCompleted extends TaskCompleted {
+
+		private static final long serialVersionUID = -4432508672641778924L;
+
+		static WrapCopier<TaskCompleted, WoTaskCompleted> copier = WrapCopierFactory.wo(TaskCompleted.class,
+				WoTaskCompleted.class,
+				ListTools.toList(TaskCompleted.id_FIELDNAME, TaskCompleted.person_FIELDNAME,
+						TaskCompleted.unit_FIELDNAME, TaskCompleted.routeName_FIELDNAME,
+						TaskCompleted.opinion_FIELDNAME, TaskCompleted.startTime_FIELDNAME,
+						TaskCompleted.activityName_FIELDNAME, TaskCompleted.completedTime_FIELDNAME),
+				null);
+	}
+
+	public static class WoRead extends Read {
+
+		private static final long serialVersionUID = -7243683008987722267L;
+
+		static WrapCopier<Read, WoRead> copier = WrapCopierFactory.wo(Read.class, WoRead.class,
+				ListTools.toList(Read.id_FIELDNAME, Read.person_FIELDNAME, Read.unit_FIELDNAME, Read.opinion_FIELDNAME,
+						Read.startTime_FIELDNAME, Read.activityName_FIELDNAME),
+				null);
+	}
+
+	public static class WoReadCompleted extends ReadCompleted {
+
+		private static final long serialVersionUID = -7086077858353505033L;
+
+		static WrapCopier<ReadCompleted, WoReadCompleted> copier = WrapCopierFactory.wo(ReadCompleted.class,
+				WoReadCompleted.class,
+				ListTools.toList(ReadCompleted.id_FIELDNAME, ReadCompleted.person_FIELDNAME,
+						ReadCompleted.unit_FIELDNAME, ReadCompleted.opinion_FIELDNAME,
+						ReadCompleted.startTime_FIELDNAME, ReadCompleted.activityName_FIELDNAME,
+						ReadCompleted.completedTime_FIELDNAME),
+				null);
+	}
+
+}

+ 0 - 13
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/worklog/ExceptionAccessDenied.java

@@ -1,13 +0,0 @@
-package com.x.processplatform.assemble.surface.jaxrs.worklog;
-
-import com.x.base.core.project.exception.PromptException;
-
-class ExceptionAccessDenied extends PromptException {
-
-	private static final long serialVersionUID = -5515077418025884395L;
-
-	ExceptionAccessDenied(String person) {
-		super("用户:{} 权限不足.", person);
-	}
-
-}

+ 19 - 7
o2server/x_processplatform_assemble_surface/src/main/java/com/x/processplatform/assemble/surface/jaxrs/worklog/WorkLogAction.java

@@ -4,10 +4,7 @@ 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;
@@ -15,9 +12,7 @@ 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 javax.ws.rs.core.Response;
 
-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;
@@ -28,7 +23,6 @@ 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;
-import com.x.processplatform.core.entity.element.ActivityType;
 
 @Path("worklog")
 @JaxrsDescribe("工作日志")
@@ -41,7 +35,7 @@ public class WorkLogAction extends StandardJaxrsAction {
 	@Path("list/job/{job}")
 	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
 	@Consumes(MediaType.APPLICATION_JSON)
-	public void get(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+	public void getWithJob(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
 			@JaxrsParameterDescribe("任务标识") @PathParam("job") String job) {
 		ActionResult<List<ActionListWithJob.Wo>> result = new ActionResult<>();
 		EffectivePerson effectivePerson = this.effectivePerson(request);
@@ -54,4 +48,22 @@ public class WorkLogAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
 	}
 
+	@JaxrsMethodDescribe(value = "根据指定Work或者WorkCompleted获取工作日志.", action = ActionListWithWorkOrWorkCompleted.class)
+	@GET
+	@Path("list/workorworkcompleted/{workOrWorkCompleted}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void getWithWork(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作或已完成工作标识") @PathParam("workOrWorkCompleted") String workOrWorkCompleted) {
+		ActionResult<List<ActionListWithWorkOrWorkCompleted.Wo>> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionListWithWorkOrWorkCompleted().execute(effectivePerson, workOrWorkCompleted);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
 }

+ 2 - 0
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/content/WorkCompleted.java

@@ -22,6 +22,7 @@ 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.entity.annotation.Flag;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.tools.DateTools;
 import com.x.processplatform.core.entity.PersistenceProperties;
@@ -287,6 +288,7 @@ public class WorkCompleted extends SliceJpaObject {
 	@CheckPersist(allowEmpty = true)
 	private String formMobileData;
 
+	@Flag
 	public static final String work_FIELDNAME = "work";
 	@FieldDescribe("Work Id.")
 	@Column(length = JpaObject.length_id, name = ColumnNamePrefix + work_FIELDNAME)

+ 0 - 1
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/element/Manual.java

@@ -1,6 +1,5 @@
 package com.x.processplatform.core.entity.element;
 
-import java.util.Date;
 import java.util.List;
 
 import javax.persistence.Basic;

+ 42 - 18
o2server/x_processplatform_core_entity/src/main/java/com/x/processplatform/core/entity/element/util/WorkLogTree.java

@@ -10,8 +10,8 @@ import org.apache.commons.collections4.list.TreeList;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 
-import com.x.base.core.project.gson.XGsonBuilder;
 import com.x.base.core.project.tools.ListTools;
+import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.content.WorkLog;
 import com.x.processplatform.core.entity.element.ActivityType;
 
@@ -27,25 +27,13 @@ public class WorkLogTree {
 		this.list = new ArrayList<WorkLog>(list);
 		List<String> froms = ListTools.extractProperty(list, WorkLog.fromActivityToken_FIELDNAME, String.class, true,
 				true);
-		System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!A");
-		System.out.println(XGsonBuilder.toJson(froms));
-		System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!A");
 		List<String> arriveds = ListTools.extractProperty(list, WorkLog.arrivedActivityToken_FIELDNAME, String.class,
 				true, true);
-		System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!b");
-		System.out.println(XGsonBuilder.toJson(arriveds));
-		System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Ab");
 		List<String> values = ListUtils.subtract(froms, arriveds);
-		System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!bc");
-		System.out.println(XGsonBuilder.toJson(values));
-		System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Abc");
 		List<WorkLog> begins = list.stream()
 				.filter(o -> BooleanUtils.isTrue(o.getConnected()) && values.contains(o.getFromActivityToken()))
 				.collect(Collectors.toList());
 		if (begins.size() != 1) {
-			System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-			System.out.println(XGsonBuilder.toJson(begins));
-			System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 			throw new ExceptionBeginNotFound(begins.size());
 		}
 		root = new Node();
@@ -79,6 +67,15 @@ public class WorkLogTree {
 			return true;
 		}
 
+		public boolean containsWorkLog(WorkLog workLog) {
+			for (Node n : this) {
+				if (Objects.equals(n.getWorkLog(), workLog)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
 	}
 
 	public static class Node {
@@ -92,9 +89,6 @@ public class WorkLogTree {
 			List<ActivityType> passActivityTypes = ListTools.toList(pass);
 			while ((p != null) && (!Objects.equals(p.workLog.getArrivedActivityType(), activityType))
 					&& ListTools.contains(passActivityTypes, p.workLog.getFromActivityType())) {
-				System.out.println("!!!!!!!!!!!!!!!!!!!!!!!");
-				System.out.println(p);
-				System.out.println("!!!!!!!!!!!!!!!!!!!!!!!");
 				p = p.parent;
 			}
 			return p;
@@ -106,8 +100,8 @@ public class WorkLogTree {
 
 	}
 
-	public WorkLog root() {
-		return root.workLog;
+	public Node root() {
+		return root;
 	}
 
 	public List<WorkLog> children(WorkLog workLog) {
@@ -179,4 +173,34 @@ public class WorkLogTree {
 		return nodes;
 	}
 
+	public Nodes rootTo(Node n) {
+		Nodes os = new Nodes();
+		Nodes loop = new Nodes();
+		loop.add(this.root());
+		while (!loop.isEmpty()) {
+			Nodes temps = new Nodes();
+			for (Node o : loop) {
+				if (!os.contains(o) && (n != o)) {
+					os.add(o);
+					temps.addAll(o.children);
+				}
+			}
+			loop = temps;
+		}
+		os.add(n);
+		return os;
+	}
+
+	public Node location(Work work) {
+		Node node = null;
+		for (Node o : nodes) {
+			if (Objects.equals(work.getActivityToken(), o.workLog.getFromActivityToken())) {
+				node = o;
+				break;
+			}
+		}
+		return node;
+
+	}
+
 }

+ 152 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/ActionCallback.java

@@ -0,0 +1,152 @@
+package com.x.processplatform.service.processing.jaxrs.work;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.BooleanUtils;
+
+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.project.exception.ExceptionEntityNotExist;
+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.tools.ListTools;
+import com.x.processplatform.core.entity.content.Read;
+import com.x.processplatform.core.entity.content.ReadCompleted;
+import com.x.processplatform.core.entity.content.Review;
+import com.x.processplatform.core.entity.content.Task;
+import com.x.processplatform.core.entity.content.TaskCompleted;
+import com.x.processplatform.core.entity.content.Work;
+import com.x.processplatform.core.entity.content.WorkLog;
+import com.x.processplatform.core.entity.element.util.WorkLogTree;
+import com.x.processplatform.core.entity.element.util.WorkLogTree.Node;
+import com.x.processplatform.core.entity.element.util.WorkLogTree.Nodes;
+import com.x.processplatform.service.processing.Processing;
+import com.x.processplatform.service.processing.ProcessingAttributes;
+
+class ActionCallback extends BaseAction {
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String id, JsonElement jsonElement) throws Exception {
+
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			ActionResult<Wo> result = new ActionResult<>();
+
+			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
+
+			Work work = emc.find(id, Work.class);
+
+			if (null == work) {
+				throw new ExceptionEntityNotExist(id, Work.class);
+			}
+
+			WorkLog workLog = emc.find(wi.getWorkLogId(), WorkLog.class);
+
+			if (null == workLog) {
+				throw new ExceptionEntityNotExist(wi.getWorkLogId(), WorkLog.class);
+			}
+
+			if (BooleanUtils.isTrue(workLog.getSplitting())) {
+				throw new ExceptionSplittingCannotCallback(work.getId(), workLog.getId());
+			}
+
+			List<WorkLog> workLogs = emc.listEqual(WorkLog.class, WorkLog.job_FIELDNAME, work.getJob());
+
+			WorkLogTree workLogTree = new WorkLogTree(workLogs);
+
+			Node node = workLogTree.find(workLog);
+
+			Nodes nodes = workLogTree.rootTo(node);
+
+			emc.beginTransaction(Work.class);
+			emc.beginTransaction(WorkLog.class);
+			emc.beginTransaction(Task.class);
+			emc.beginTransaction(TaskCompleted.class);
+			emc.beginTransaction(Read.class);
+			emc.beginTransaction(ReadCompleted.class);
+			emc.beginTransaction(Review.class);
+
+			work.setActivityName(workLog.getFromActivityName());
+			work.setActivity(workLog.getFromActivity());
+			work.setActivityAlias(workLog.getFromActivityAlias());
+			work.setActivityArrivedTime(workLog.getFromTime());
+			work.setActivityDescription("");
+			work.setActivityToken(workLog.getFromActivityToken());
+			work.setActivityType(workLog.getFromActivityType());
+
+			workLog.setConnected(false);
+			workLog.setArrivedActivity("");
+			workLog.setArrivedActivityAlias("");
+			workLog.setArrivedActivityName("");
+			workLog.setArrivedActivityToken("");
+			workLog.setArrivedActivityType(null);
+			workLog.setArrivedTime(null);
+			workLog.setDuration(0L);
+
+			List<WorkLog> removeWorkLogs = new ArrayList<>();
+
+			for (WorkLog o : workLogs) {
+				if (!nodes.containsWorkLog(o)) {
+					removeWorkLogs.add(o);
+				}
+			}
+
+			List<String> removeActivityToken = ListTools.extractProperty(removeWorkLogs,
+					WorkLog.fromActivityToken_FIELDNAME, String.class, true, true);
+
+			for (Task o : emc.listEqual(Task.class, Task.work_FIELDNAME, work.getId())) {
+				emc.remove(o);
+			}
+
+			for (TaskCompleted o : emc.listEqual(TaskCompleted.class, TaskCompleted.job_FIELDNAME, work.getJob())) {
+				if (removeActivityToken.contains(o.getActivityToken())) {
+					emc.remove(o);
+				}
+			}
+
+			for (ReadCompleted o : emc.listEqual(ReadCompleted.class, ReadCompleted.job_FIELDNAME, work.getJob())) {
+				if (removeActivityToken.contains(o.getActivityToken())) {
+					emc.remove(o);
+				}
+			}
+
+			for (Read o : emc.listEqual(Read.class, Read.job_FIELDNAME, work.getJob())) {
+				if (removeActivityToken.contains(o.getActivityToken())) {
+					emc.remove(o);
+				}
+			}
+
+			for (WorkLog o : removeWorkLogs) {
+				emc.remove(o);
+			}
+
+			emc.commit();
+
+			Processing processing = new Processing(wi);
+			processing.processing(work.getId());
+			Wo wo = new Wo();
+			wo.setId(work.getId());
+			result.setData(wo);
+			return result;
+		}
+	}
+
+	public static class Wi extends ProcessingAttributes {
+
+		private String workLogId;
+
+		public String getWorkLogId() {
+			return workLogId;
+		}
+
+		public void setWorkLogId(String workLogId) {
+			this.workLogId = workLogId;
+		}
+
+	}
+
+	public static class Wo extends WoId {
+	}
+
+}

+ 12 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/ExceptionSplittingCannotCallback.java

@@ -0,0 +1,12 @@
+package com.x.processplatform.service.processing.jaxrs.work;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ExceptionSplittingCannotCallback extends PromptException {
+
+	private static final long serialVersionUID = -3439770681867963457L;
+
+	ExceptionSplittingCannotCallback(String workId, String workLogId) {
+		super("工作无法回滚到处于拆分的状态,work:{}, workLog:{}.", workId, workLogId);
+	}
+}

+ 18 - 0
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/jaxrs/work/WorkAction.java

@@ -158,4 +158,22 @@ public class WorkAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
 	}
 
+	@JaxrsMethodDescribe(value = "回滚指定的工作到指定的workLog.", action = ActionCallback.class)
+	@PUT
+	@Path("{id}/callback")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void callback(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+			@JaxrsParameterDescribe("工作标识") @PathParam("id") String id, JsonElement jsonElement) {
+		ActionResult<ActionCallback.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionCallback().execute(effectivePerson, id, jsonElement);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
 }

+ 2 - 4
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/AbstractBaseProcessor.java

@@ -63,9 +63,6 @@ public abstract class AbstractBaseProcessor {
 	protected static String AIS = "afterInquireScript";
 	protected static String AIST = "afterInquireScriptText";
 
-	protected static String Binding_name_routes = "routes";
-	protected static String Binding_name_route = "route";
-
 	protected void arriveActivity(AeiObjects aeiObjects) throws Exception {
 		String token = aeiObjects.getWork().getActivityToken();
 		if (aeiObjects.getActivityProcessingConfigurator().getChangeActivityToken()) {
@@ -106,7 +103,8 @@ public abstract class AbstractBaseProcessor {
 
 	protected WorkLog stampArriveWorkLog(AeiObjects aeiObjects, String token, Date date) throws Exception {
 		WorkLog workLog = aeiObjects.getWorkLogs().stream()
-				.filter(o -> StringUtils.equals(aeiObjects.getWork().getActivityToken(), o.getFromActivityToken())
+				.filter(o -> StringUtils.equals(aeiObjects.getWork().getId(), o.getWork())
+						&& StringUtils.equals(aeiObjects.getWork().getActivityToken(), o.getFromActivityToken())
 						&& BooleanUtils.isNotTrue(o.getConnected()))
 				.findFirst().orElse(null);
 		if (null != workLog) {

+ 4 - 3
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/AbstractProcessor.java

@@ -11,6 +11,7 @@ import org.apache.commons.lang3.StringUtils;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.scripting.ScriptingEngine;
 import com.x.base.core.project.tools.ListTools;
 import com.x.collaboration.core.message.Collaboration;
 import com.x.collaboration.core.message.notification.ReadMessage;
@@ -43,7 +44,7 @@ public abstract class AbstractProcessor extends AbstractBaseProcessor {
 
 	public String arrive(String workId, ProcessingConfigurator processingConfigurator,
 			ProcessingAttributes processingAttributes) {
-		/** 返回值,如果返回值不为空,将继续循环 */
+		/* 返回值,如果返回值不为空,将继续循环 */
 		try {
 			Work work = this.entityManagerContainer().find(workId, Work.class);
 			if (null == work) {
@@ -306,7 +307,7 @@ public abstract class AbstractProcessor extends AbstractBaseProcessor {
 		if (aeiObjects.getActivityProcessingConfigurator().getCallBeforeInquireScript()) {
 			if (this.hasBeforeInquireScript(aeiObjects.getActivity())) {
 				ScriptHelper scriptHelper = ScriptHelperFactory.create(aeiObjects,
-						new BindingPair(Binding_name_routes, aeiObjects.getRoutes()));
+						new BindingPair(ScriptingEngine.BINDINGNAME_ROUTES, aeiObjects.getRoutes()));
 				scriptHelper.eval(aeiObjects.getWork().getApplication(),
 						Objects.toString(PropertyUtils.getProperty(aeiObjects.getActivity(), BIS)),
 						Objects.toString(PropertyUtils.getProperty(aeiObjects.getActivity(), BIST)));
@@ -318,7 +319,7 @@ public abstract class AbstractProcessor extends AbstractBaseProcessor {
 		if (aeiObjects.getActivityProcessingConfigurator().getCallAfterInquireScript()) {
 			if (this.hasAfterInquireScript(aeiObjects.getActivity())) {
 				ScriptHelper scriptHelper = ScriptHelperFactory.create(aeiObjects,
-						new BindingPair(Binding_name_routes, aeiObjects.getSelectRoutes()));
+						new BindingPair(ScriptingEngine.BINDINGNAME_ROUTES, aeiObjects.getSelectRoutes()));
 				scriptHelper.eval(aeiObjects.getWork().getApplication(),
 						Objects.toString(PropertyUtils.getProperty(aeiObjects.getActivity(), AIS)),
 						Objects.toString(PropertyUtils.getProperty(aeiObjects.getActivity(), AIST)));

+ 2 - 3
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/choice/ChoiceProcessor.java

@@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.scripting.ScriptingEngine;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.element.Choice;
 import com.x.processplatform.core.entity.element.Route;
@@ -17,8 +18,6 @@ import com.x.processplatform.service.processing.BindingPair;
 import com.x.processplatform.service.processing.ScriptHelper;
 import com.x.processplatform.service.processing.ScriptHelperFactory;
 import com.x.processplatform.service.processing.processor.AeiObjects;
-import com.x.processplatform.service.processing.processor.AeiObjects;
-import com.x.processplatform.service.processing.processor.AeiObjects;
 
 public class ChoiceProcessor extends AbstractChoiceProcessor {
 
@@ -56,7 +55,7 @@ public class ChoiceProcessor extends AbstractChoiceProcessor {
 		/* 多条路由进行判断 */
 		for (Route o : aeiObjects.getRoutes()) {
 			ScriptHelper scriptHelper = ScriptHelperFactory.create(aeiObjects,
-					new BindingPair(Binding_name_route, o));
+					new BindingPair(ScriptingEngine.BINDINGNAME_ROUTE, o));
 			Object obj = scriptHelper.eval(aeiObjects.getWork().getApplication(), o.getScript(), o.getScriptText());
 			if (BooleanUtils.toBoolean(StringUtils.trimToNull(Objects.toString(obj))) == true) {
 				results.add(o);

+ 11 - 5
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/merge/MergeProcessor.java

@@ -94,7 +94,6 @@ public class MergeProcessor extends AbstractMergeProcessor {
 				aeiObjects.getWorkLogs().stream()
 						.filter(p -> StringUtils.equals(p.getFromActivityToken(), o.getActivityToken()))
 						.forEach(obj -> {
-							obj.setWork(aeiObjects.getWork().getId());
 							aeiObjects.getDeleteWorkLogs().add(obj);
 						});
 			} catch (Exception e) {
@@ -126,6 +125,7 @@ public class MergeProcessor extends AbstractMergeProcessor {
 			aeiObjects.getTaskCompleteds().stream().filter(o -> StringUtils.equals(o.getWork(), work.getId()))
 					.forEach(o -> {
 						o.setWork(oldest.getId());
+						// o.setActivityToken(oldest.getActivityToken());
 						aeiObjects.getUpdateTaskCompleteds().add(o);
 					});
 		} catch (Exception e) {
@@ -137,6 +137,7 @@ public class MergeProcessor extends AbstractMergeProcessor {
 		try {
 			aeiObjects.getReads().stream().filter(o -> StringUtils.equals(o.getWork(), work.getId())).forEach(o -> {
 				o.setWork(oldest.getId());
+				// o.setActivityToken(oldest.getActivityToken());
 				aeiObjects.getUpdateReads().add(o);
 			});
 		} catch (Exception e) {
@@ -149,6 +150,7 @@ public class MergeProcessor extends AbstractMergeProcessor {
 			aeiObjects.getReadCompleteds().stream().filter(o -> StringUtils.equals(o.getWork(), work.getId()))
 					.forEach(o -> {
 						o.setWork(oldest.getId());
+						// o.setActivityToken(oldest.getActivityToken());
 						aeiObjects.getUpdateReadCompleteds().add(o);
 					});
 		} catch (Exception e) {
@@ -192,10 +194,14 @@ public class MergeProcessor extends AbstractMergeProcessor {
 
 	private void mergeWorkLog(AeiObjects aeiObjects, Work work, Work oldest) {
 		try {
-			aeiObjects.getWorkLogs().stream().filter(o -> StringUtils.equals(o.getWork(), work.getId())).forEach(o -> {
-				o.setWork(oldest.getId());
-				aeiObjects.getUpdateWorkLogs().add(o);
-			});
+			aeiObjects.getWorkLogs().stream()
+					.filter(o -> StringUtils.equals(work.getActivityToken(), o.getArrivedActivityToken())
+							&& StringUtils.equals(o.getWork(), work.getId()))
+					.forEach(o -> {
+						o.setWork(oldest.getId());
+						o.setArrivedActivityToken(oldest.getActivityToken());
+						aeiObjects.getUpdateWorkLogs().add(o);
+					});
 		} catch (Exception e) {
 			logger.error(e);
 		}

+ 28 - 11
o2server/x_processplatform_service_processing/src/main/java/com/x/processplatform/service/processing/processor/parallel/ParallelProcessor.java

@@ -2,18 +2,23 @@ package com.x.processplatform.service.processing.processor.parallel;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
+import org.apache.commons.lang3.BooleanUtils;
 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.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.scripting.ScriptingEngine;
 import com.x.base.core.project.tools.StringTools;
 import com.x.processplatform.core.entity.content.Work;
 import com.x.processplatform.core.entity.content.WorkLog;
 import com.x.processplatform.core.entity.element.Parallel;
 import com.x.processplatform.core.entity.element.Route;
+import com.x.processplatform.service.processing.BindingPair;
+import com.x.processplatform.service.processing.ScriptHelper;
+import com.x.processplatform.service.processing.ScriptHelperFactory;
 import com.x.processplatform.service.processing.processor.AeiObjects;
 
 public class ParallelProcessor extends AbstractParallelProcessor {
@@ -48,31 +53,43 @@ public class ParallelProcessor extends AbstractParallelProcessor {
 		aeiObjects.getWork().setSplitValue("");
 		/* 新创建并行Work需要单独的workLog,拷贝当前的WorkLog */
 		WorkLog mainWorkLog = aeiObjects.getWorkLogs().stream()
-				.filter(o -> StringUtils.equals(aeiObjects.getWork().getActivityToken(), o.getFromActivityToken()))
+				.filter(o -> StringUtils.equals(aeiObjects.getWork().getId(), o.getWork())
+						&& StringUtils.equals(aeiObjects.getWork().getActivityToken(), o.getFromActivityToken()))
 				.findFirst().orElse(null);
 		mainWorkLog.setSplitting(aeiObjects.getWork().getSplitting());
 		mainWorkLog.setSplitTokenList(aeiObjects.getWork().getSplitTokenList());
 		mainWorkLog.setSplitToken(aeiObjects.getWork().getSplitToken());
 		mainWorkLog.setSplitValue(aeiObjects.getWork().getSplitValue());
 		aeiObjects.getUpdateWorkLogs().add(mainWorkLog);
-		for (int i = 0; i < aeiObjects.getRoutes().size(); i++) {
-			Route route = aeiObjects.getRoutes().get(i);
+
+		List<Route> routes = new ArrayList<>();
+		/* 多条路由进行判断 */
+		for (Route o : aeiObjects.getRoutes()) {
+			ScriptHelper scriptHelper = ScriptHelperFactory.create(aeiObjects,
+					new BindingPair(ScriptingEngine.BINDINGNAME_ROUTE, o));
+			Object obj = scriptHelper.eval(aeiObjects.getWork().getApplication(), o.getScript(), o.getScriptText());
+			if (BooleanUtils.toBoolean(StringUtils.trimToNull(Objects.toString(obj))) == true) {
+				routes.add(o);
+			}
+		}
+
+		for (int i = 0; i < routes.size(); i++) {
+			Route route = routes.get(i);
 			if (i == 0) {
 				aeiObjects.getWork().setDestinationRoute(route.getId());
 				aeiObjects.getWork().setDestinationRouteName(route.getName());
 				results.add(aeiObjects.getWork());
 			} else {
-				Work work = new Work();
-				aeiObjects.getWork().copyTo(work, JpaObject.id_FIELDNAME);
+				Work work = new Work(aeiObjects.getWork());
+				// aeiObjects.getWork().copyTo(work, JpaObject.id_FIELDNAME);
 				work.setDestinationRoute(route.getId());
 				work.setDestinationRouteName(route.getName());
-				String activityToken = StringTools.uniqueToken();
-				work.setActivityToken(activityToken);
+				// String activityToken = StringTools.uniqueToken();
+				// work.setActivityToken(activityToken);
 				/* 创建新的Token */
-				WorkLog workLog = new WorkLog();
-				mainWorkLog.copyTo(workLog, JpaObject.id_FIELDNAME);
+				WorkLog workLog = new WorkLog(mainWorkLog);
 				workLog.setWork(work.getId());
-				workLog.setFromActivityToken(activityToken);
+				// workLog.setFromActivityToken(activityToken);
 				aeiObjects.getCreateWorks().add(work);
 				aeiObjects.getCreateWorkLogs().add(workLog);
 				results.add(work);

+ 7 - 2
o2server/x_query_assemble_surface/src/main/java/com/x/query/assemble/surface/jaxrs/view/BaseAction.java

@@ -124,11 +124,16 @@ abstract class BaseAction extends StandardJaxrsAction {
 					row = plan.grid.get(j);
 					r = sheet.createRow(j + 1);
 					i = 0;
-					for (Entry<String, Object> entry : row.data.entrySet()) {
+					for (SelectEntry o : plan.selectList) {
 						c = r.createCell(i);
-						c.setCellValue(Objects.toString(entry.getValue(), ""));
+						c.setCellValue(Objects.toString(row.get(o.column)));
 						i++;
 					}
+//					for (Entry<String, Object> entry : row.data.entrySet()) {
+//						c = r.createCell(i);
+//						c.setCellValue(Objects.toString(entry.getValue(), ""));
+//						i++;
+//					}
 				}
 			}
 			String name = view.getName() + ".xlsx";