Explorar o código

增加腾讯企业邮

roo00 %!s(int64=6) %!d(string=hai) anos
pai
achega
15df446dd4
Modificáronse 100 ficheiros con 2739 adicións e 690 borrados
  1. 4 4
      o2server/start_aix.sh
  2. 4 4
      o2server/start_aix_debug.sh
  3. 4 4
      o2server/start_kylinos_phytium.sh
  4. 4 4
      o2server/start_kylinos_phytium_debug.sh
  5. 4 4
      o2server/start_linux_debug.sh
  6. 4 4
      o2server/start_macos.sh
  7. 4 4
      o2server/start_macos_debug.sh
  8. 4 4
      o2server/start_neokylin_loongson.sh
  9. 4 4
      o2server/start_neokylin_loongson_debug.sh
  10. 4 4
      o2server/start_raspberrypi.sh
  11. 4 4
      o2server/start_raspberrypi_debug.sh
  12. 4 4
      o2server/start_windows.bat
  13. 4 4
      o2server/start_windows_debug.bat
  14. 1 1
      o2server/version.o2
  15. 98 34
      o2server/x_base_core_project/src/main/java/com/x/base/core/container/EntityManagerContainer.java
  16. 1 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/Applications.java
  17. 4 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/build/CreateConfigSample.java
  18. 38 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Config.java
  19. 65 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Dingding.java
  20. 13 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/ExceptionExmailNewRemindAccessToken.java
  21. 12 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/ExceptionExmailSsoAccessToken.java
  22. 315 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Exmail.java
  23. 30 2
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Message.java
  24. 19 2
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Messages.java
  25. 70 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Qiyeweixin.java
  26. 85 12
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Query.java
  27. 23 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/exception/ExceptionAccessDeniedOrEntityNotExist.java
  28. 4 3
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/http/HttpToken.java
  29. 1 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/AbstractActionApplication.java
  30. 12 4
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/MessageBodyReaderImpl.java
  31. 0 13
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/WrapInMessageBodyReader.java
  32. 30 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/message/DingdingMessage.java
  33. 6 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/organization/OrganizationDefinition.java
  34. 2 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/tools/BaseTools.java
  35. 1 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_cms_assemble_control.java
  36. 1 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_processplatform_assemble_surface.java
  37. 1 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_processplatform_service_processing.java
  38. 49 45
      o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/image/ActionImageBase64.java
  39. 26 21
      o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/login/ActionLogin.java
  40. 26 23
      o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/replyinfo/ActionListMyReplyForPages.java
  41. 81 71
      o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/replyinfo/ActionListWithSubjectForPage.java
  42. 64 49
      o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/roleinfo/ActionBindRoleToUser.java
  43. 8 4
      o2server/x_calendar_core_entity/src/main/java/com/x/calendar/core/entity/Calendar_EventComment.java
  44. 13 31
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/Business.java
  45. 29 0
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/factory/AppInfoConfigFactory.java
  46. 5 4
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/ActionApplication.java
  47. 3 2
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/CmsJaxrsFilter.java
  48. 22 5
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionGet.java
  49. 61 0
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionGetConfig.java
  50. 12 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanManage.java
  51. 14 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanManage_WithAppType.java
  52. 14 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanPublish.java
  53. 13 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanPublish_WithAppType.java
  54. 14 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewAllDocType.java
  55. 14 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewAllDocType_WithAppType.java
  56. 14 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewArticle.java
  57. 14 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewArticle_WithAppType.java
  58. 14 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewData.java
  59. 14 6
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewData_WithAppType.java
  60. 6 2
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionSave.java
  61. 63 0
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionSaveConfig.java
  62. 75 0
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/AppInfoConfigAction.java
  63. 26 33
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/BaseAction.java
  64. 3 2
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistDraftDocument.java
  65. 1 1
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistImportDataExcel.java
  66. 17 18
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistPublishByWorkFlow.java
  67. 17 18
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistPublishContent.java
  68. 11 10
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistSaveDocument.java
  69. 3 0
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionQueryListPrevWithFilter.java
  70. 1 1
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/DocumentAction.java
  71. 0 12
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ExceptionDocumentTitleEmpty.java
  72. 4 3
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/ActionFileUpdate.java
  73. 5 4
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/ActionFileUpdateCallback.java
  74. 4 3
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/ActionFileUpload.java
  75. 5 3
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/ActionFileUploadCallback.java
  76. 12 8
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/FileInfoAction.java
  77. 36 25
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/input/ActionCover.java
  78. 33 8
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/input/ActionCreate.java
  79. 13 5
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/output/ActionList.java
  80. 15 16
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/output/ActionSelect.java
  81. 8 8
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/queue/QueueSendDocumentNotify.java
  82. 89 19
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/service/AppInfoService.java
  83. 70 18
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/service/AppInfoServiceAdv.java
  84. 72 0
      o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/AppInfoConfig.java
  85. 5 1
      o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/PersistenceProperties.java
  86. 12 5
      o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/element/wrap/WrapCms.java
  87. 2 0
      o2server/x_console/src/main/java/com/x/server/console/ResourceFactory.java
  88. 1 1
      o2server/x_jpush_assemble_control/src/main/java/com/x/jpush/assemble/control/jaxrs/message/ActionSendMessage.java
  89. 114 1
      o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/DingdingConsumeQueue.java
  90. 144 1
      o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/QiyeweixinConsumeQueue.java
  91. 65 14
      o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/connector/ActionCreate.java
  92. 25 0
      o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthDingdingConfig.java
  93. 142 0
      o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthDingdingLogin.java
  94. 18 0
      o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthList.java
  95. 25 0
      o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthQiyeweixinConfig.java
  96. 94 0
      o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthQiyeweixinLogin.java
  97. 76 0
      o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/AuthenticationAction.java
  98. 12 0
      o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ExceptionOauthDingdingErrorInfo.java
  99. 6 6
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/group/ActionGet.java
  100. 1 0
      o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/identity/ActionOrder.java

+ 4 - 4
o2server/start_aix.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_aix_debug.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_kylinos_phytium.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_kylinos_phytium_debug.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_linux_debug.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_macos.sh

@@ -7,8 +7,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -16,8 +16,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_macos_debug.sh

@@ -7,8 +7,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -16,8 +16,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_neokylin_loongson.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_neokylin_loongson_debug.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_raspberrypi.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		sudo mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		sudo mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		sudo mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		sudo mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		sudo mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		sudo mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		sudo mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		sudo mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_raspberrypi_debug.sh

@@ -6,8 +6,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/config ]; then
 		sudo mkdir ${current_dir}/config
 	fi
-	if [ ! -d ${current_dir}/config/sample ]; then
-		sudo mkdir ${current_dir}/config/sample
+	if [ ! -d ${current_dir}/configSample ]; then
+		sudo mkdir ${current_dir}/configSample
 	fi
 	if [ ! -d ${current_dir}/local ]; then
 		sudo mkdir ${current_dir}/local
@@ -15,8 +15,8 @@ if [ -d ${current_dir}/local/update ]; then
 	if [ ! -d ${current_dir}/local ]; then
 		sudo mkdir ${current_dir}/local
 	fi
-	if [ ! -d ${current_dir}/local/sample ]; then
-		sudo mkdir ${current_dir}/local/sample
+	if [ ! -d ${current_dir}/localSample ]; then
+		sudo mkdir ${current_dir}/localSample
 	fi
 	if [ ! -d ${current_dir}/jvm ]; then
 		sudo mkdir ${current_dir}/jvm

+ 4 - 4
o2server/start_windows.bat

@@ -6,14 +6,14 @@ if exist "%~dp0local\update" (
 	if not exist "%~dp0config" (
 		mkdir "%~dp0config"
 	)
-	if not exist "%~dp0config/sample" (
-		mkdir "%~dp0config/sample"
+	if not exist "%~dp0configSample" (
+		mkdir "%~dp0configSample"
 	)
 	if not exist "%~dp0local" (
 		mkdir "%~dp0local"
 	)
-	if not exist "%~dp0local/sample" (
-		mkdir "%~dp0local/sample"
+	if not exist "%~dp0localSample" (
+		mkdir "%~dp0localSample"
 	)
 	if not exist "%~dp0jvm" (
 		mkdir "%~dp0jvm"

+ 4 - 4
o2server/start_windows_debug.bat

@@ -6,14 +6,14 @@ if exist "%~dp0local\update" (
 	if not exist "%~dp0config" (
 		mkdir "%~dp0config"
 	)
-	if not exist "%~dp0config/sample" (
-		mkdir "%~dp0config/sample"
+	if not exist "%~dp0configSample" (
+		mkdir "%~dp0configSample"
 	)
 	if not exist "%~dp0local" (
 		mkdir "%~dp0local"
 	)
-	if not exist "%~dp0local/sample" (
-		mkdir "%~dp0local/sample"
+	if not exist "%~dp0localSample" (
+		mkdir "%~dp0localSample"
 	)
 	if not exist "%~dp0jvm" (
 		mkdir "%~dp0jvm"

+ 1 - 1
o2server/version.o2

@@ -1 +1 @@
-2020-01-07 22:22:27
+2020-02-07 17:43:19

+ 98 - 34
o2server/x_base_core_project/src/main/java/com/x/base/core/container/EntityManagerContainer.java

@@ -521,6 +521,62 @@ public class EntityManagerContainer extends EntityManagerContainerBasic {
 		return new ArrayList<T>(query.getResultList());
 	}
 
+	public <T extends JpaObject> List<T> listNotEqual(Class<T> cls, String attribute, Object value) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root).where(cb.or(cb.isNull(root.get(attribute)), cb.notEqual(root.get(attribute), value)));
+		List<T> os = em.createQuery(cq).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject, W extends Object> List<T> listIn(Class<T> cls, String attribute, Collection<W> values)
+			throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root).where(cb.isMember(root.get(attribute), cb.literal(values)));
+		List<T> os = em.createQuery(cq.distinct(true)).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> List<T> listIsMember(Class<T> cls, String attribute, Object value) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root).where(cb.isMember(value, root.get(attribute)));
+		List<T> os = em.createQuery(cq).getResultList();
+		List<T> list = new ArrayList<>(os);
+		return list;
+	}
+
+	public <T extends JpaObject> T firstEqual(Class<T> cls, String attribute, Object value) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root).where(cb.equal(root.get(attribute), value));
+		List<T> os = em.createQuery(cq).setMaxResults(1).getResultList();
+		return os.isEmpty() ? null : os.get(0);
+	}
+
+	public <T extends JpaObject> T firstEqualAndEqual(Class<T> cls, String attribute, Object value,
+			String otherAttribute, Object otherValue) throws Exception {
+		EntityManager em = this.get(cls);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<T> cq = cb.createQuery(cls);
+		Root<T> root = cq.from(cls);
+		cq.select(root)
+				.where(cb.and(cb.equal(root.get(attribute), value), cb.equal(root.get(otherAttribute), otherValue)));
+		List<T> os = em.createQuery(cq).setMaxResults(1).getResultList();
+		return os.isEmpty() ? null : os.get(0);
+	}
+
 	public <T extends JpaObject> Long count(Class<T> cls) throws Exception {
 		EntityManager em = this.get(cls);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
@@ -664,40 +720,6 @@ public class EntityManagerContainer extends EntityManagerContainerBasic {
 		return em.createQuery(cq).getSingleResult();
 	}
 
-	public <T extends JpaObject> List<T> listNotEqual(Class<T> cls, String attribute, Object value) throws Exception {
-		EntityManager em = this.get(cls);
-		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<T> cq = cb.createQuery(cls);
-		Root<T> root = cq.from(cls);
-		cq.select(root).where(cb.or(cb.isNull(root.get(attribute)), cb.notEqual(root.get(attribute), value)));
-		List<T> os = em.createQuery(cq).getResultList();
-		List<T> list = new ArrayList<>(os);
-		return list;
-	}
-
-	public <T extends JpaObject, W extends Object> List<T> listIn(Class<T> cls, String attribute, Collection<W> values)
-			throws Exception {
-		EntityManager em = this.get(cls);
-		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<T> cq = cb.createQuery(cls);
-		Root<T> root = cq.from(cls);
-		cq.select(root).where(cb.isMember(root.get(attribute), cb.literal(values)));
-		List<T> os = em.createQuery(cq.distinct(true)).getResultList();
-		List<T> list = new ArrayList<>(os);
-		return list;
-	}
-
-	public <T extends JpaObject> List<T> listIsMember(Class<T> cls, String attribute, Object value) throws Exception {
-		EntityManager em = this.get(cls);
-		CriteriaBuilder cb = em.getCriteriaBuilder();
-		CriteriaQuery<T> cq = cb.createQuery(cls);
-		Root<T> root = cq.from(cls);
-		cq.select(root).where(cb.isMember(value, root.get(attribute)));
-		List<T> os = em.createQuery(cq).getResultList();
-		List<T> list = new ArrayList<>(os);
-		return list;
-	}
-
 	public <T extends JpaObject> List<String> ids(Class<T> cls) throws Exception {
 		EntityManager em = this.get(cls);
 		CriteriaBuilder cb = em.getCriteriaBuilder();
@@ -1036,6 +1058,48 @@ public class EntityManagerContainer extends EntityManagerContainerBasic {
 		return copier.copy(os);
 	}
 
+	/* 仅在单一数据库可用 */
+	public <T extends JpaObject> List<T> fetch(Class<T> clz, Predicate predicate)
+			throws Exception {
+		List<T> os = fetch(clz, JpaObject.singularAttributeField(clz, true, true), predicate);
+		return os;
+	}
+
+	/* 仅在单一数据库可用 */
+	public <T extends JpaObject, W extends GsonPropertyObject> List<W> fetch(Class<T> clz, WrapCopier<T, W> copier,
+			Predicate predicate) throws Exception {
+		List<T> os = fetch(clz, copier.getCopyFields(), predicate);
+		return copier.copy(os);
+	}
+
+	/* 仅在单一数据库可用 */
+	public <T extends JpaObject, W extends GsonPropertyObject> List<T> fetch(Class<T> clz, List<String> fetchAttributes,
+			Predicate predicate) throws Exception {
+		List<T> list = new ArrayList<>();
+		List<String> fields = ListTools.trim(fetchAttributes, true, true, JpaObject.id_FIELDNAME);
+		EntityManager em = this.get(clz);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<T> root = cq.from(clz);
+		List<Selection<?>> selections = new ArrayList<>();
+		for (String str : fields) {
+			selections.add(root.get(str));
+		}
+		cq.multiselect(selections).where(predicate);
+//		if (StringUtils.isNotEmpty(orderAttribute)) {
+//			cq.orderBy(cb.desc(root.get(orderAttribute)));
+//		}
+		T t = null;
+		for (Tuple o : em.createQuery(cq).getResultList()) {
+			t = clz.newInstance();
+			for (int i = 0; i < fields.size(); i++) {
+				PropertyUtils.setProperty(t, fields.get(i), o.get(selections.get(i)));
+			}
+			list.add(t);
+		}
+		return list;
+	}
+
 	public <T extends JpaObject> List<T> fetchEqual(Class<T> clz, String attribute, Object value) throws Exception {
 		List<T> os = this.fetchEqual(clz, JpaObject.singularAttributeField(clz, true, true), attribute, value);
 		return os;

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

@@ -327,7 +327,7 @@ public class Applications extends ConcurrentHashMap<String, CopyOnWriteArrayList
 		CRC32 crc32 = new CRC32();
 		crc32.update(seed.getBytes(DefaultCharset.charset));
 		int idx = (int) crc32.getValue() % list.size();
-		return list.get(idx);
+		return list.get(Math.abs(idx));
 	}
 
 	public static String joinQueryUri(String... parts) {

+ 4 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/build/CreateConfigSample.java

@@ -21,10 +21,12 @@ import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.config.AppStyle;
 import com.x.base.core.project.config.CenterServer;
 import com.x.base.core.project.config.Collect;
+import com.x.base.core.project.config.Communicate;
 import com.x.base.core.project.config.ConfigObject;
 import com.x.base.core.project.config.Dingding;
 import com.x.base.core.project.config.DumpRestoreData;
 import com.x.base.core.project.config.DumpRestoreStorage;
+import com.x.base.core.project.config.Exmail;
 import com.x.base.core.project.config.ExternalDataSource;
 import com.x.base.core.project.config.LogLevel;
 import com.x.base.core.project.config.Meeting;
@@ -70,6 +72,8 @@ public class CreateConfigSample {
 		classes.add(WorkTime.class);
 		classes.add(ZhengwuDingding.class);
 		classes.add(ExternalDataSource.class);
+		classes.add(Exmail.class);
+		classes.add(Communicate.class);
 
 		Collections.sort(classes, new Comparator<Class<?>>() {
 			public int compare(Class<?> c1, Class<?> c2) {

+ 38 - 1
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Config.java

@@ -50,6 +50,7 @@ public class Config {
 	public static final String PATH_CONFIG_DUMPRESTOREDATA = "config/dumpRestoreData.json";
 	public static final String PATH_CONFIG_DUMPRESTORESTORAGE = "config/dumpRestoreStorage.json";
 	public static final String PATH_CONFIG_MESSAGES = "config/messages.json";
+	public static final String PATH_CONFIG_MESSAGES_SEND_RULE = "config/messageSendRule.js";
 	public static final String PATH_CONFIG_SSLKEYSTORE = "config/keystore";
 	public static final String PATH_CONFIG_SSLKEYSTORESAMPLE = "config/sample/keystore";
 	public static final String PATH_CONFIG_STARTIMAGE = "config/startImage.png";
@@ -69,6 +70,7 @@ public class Config {
 	public static final String PATH_COMMONS_MOOTOOLSSCRIPTTEXT = "commons/mooToolsScriptText.js";
 	public static final String PATH_CONFIG_JPUSH = "config/jpushConfig.json";
 	public static final String PATH_CONFIG_COMMUNICATE = "config/communicate.json";
+	public static final String PATH_CONFIG_EXMAIL = "config/exmail.json";
 
 	public static final String DIR_COMMONS = "commons";
 	public static final String DIR_COMMONS_TESS4J_TESSDATA = "commons/tess4j/tessdata";
@@ -909,7 +911,8 @@ public class Config {
 					Messages custom = BaseTools.readConfigObject(PATH_CONFIG_MESSAGES, Messages.class);
 					if (null != custom) {
 						custom.entrySet().stream().forEach(o -> {
-							obj.put(o.getKey(), new Message(o.getValue().getConsumers()));
+							obj.put(o.getKey(),
+									new Message(o.getValue().getConsumers(), o.getValue().getConsumersV2()));
 						});
 					}
 					instance().messages = obj;
@@ -919,6 +922,23 @@ public class Config {
 		return instance().messages;
 	}
 
+	private String messageSendRuleScript;
+
+	public static String messageSendRuleScript() throws Exception {
+		if (null == instance().messageSendRuleScript) {
+			synchronized (Config.class) {
+				if (null == instance().messageSendRuleScript) {
+					String scriptStr = BaseTools.readString(PATH_CONFIG_MESSAGES_SEND_RULE);
+					if (scriptStr == null) {
+						scriptStr = "";
+					}
+					instance().messageSendRuleScript = scriptStr;
+				}
+			}
+		}
+		return instance().messageSendRuleScript;
+	}
+
 	private PushConfig pushConfig;
 
 	public static PushConfig pushConfig() throws Exception {
@@ -1158,6 +1178,23 @@ public class Config {
 		return instance().slice;
 	}
 
+	public Exmail exmail;
+
+	public static Exmail exmail() throws Exception {
+		if (null == instance().exmail) {
+			synchronized (Config.class) {
+				if (null == instance().exmail) {
+					Exmail obj = BaseTools.readConfigObject(PATH_CONFIG_EXMAIL, Exmail.class);
+					if (null == obj) {
+						obj = Exmail.defaultInstance();
+					}
+					instance().exmail = obj;
+				}
+			}
+		}
+		return instance().exmail;
+	}
+
 	public static Object resource(String name) throws Exception {
 		return initialContext().lookup(name);
 	}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 65 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Dingding.java


+ 13 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/ExceptionExmailNewRemindAccessToken.java

@@ -0,0 +1,13 @@
+package com.x.base.core.project.config;
+
+import com.x.base.core.project.exception.PromptException;
+import com.x.base.core.project.http.EffectivePerson;
+
+class ExceptionExmailNewRemindAccessToken extends PromptException {
+
+	private static final long serialVersionUID = -3439770681867963457L;
+
+	ExceptionExmailNewRemindAccessToken(Integer code, String message) {
+		super("获取腾讯企业邮新邮件提醒accessToken失败,错误代码:{}, 错误消息:{}.", code, message);
+	}
+}

+ 12 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/ExceptionExmailSsoAccessToken.java

@@ -0,0 +1,12 @@
+package com.x.base.core.project.config;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ExceptionExmailSsoAccessToken extends PromptException {
+
+	private static final long serialVersionUID = -3439770681867963457L;
+
+	ExceptionExmailSsoAccessToken(Integer code, String message) {
+		super("获取腾讯企业邮单点登录accessToken失败,错误代码:{}, 错误消息:{}.", code, message);
+	}
+}

+ 315 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Exmail.java

@@ -0,0 +1,315 @@
+package com.x.base.core.project.config;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.connection.HttpConnection;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.gson.XGsonBuilder;
+import com.x.base.core.project.tools.DefaultCharset;
+
+/**
+ * 回调要求本地网络端口更换到80、 443、 8080 这三个端口再试,核实使用其它端口会被限制不能连接
+ */
+public class Exmail extends ConfigObject {
+
+	@FieldDescribe("是否启用.")
+	private Boolean enable;
+	@FieldDescribe("腾讯企业邮corpId")
+	private String corpId;
+	@FieldDescribe("新邮件提醒secret")
+	private String newRemindSecret;
+	@FieldDescribe("单点登录secret")
+	private String ssoSecret;
+	@FieldDescribe("corpAccessToken获取地址")
+	private String corpAccessTokenAddress;
+	@FieldDescribe("新邮件数量获取地址")
+	private String newCountAddress;
+	@FieldDescribe("单点登录获取地址")
+	private String ssoAddress;
+	@FieldDescribe("回调token")
+	private String token;
+	@FieldDescribe("回调encodingAesKey")
+	private String encodingAesKey;
+	@FieldDescribe(" 存储邮件数量个人属性值.")
+	private String personAttributeNewCountName;
+	@FieldDescribe(" 存储邮件标题个人属性值.")
+	private String personAttributeTitleName;
+
+	public static Exmail defaultInstance() {
+		return new Exmail();
+	}
+
+	public static final Boolean default_enable = false;
+	public static final String default_corpId = "";
+	public static final String default_corpSecret = "";
+	public static final String default_newRemindSecret = "";
+	public static final String default_ssoSecret = "";
+	public static final String default_corpAccessTokenAddress = "https://api.exmail.qq.com/cgi-bin/gettoken";
+	public static final String default_newCountAddress = "https://api.exmail.qq.com/cgi-bin/mail/newcount";
+	public static final String default_ssoAddress = "https://api.exmail.qq.com/cgi-bin/service/get_login_url";
+	public static final String default_personAttributeNewCountName = "exmailNewCount";
+	public static final String default_personAttributeTitleName = "exmailTitle";
+
+	public Exmail() {
+		this.enable = default_enable;
+		this.corpId = default_corpId;
+		this.corpAccessTokenAddress = default_corpAccessTokenAddress;
+		this.newCountAddress = default_newCountAddress;
+		this.ssoAddress = default_ssoAddress;
+		this.personAttributeNewCountName = default_personAttributeNewCountName;
+		this.personAttributeTitleName = default_personAttributeTitleName;
+	}
+
+	public Boolean getEnable() {
+		return BooleanUtils.isTrue(this.enable);
+	}
+
+	public String getCorpId() {
+		return StringUtils.isEmpty(corpId) ? default_corpId : this.corpId;
+	}
+
+	public String getNewRemindSecret() {
+		return StringUtils.isEmpty(newRemindSecret) ? default_newRemindSecret : this.newRemindSecret;
+	}
+
+	public String getSsoSecret() {
+		return StringUtils.isEmpty(ssoSecret) ? default_ssoSecret : this.ssoSecret;
+	}
+
+	public String getCorpAccessTokenAddress() {
+		return StringUtils.isEmpty(this.corpAccessTokenAddress) ? default_corpAccessTokenAddress
+				: this.corpAccessTokenAddress;
+	}
+
+	public String getNewCountAddress() {
+		return StringUtils.isEmpty(this.newCountAddress) ? default_newCountAddress : this.newCountAddress;
+	}
+
+	public String getSsoAddress() {
+		return StringUtils.isEmpty(this.ssoAddress) ? default_ssoAddress : this.ssoAddress;
+	}
+
+	public String getPersonAttributeNewCountName() {
+		return StringUtils.isEmpty(this.personAttributeNewCountName) ? default_personAttributeNewCountName
+				: this.personAttributeNewCountName;
+	}
+
+	public String getPersonAttributeTitleName() {
+		return StringUtils.isEmpty(this.personAttributeTitleName) ? default_personAttributeTitleName
+				: this.personAttributeTitleName;
+	}
+
+	private static String cachedNewRemindAccessToken;
+	private static Date cachedNewRemindAccessTokenDate;
+
+	public String newRemindAccessToken() throws Exception {
+		if ((StringUtils.isNotEmpty(cachedNewRemindAccessToken) && (null != cachedNewRemindAccessTokenDate))
+				&& (cachedNewRemindAccessTokenDate.after(new Date()))) {
+			return cachedNewRemindAccessToken;
+		} else {
+			String address = getCorpAccessTokenAddress() + "?corpid=" + this.getCorpId() + "&corpsecret="
+					+ this.getNewRemindSecret();
+			NewRemindAccessTokenResp resp = HttpConnection.getAsObject(address, null, NewRemindAccessTokenResp.class);
+			if (resp.getErrcode() != 0) {
+				throw new ExceptionExmailNewRemindAccessToken(resp.getErrcode(), resp.getErrmsg());
+			}
+			cachedNewRemindAccessToken = resp.getAccess_token();
+			Calendar cal = Calendar.getInstance();
+			cal.add(Calendar.MINUTE, 90);
+			cachedNewRemindAccessTokenDate = cal.getTime();
+			return cachedNewRemindAccessToken;
+		}
+	}
+
+	private static String cachedSsoAccessToken;
+	private static Date cachedSsoAccessTokenDate;
+
+	public String ssoAccessToken() throws Exception {
+		if ((StringUtils.isNotEmpty(cachedSsoAccessToken) && (null != cachedSsoAccessTokenDate))
+				&& (cachedSsoAccessTokenDate.after(new Date()))) {
+			return cachedSsoAccessToken;
+		} else {
+			String address = getCorpAccessTokenAddress() + "?corpid=" + this.getCorpId() + "&corpsecret="
+					+ this.getSsoSecret();
+			SsoAccessTokenResp resp = HttpConnection.getAsObject(address, null, SsoAccessTokenResp.class);
+			if (resp.getErrcode() != 0) {
+				throw new ExceptionExmailSsoAccessToken(resp.getErrcode(), resp.getErrmsg());
+			}
+			cachedSsoAccessToken = resp.getAccess_token();
+			Calendar cal = Calendar.getInstance();
+			cal.add(Calendar.MINUTE, 90);
+			cachedSsoAccessTokenDate = cal.getTime();
+			return cachedSsoAccessToken;
+		}
+	}
+
+	public static class SsoAccessTokenResp extends GsonPropertyObject {
+
+		private Integer errcode;
+		private String access_token;
+		private String errmsg;
+		private Integer expires_in;
+
+		public Integer getErrcode() {
+			return errcode;
+		}
+
+		public void setErrcode(Integer errcode) {
+			this.errcode = errcode;
+		}
+
+		public String getAccess_token() {
+			return access_token;
+		}
+
+		public void setAccess_token(String access_token) {
+			this.access_token = access_token;
+		}
+
+		public String getErrmsg() {
+			return errmsg;
+		}
+
+		public void setErrmsg(String errmsg) {
+			this.errmsg = errmsg;
+		}
+
+		public Integer getExpires_in() {
+			return expires_in;
+		}
+
+		public void setExpires_in(Integer expires_in) {
+			this.expires_in = expires_in;
+		}
+
+	}
+
+	public static class NewRemindAccessTokenResp extends GsonPropertyObject {
+
+		private Integer errcode;
+		private String access_token;
+		private String errmsg;
+		private Integer expires_in;
+
+		public Integer getErrcode() {
+			return errcode;
+		}
+
+		public void setErrcode(Integer errcode) {
+			this.errcode = errcode;
+		}
+
+		public String getAccess_token() {
+			return access_token;
+		}
+
+		public void setAccess_token(String access_token) {
+			this.access_token = access_token;
+		}
+
+		public String getErrmsg() {
+			return errmsg;
+		}
+
+		public void setErrmsg(String errmsg) {
+			this.errmsg = errmsg;
+		}
+
+		public Integer getExpires_in() {
+			return expires_in;
+		}
+
+		public void setExpires_in(Integer expires_in) {
+			this.expires_in = expires_in;
+		}
+
+	}
+
+	public static class CorpAccessTokenResp extends GsonPropertyObject {
+
+		// {"":7200,"":"ok","":"1601c97b17893fbfa4218ce2151a0692","":0}
+
+		private Integer errcode;
+		private String access_token;
+		private String errmsg;
+		private Integer expires_in;
+
+		public Integer getErrcode() {
+			return errcode;
+		}
+
+		public void setErrcode(Integer errcode) {
+			this.errcode = errcode;
+		}
+
+		public String getAccess_token() {
+			return access_token;
+		}
+
+		public void setAccess_token(String access_token) {
+			this.access_token = access_token;
+		}
+
+		public String getErrmsg() {
+			return errmsg;
+		}
+
+		public void setErrmsg(String errmsg) {
+			this.errmsg = errmsg;
+		}
+
+		public Integer getExpires_in() {
+			return expires_in;
+		}
+
+		public void setExpires_in(Integer expires_in) {
+			this.expires_in = expires_in;
+		}
+
+	}
+
+	public void setEnable(Boolean enable) {
+		this.enable = enable;
+	}
+
+	public void setCorpId(String corpId) {
+		this.corpId = corpId;
+	}
+
+	public void setCorpAccessTokenAddress(String corpAccessTokenAddress) {
+		this.corpAccessTokenAddress = corpAccessTokenAddress;
+	}
+
+	public void setPersonAttributeNewCountName(String personAttributeNewCountName) {
+		this.personAttributeNewCountName = personAttributeNewCountName;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+	public String getEncodingAesKey() {
+		return encodingAesKey;
+	}
+
+	public void setEncodingAesKey(String encodingAesKey) {
+		this.encodingAesKey = encodingAesKey;
+	}
+
+	public void save() throws Exception {
+		File file = new File(Config.base(), Config.PATH_CONFIG_EXMAIL);
+		FileUtils.write(file, XGsonBuilder.toJson(this), DefaultCharset.charset);
+	}
+
+}

+ 30 - 2
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Message.java

@@ -1,10 +1,11 @@
 package com.x.base.core.project.config;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import com.x.base.core.project.gson.GsonPropertyObject;
-import com.x.base.core.project.tools.ListTools;
 
 public class Message extends GsonPropertyObject {
 
@@ -16,8 +17,26 @@ public class Message extends GsonPropertyObject {
 		this.consumers.addAll(list);
 	}
 
+	public Message(List<String> list, Map<String, String> map) {
+		this.consumers.addAll(list);
+		if(map!=null) {
+			this.consumersV2.putAll(map);
+		}
+	}
+
 	public Message(String... args) {
-		this.consumers.addAll(ListTools.toList(args));
+		if(args!=null){
+			for (String arg : args){
+				this.consumersV2.put(arg,"");
+			}
+		}
+		//this.consumers.addAll(ListTools.toList(args));
+	}
+
+	public Message(Map<String, String> map){
+		if(map!=null) {
+			this.consumersV2.putAll(map);
+		}
 	}
 
 	public static Message defaultInstance() {
@@ -26,6 +45,8 @@ public class Message extends GsonPropertyObject {
 
 	private List<String> consumers = new ArrayList<>();
 
+	private Map<String,String> consumersV2 = new HashMap<>();
+
 	public List<String> getConsumers() {
 		return consumers;
 	}
@@ -34,4 +55,11 @@ public class Message extends GsonPropertyObject {
 		this.consumers = consumers;
 	}
 
+	public Map<String, String> getConsumersV2() {
+		return consumersV2;
+	}
+
+	public void setConsumersV2(Map<String, String> consumersV2) {
+		this.consumersV2 = consumersV2;
+	}
 }

+ 19 - 2
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Messages.java

@@ -1,7 +1,6 @@
 package com.x.base.core.project.config;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.ConcurrentSkipListMap;
 
 import com.x.base.core.project.message.MessageConnector;
@@ -19,6 +18,12 @@ public class Messages extends ConcurrentSkipListMap<String, Message> {
 	public static Messages defaultInstance() throws Exception {
 		Messages o = new Messages();
 
+		/* 示例 */
+		Map<String,String> map = new HashMap<>();
+		map.put(MessageConnector.CONSUME_QIYEWEIXIN, "excute");
+		map.put("describe","excute表示脚本messageRule.js中的方法名称,该js文件需放在与messages.json同目录下,更改脚本需重启服务");
+		o.put("##sample##", new Message(map));
+
 		/* 文件通知 */
 		o.put(MessageConnector.TYPE_ATTACHMENT_SHARE,
 				new Message(MessageConnector.CONSUME_WS, MessageConnector.CONSUME_PMS,
@@ -128,4 +133,16 @@ public class Messages extends ConcurrentSkipListMap<String, Message> {
 		return new ArrayList<String>();
 	}
 
+	public Map<String,String> getConsumersV2(String type) {
+		Message o = this.get(type);
+		Map<String,String> map = new HashMap<>();
+		if (o != null) {
+			/* 这里必须复制内容,在消息处理中会对列表进行删除操作 */
+			if(o.getConsumersV2()!=null){
+				map.putAll(o.getConsumersV2());
+			}
+		}
+		return map;
+	}
+
 }

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 70 - 1
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Qiyeweixin.java


+ 85 - 12
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Query.java

@@ -1,6 +1,8 @@
 package com.x.base.core.project.config;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.BooleanUtils;
@@ -22,11 +24,11 @@ public class Query extends ConfigObject {
 		this.crawlWorkCompleted = new CrawlWorkCompleted();
 		this.crawlWork = new CrawlWork();
 		this.crawlCms = new CrawlCms();
-		this.extractOffice = default_extractOffice;
-		this.extractPdf = default_extractPdf;
-		this.extractText = default_extractText;
-		this.extractImage = default_extractImage;
-		this.tessLanguage = default_tessLanguage;
+		this.extractOffice = DEFAULT_EXTRACTOFFICE;
+		this.extractPdf = DEFAULT_EXTRACTPDF;
+		this.extractText = DEFAULT_EXTRACTTEXT;
+		this.extractImage = DEFAULT_EXTRACTIMAGE;
+		this.tessLanguage = DEFAULT_TESSLANGUAGE;
 	}
 
 	@FieldDescribe("已完成工作收集器设置.")
@@ -53,11 +55,11 @@ public class Query extends ConfigObject {
 	@FieldDescribe("tess使用语言.")
 	private String tessLanguage = "chi_sim";
 
-	public static final Boolean default_extractOffice = true;
-	public static final Boolean default_extractPdf = true;
-	public static final Boolean default_extractText = true;
-	public static final Boolean default_extractImage = false;
-	public static final String default_tessLanguage = "chi_sim";
+	public static final Boolean DEFAULT_EXTRACTOFFICE = true;
+	public static final Boolean DEFAULT_EXTRACTPDF = true;
+	public static final Boolean DEFAULT_EXTRACTTEXT = true;
+	public static final Boolean DEFAULT_EXTRACTIMAGE = false;
+	public static final String DEFAULT_TESSLANGUAGE = "chi_sim";
 
 	public Boolean getExtractOffice() {
 		return BooleanUtils.isTrue(extractOffice);
@@ -76,7 +78,7 @@ public class Query extends ConfigObject {
 	}
 
 	public String getTessLanguage() {
-		return StringUtils.isNotEmpty(this.tessLanguage) ? this.tessLanguage : default_tessLanguage;
+		return StringUtils.isNotEmpty(this.tessLanguage) ? this.tessLanguage : DEFAULT_TESSLANGUAGE;
 	}
 
 	public CrawlCms getCrawlCms() {
@@ -109,6 +111,8 @@ public class Query extends ConfigObject {
 
 		public final static Integer DEFAULT_CONUT = 1000;
 
+		public final static Integer DEFAULT_MAXATTACHMENTSIZE = 1024 * 1024 * 5;
+
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
 
@@ -118,6 +122,15 @@ public class Query extends ConfigObject {
 		@FieldDescribe("每次处理的数量,默认为1000,同时每次将重爬最旧的25%以提高数据质量.")
 		private Integer count = DEFAULT_CONUT;
 
+		@FieldDescribe("忽略附件名称.")
+		private List<String> excludeAttachment = new ArrayList<>();
+
+		@FieldDescribe("忽略附件位置.")
+		private List<String> excludeSite = new ArrayList<>();
+
+		@FieldDescribe("最大附件大小.")
+		private Integer maxAttachmentSize = DEFAULT_MAXATTACHMENTSIZE;
+
 		public String getCron() {
 			if (StringUtils.isNotEmpty(this.cron) && CronExpression.isValidExpression(this.cron)) {
 				return this.cron;
@@ -126,6 +139,18 @@ public class Query extends ConfigObject {
 			}
 		}
 
+		public List<String> getExcludeAttachment() {
+			return excludeAttachment;
+		}
+
+		public List<String> getExcludeSite() {
+			return excludeSite;
+		}
+
+		public Integer getMaxAttachmentSize() {
+			return this.maxAttachmentSize == null ? DEFAULT_MAXATTACHMENTSIZE : this.maxAttachmentSize;
+		}
+
 		public Boolean getEnable() {
 			return BooleanUtils.isTrue(this.enable);
 		}
@@ -145,6 +170,19 @@ public class Query extends ConfigObject {
 		public void setCount(Integer count) {
 			this.count = count;
 		}
+
+		public void setExcludeAttachment(List<String> excludeAttachment) {
+			this.excludeAttachment = excludeAttachment;
+		}
+
+		public void setExcludeSite(List<String> excludeSite) {
+			this.excludeSite = excludeSite;
+		}
+
+		public void setMaxAttachmentSize(Integer maxAttachmentSize) {
+			this.maxAttachmentSize = maxAttachmentSize;
+		}
+
 	}
 
 	public static class CrawlWorkCompleted extends ConfigObject {
@@ -160,6 +198,8 @@ public class Query extends ConfigObject {
 
 		public final static Integer DEFAULT_CONUT = 5000;
 
+		public final static Integer DEFAULT_MAXATTACHMENTSIZE = 1024 * 1024 * 5;
+
 		@FieldDescribe("是否启用")
 		private Boolean enable = DEFAULT_ENABLE;
 
@@ -169,6 +209,15 @@ public class Query extends ConfigObject {
 		@FieldDescribe("每次处理的数量,默认为5000,同时每次将重爬最旧的10%以提高数据质量.")
 		private Integer count = DEFAULT_CONUT;
 
+		@FieldDescribe("忽略附件名称.")
+		private List<String> excludeAttachment = new ArrayList<>();
+
+		@FieldDescribe("忽略附件位置.")
+		private List<String> excludeSite = new ArrayList<>();
+
+		@FieldDescribe("最大附件大小.")
+		private Integer maxAttachmentSize = DEFAULT_MAXATTACHMENTSIZE;
+
 		public String getCron() {
 			if (StringUtils.isNotEmpty(this.cron) && CronExpression.isValidExpression(this.cron)) {
 				return this.cron;
@@ -177,6 +226,18 @@ public class Query extends ConfigObject {
 			}
 		}
 
+		public List<String> getExcludeAttachment() {
+			return excludeAttachment;
+		}
+
+		public Integer getMaxAttachmentSize() {
+			return this.maxAttachmentSize == null ? DEFAULT_MAXATTACHMENTSIZE : this.maxAttachmentSize;
+		}
+
+		public List<String> getExcludeSite() {
+			return excludeSite;
+		}
+
 		public Boolean getEnable() {
 			return BooleanUtils.isTrue(this.enable);
 		}
@@ -196,6 +257,19 @@ public class Query extends ConfigObject {
 		public void setCount(Integer count) {
 			this.count = count;
 		}
+
+		public void setExcludeAttachment(List<String> excludeAttachment) {
+			this.excludeAttachment = excludeAttachment;
+		}
+
+		public void setExcludeSite(List<String> excludeSite) {
+			this.excludeSite = excludeSite;
+		}
+
+		public void setMaxAttachmentSize(Integer maxAttachmentSize) {
+			this.maxAttachmentSize = maxAttachmentSize;
+		}
+
 	}
 
 	public static class CrawlCms extends ConfigObject {
@@ -280,5 +354,4 @@ public class Query extends ConfigObject {
 	public void setTessLanguage(String tessLanguage) {
 		this.tessLanguage = tessLanguage;
 	}
-
 }

+ 23 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/exception/ExceptionAccessDeniedOrEntityNotExist.java

@@ -0,0 +1,23 @@
+package com.x.base.core.project.exception;
+
+import java.util.Objects;
+
+import com.x.base.core.project.http.EffectivePerson;
+
+public class ExceptionAccessDeniedOrEntityNotExist extends PromptException {
+
+	private static final long serialVersionUID = -7354813827434276962L;
+
+	public ExceptionAccessDeniedOrEntityNotExist(String person) {
+		super("用户:{} 权限不足或者对象不存在.", person);
+	}
+
+	public ExceptionAccessDeniedOrEntityNotExist(EffectivePerson effectivePerson) {
+		super("用户:{} 权限不足或者对象不存在.", effectivePerson.getDistinguishedName());
+	}
+
+	public ExceptionAccessDeniedOrEntityNotExist(EffectivePerson effectivePerson, String message) {
+		super("用户:{} 权限不足或者对象不存在, {}.", effectivePerson.getDistinguishedName(), Objects.toString(message, ""));
+	}
+
+}

+ 4 - 3
o2server/x_base_core_project/src/main/java/com/x/base/core/project/http/HttpToken.java

@@ -152,9 +152,10 @@ public class HttpToken {
 		if (StringUtils.isEmpty(token)) {
 			token = request.getHeader(X_Authorization);
 		}
-		if (StringUtils.isEmpty(token)) {
-			token = request.getParameter(X_Token);
-		}
+		// 此代码将导致input被关闭.
+//		if (StringUtils.isEmpty(token)) {
+//			token = request.getParameter(X_Token);
+//		}
 		return token;
 	}
 

+ 1 - 1
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/AbstractActionApplication.java

@@ -22,7 +22,7 @@ public abstract class AbstractActionApplication extends Application {
 		classes.add(LoggerAction.class);
 		classes.add(FireScheduleAction.class);
 		// providers
-		classes.add(WrapInMessageBodyReader.class);
+		classes.add(MessageBodyReaderImpl.class);
 		classes.add(MultiPartFeature.class);
 	}
 

+ 12 - 4
o2server/x_base_core_project/src/main/java/com/x/base/core/project/http/AbstractJsonMessageBodyReader.java → o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/MessageBodyReaderImpl.java

@@ -1,4 +1,4 @@
-package com.x.base.core.project.http;
+package com.x.base.core.project.jaxrs;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -6,14 +6,21 @@ import java.io.InputStreamReader;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
+import javax.ws.rs.Consumes;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
 
+import com.google.gson.Gson;
 import com.x.base.core.project.gson.XGsonBuilder;
 
-public abstract class AbstractJsonMessageBodyReader<T> implements MessageBodyReader<T> {
+@Provider
+@Consumes(MediaType.APPLICATION_JSON)
+public class MessageBodyReaderImpl<T> implements MessageBodyReader<T> {
+
+	private Gson gson = XGsonBuilder.instance();
 
 	@Override
 	public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
@@ -21,11 +28,12 @@ public abstract class AbstractJsonMessageBodyReader<T> implements MessageBodyRea
 	}
 
 	@Override
-	public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream stream)
+	public T readFrom(Class<T> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+			MultivaluedMap<String, String> httpHeaders, InputStream stream)
 			throws IOException, WebApplicationException {
 		try {
 			// UTF-8 only
-			return XGsonBuilder.instance().fromJson(new InputStreamReader(stream, "UTF-8"), type);
+			return gson.fromJson(new InputStreamReader(stream, "UTF-8"), type);
 		} catch (Exception e) {
 			// 此方法在JAXRS方法之前运行,无法捕获违例
 			e.printStackTrace();

+ 0 - 13
o2server/x_base_core_project/src/main/java/com/x/base/core/project/jaxrs/WrapInMessageBodyReader.java

@@ -1,13 +0,0 @@
-package com.x.base.core.project.jaxrs;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.ext.Provider;
-
-import com.x.base.core.project.http.AbstractJsonMessageBodyReader;
-
-@Provider
-@Consumes(MediaType.APPLICATION_JSON)
-public class WrapInMessageBodyReader<T> extends AbstractJsonMessageBodyReader<T> {
-
-}

+ 30 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/message/DingdingMessage.java

@@ -10,6 +10,7 @@ public class DingdingMessage extends GsonPropertyObject {
 	// dept_id_list String 可选 123,456 接收者的部门id列表,最大列表长度:20, 接收者是部门id下(包括子部门下的所有用户)
 	// to_all_user Boolean 可选 false 是否发送给企业全部用户(ISV不能设置true)
 	// msg Json 必须 {"msgtype":"text","text":{"content":"消息内容"}}
+	// msg markdown 消息格式 {"msgtype":"markdown","markdown":{"title":"消息内容", "text":"[这是一个链接](http://o2oa.net)"}}
 	// 消息内容,具体见“消息类型与数据格式”。最长不超过2048个字节。重复消息内容当日只能接收一次。
 
 	private Long agent_id = 0L;
@@ -29,6 +30,7 @@ public class DingdingMessage extends GsonPropertyObject {
 		// }
 		private String msgtype = "text";
 		private Text text = new Text();
+		private Markdown markdown = new Markdown();
 
 		public String getMsgtype() {
 			return msgtype;
@@ -46,6 +48,13 @@ public class DingdingMessage extends GsonPropertyObject {
 			this.text = text;
 		}
 
+		public Markdown getMarkdown() {
+			return markdown;
+		}
+
+		public void setMarkdown(Markdown markdown) {
+			this.markdown = markdown;
+		}
 	}
 
 	public static class Text {
@@ -62,6 +71,27 @@ public class DingdingMessage extends GsonPropertyObject {
 
 	}
 
+	public static class Markdown {
+		private String title = "";//消息头 文字
+		private String text = "";//markdown格式的消息
+
+		public String getTitle() {
+			return title;
+		}
+
+		public void setTitle(String title) {
+			this.title = title;
+		}
+
+		public String getText() {
+			return text;
+		}
+
+		public void setText(String text) {
+			this.text = text;
+		}
+	}
+
 	public Long getAgent_id() {
 		return agent_id;
 	}

+ 6 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/organization/OrganizationDefinition.java

@@ -4,6 +4,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
 
+import org.apache.commons.collections4.list.UnmodifiableList;
 import org.apache.commons.lang3.StringUtils;
 
 import com.x.base.core.project.tools.ListTools;
@@ -90,6 +91,11 @@ public class OrganizationDefinition {
 
 	public final static Pattern distinguishedName_pattern = Pattern.compile("^(.+)\\@(\\S+)\\@(P|PA|G|R|I|U|UA|UD)$");
 
+	public final static List<String> DEFAULTROLES = new UnmodifiableList<String>(ListTools.toList(Manager,
+			AttendanceManager, OrganizationManager, PersonManager, GroupManager, UnitManager, RoleManager,
+			ProcessPlatformManager, ProcessPlatformCreator, MeetingManager, MeetingViewer, PortalManager, BBSManager,
+			CMSManager, OKRManager, CRMManager, QueryManager, MessageManager, HotPictureManager, SearchPrivilege));
+
 	public static String name(String distinguishedName) {
 		if (StringUtils.contains(distinguishedName, "@")) {
 			return StringUtils.substringBefore(distinguishedName, "@");

+ 2 - 1
o2server/x_base_core_project/src/main/java/com/x/base/core/project/tools/BaseTools.java

@@ -130,7 +130,8 @@ public class BaseTools {
 		String base = BaseTools.getBasePath();
 		File file = new File(base, path);
 		if ((!file.exists()) || file.isDirectory()) {
-			throw new Exception("can not get file with path:" + file.getAbsolutePath());
+			//throw new Exception("can not get file with path:" + file.getAbsolutePath());
+			return null;
 		}
 		return FileUtils.readFileToString(file, DefaultCharset.charset);
 	}

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

@@ -11,7 +11,7 @@ import com.x.base.core.project.annotation.ModuleType;
 		"com.x.cms.core.entity.element.QueryView", "com.x.cms.core.entity.element.Script",
 		"com.x.cms.core.entity.element.TemplateForm", "com.x.cms.core.entity.element.View",
 		"com.x.cms.core.entity.element.ViewCategory", "com.x.cms.core.entity.element.ViewFieldConfig",
-		"com.x.cms.core.entity.AppInfo", "com.x.cms.core.entity.CategoryInfo", "com.x.cms.core.entity.CategoryExt",
+		"com.x.cms.core.entity.AppInfo", "com.x.cms.core.entity.AppInfoConfig", "com.x.cms.core.entity.CategoryInfo", "com.x.cms.core.entity.CategoryExt",
 		"com.x.cms.core.entity.Document", "com.x.cms.core.entity.DocumentViewRecord",
 		"com.x.cms.core.entity.element.File", "com.x.cms.core.entity.FileInfo", "com.x.cms.core.entity.Log",
 		"com.x.processplatform.core.entity.content.Attachment", "com.x.query.core.entity.Item",

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

@@ -12,6 +12,7 @@ import com.x.base.core.project.annotation.ModuleType;
 		"com.x.processplatform.core.entity.content.Task", "com.x.processplatform.core.entity.content.TaskCompleted",
 		"com.x.processplatform.core.entity.content.Work", "com.x.processplatform.core.entity.content.WorkCompleted",
 		"com.x.processplatform.core.entity.content.WorkLog", "com.x.processplatform.core.entity.content.KeyLock",
+		"com.x.processplatform.core.entity.content.DocumentVersion",
 		"com.x.processplatform.core.entity.element.Agent", "com.x.processplatform.core.entity.element.Application",
 		"com.x.processplatform.core.entity.element.ApplicationDict",
 		"com.x.processplatform.core.entity.element.ApplicationDictItem",

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

@@ -12,6 +12,7 @@ import com.x.base.core.project.annotation.ModuleType;
 		"com.x.processplatform.core.entity.content.Hint", "com.x.processplatform.core.entity.content.WorkCompleted",
 		"com.x.processplatform.core.entity.content.WorkLog", "com.x.processplatform.core.entity.content.Task",
 		"com.x.processplatform.core.entity.content.Work", "com.x.processplatform.core.entity.content.Read",
+		"com.x.processplatform.core.entity.content.DocumentVersion",
 		"com.x.processplatform.core.entity.content.SerialNumber", "com.x.processplatform.core.entity.element.End",
 		"com.x.processplatform.core.entity.element.Application",
 		"com.x.processplatform.core.entity.element.ApplicationDict",

+ 49 - 45
o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/image/ActionImageBase64.java

@@ -13,6 +13,7 @@ import org.apache.commons.codec.binary.Base64;
 import org.imgscalr.Scalr;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.gson.GsonPropertyObject;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -24,11 +25,12 @@ import com.x.bbs.assemble.control.jaxrs.image.exception.ExceptionWrapInConvert;
 import net.sf.ehcache.Element;
 
 public class ActionImageBase64 extends BaseAction {
-	
-	private static  Logger logger = LoggerFactory.getLogger( ActionImageBase64.class );
+
+	private static Logger logger = LoggerFactory.getLogger(ActionImageBase64.class);
 	private String catchNamePrefix = this.getClass().getName();
-	
-	protected ActionResult<String> execute( HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
+
+	protected ActionResult<String> execute(HttpServletRequest request, EffectivePerson effectivePerson,
+			JsonElement jsonElement) throws Exception {
 		ActionResult<String> result = new ActionResult<>();
 		Wi wrapIn = null;
 		EffectivePerson currentPerson = this.effectivePerson(request);
@@ -36,88 +38,90 @@ public class ActionImageBase64 extends BaseAction {
 		URL url = null;
 		BufferedImage image = null;
 		Boolean check = true;
-		
+
 		try {
-			wrapIn = this.convertToWrapIn( jsonElement, Wi.class );
-		} catch (Exception e ) {
+			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
+		} catch (Exception e) {
 			check = false;
-			Exception exception = new ExceptionWrapInConvert( e, jsonElement );
-			result.error( exception );
-			logger.error( e, currentPerson, request, null);
+			Exception exception = new ExceptionWrapInConvert(e, jsonElement);
+			result.error(exception);
+			logger.error(e, currentPerson, request, null);
 		}
-		
-		if( check ){
-			if( wrapIn.getUrl() != null || wrapIn.getUrl().isEmpty() ){
+
+		if (check) {
+			if (wrapIn.getUrl() != null || wrapIn.getUrl().isEmpty()) {
 				check = false;
 				Exception exception = new ExceptionURLEmpty();
-				result.error( exception );
+				result.error(exception);
 			}
 		}
-		if( check ){
-			if( wrapIn.getSize() != null || wrapIn.getSize() == 0 ){
+		if (check) {
+			if (wrapIn.getSize() != null || wrapIn.getSize() == 0) {
 				wrapIn.setSize(800);
 			}
 		}
-		
+
 		String cacheKey = catchNamePrefix + "#url#" + wrapIn.getUrl() + "#size#" + wrapIn.getSize();
 		Element element = null;
-		element = cache.get( cacheKey );
-		if( element != null ){
+		element = cache.get(cacheKey);
+		if (element != null) {
 			wrap = (String) element.getObjectValue();
-			result.setData( wrap );
-		}else{
-			if( check ){
+			result.setData(wrap);
+		} else {
+			if (check) {
 				try {
-					url = new URL( wrapIn.getUrl() );
-				} catch ( MalformedURLException e ) {
+					url = new URL(wrapIn.getUrl());
+				} catch (MalformedURLException e) {
 					check = false;
-					Exception exception = new ExceptionURLEmpty( e, wrapIn.getUrl() );
-					result.error( exception );
-					logger.error( e, currentPerson, request, null);
+					Exception exception = new ExceptionURLEmpty(e, wrapIn.getUrl());
+					result.error(exception);
+					logger.error(e, currentPerson, request, null);
 				}
 			}
-			if( check ){
+			if (check) {
 				try {
-					image = ImageIO.read( url );
-					if( image == null ){
+					image = ImageIO.read(url);
+					if (image == null) {
 						check = false;
-						result.error( new Exception("system can not read image in url.") );
+						result.error(new Exception("system can not read image in url."));
 					}
 				} catch (IOException e) {
 					check = false;
-					result.error( e );
-					logger.warn( "system read picture with url got an exception!url:" + url );
+					result.error(e);
+					logger.warn("system read picture with url got an exception!url:" + url);
 					logger.error(e);
 				}
 			}
-			if( check ){
+			if (check) {
 				int width = image.getWidth();
 				int height = image.getHeight();
-				if( width * height > wrapIn.getSize() * wrapIn.getSize() ){
-					image = Scalr.resize( image, wrapIn.getSize() );
+				if (width * height > wrapIn.getSize() * wrapIn.getSize()) {
+					image = Scalr.resize(image, wrapIn.getSize());
 				}
 			}
-			if( check ){
+			if (check) {
 				try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
-					ImageIO.write( image, "png", baos );
-					wrap = Base64.encodeBase64String( baos.toByteArray() );
-					cache.put( new Element( cacheKey, wrap ) );
-					result.setData( wrap );
-				} catch ( Exception e ) {
+					ImageIO.write(image, "png", baos);
+					wrap = Base64.encodeBase64String(baos.toByteArray());
+					cache.put(new Element(cacheKey, wrap));
+					result.setData(wrap);
+				} catch (Exception e) {
 					check = false;
-					result.error( e );
-					logger.warn( "system encode picture in base64 got an exception!" );
+					result.error(e);
+					logger.warn("system encode picture in base64 got an exception!");
 					logger.error(e);
 				}
 			}
-		}	
+		}
 		return result;
 	}
 
 	public static class Wi extends GsonPropertyObject {
 
+		@FieldDescribe("地址")
 		private String url;
 
+		@FieldDescribe("像素大小")
 		private Integer size;
 
 		public String getUrl() {

+ 26 - 21
o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/login/ActionLogin.java

@@ -14,6 +14,7 @@ import com.x.bbs.assemble.control.ThisApplication;
 import com.x.bbs.assemble.control.jaxrs.login.exception.ExceptionInsufficientPermissions;
 import com.x.bbs.assemble.control.jaxrs.login.exception.ExceptionUserLogin;
 import com.x.bbs.assemble.control.service.bean.RoleAndPermission;
+
 /**
  * 手机用户访问论坛信息,首页所有的信息整合在一起 匿名用户可以访问
  * 
@@ -22,18 +23,19 @@ import com.x.bbs.assemble.control.service.bean.RoleAndPermission;
  */
 public class ActionLogin extends BaseAction {
 
-	private static  Logger logger = LoggerFactory.getLogger(ActionLogin.class);
-	
-	public ActionResult<RoleAndPermission> execute( @Context HttpServletRequest request, EffectivePerson effectivePerson ) {
-		
+	private static Logger logger = LoggerFactory.getLogger(ActionLogin.class);
+
+	public ActionResult<RoleAndPermission> execute(@Context HttpServletRequest request,
+			EffectivePerson effectivePerson) {
+
 		ActionResult<RoleAndPermission> result = new ActionResult<>();
 		Boolean isBBSManager = false;
 		String hostIp = request.getRemoteAddr();
 		String hostName = request.getRemoteAddr();
 		Boolean check = true;
-		
-		if( check ){
-			if ("anonymous".equalsIgnoreCase( effectivePerson.getTokenType().name())) {
+
+		if (check) {
+			if ("anonymous".equalsIgnoreCase(effectivePerson.getTokenType().name())) {
 				try {
 					operationRecordService.loginOperation("anonymous", hostIp, hostName);
 					result.setData(new RoleAndPermission());
@@ -45,32 +47,35 @@ public class ActionLogin extends BaseAction {
 			} else {
 				RoleAndPermission roleAndPermission = null;
 				try {
-					operationRecordService.loginOperation( effectivePerson.getDistinguishedName(), hostIp, hostName);
-					roleAndPermission = userPermissionService.getUserRoleAndPermissionForLogin( effectivePerson.getDistinguishedName());
+					operationRecordService.loginOperation(effectivePerson.getDistinguishedName(), hostIp, hostName);
+					roleAndPermission = userPermissionService
+							.getUserRoleAndPermissionForLogin(effectivePerson.getDistinguishedName());
 				} catch (Exception e) {
-					Exception exception = new ExceptionUserLogin( e, effectivePerson.getDistinguishedName());
+					Exception exception = new ExceptionUserLogin(e, effectivePerson.getDistinguishedName());
 					result.error(exception);
 					logger.error(e, effectivePerson, request, null);
 				}
 				try {
-					isBBSManager = userManagerService.isHasPlatformRole( effectivePerson.getDistinguishedName(), ThisApplication.BBSMANAGER );
+					isBBSManager = userManagerService.isHasPlatformRole(effectivePerson.getDistinguishedName(),
+							ThisApplication.BBSMANAGER);
 				} catch (Exception e) {
-					Exception exception = new ExceptionInsufficientPermissions( effectivePerson.getDistinguishedName(), ThisApplication.BBSMANAGER );
+					Exception exception = new ExceptionInsufficientPermissions(effectivePerson.getDistinguishedName(),
+							ThisApplication.BBSMANAGER);
 					result.error(exception);
-					logger.error( e, effectivePerson, request, null );
+					logger.error(e, effectivePerson, request, null);
 				}
-				if ( roleAndPermission != null ) {
-					roleAndPermission.setIsBBSManager( isBBSManager );
+				if (roleAndPermission != null) {
+					roleAndPermission.setIsBBSManager(isBBSManager);
 				}
-				result.setData( roleAndPermission );
+				result.setData(roleAndPermission);
 			}
 		}
 		return result;
 	}
 
-	public static class Wi extends GsonPropertyObject implements Serializable{
-		
-		private static final long serialVersionUID = -5076990764713538973L;
-		
-	}
+//	public static class Wi extends GsonPropertyObject implements Serializable {
+//
+//		private static final long serialVersionUID = -5076990764713538973L;
+//
+//	}
 }

+ 26 - 23
o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/replyinfo/ActionListMyReplyForPages.java

@@ -23,9 +23,10 @@ import com.x.bbs.entity.BBSReplyInfo;
 
 public class ActionListMyReplyForPages extends BaseAction {
 
-	private static  Logger logger = LoggerFactory.getLogger(ActionListMyReplyForPages.class);
+	private static Logger logger = LoggerFactory.getLogger(ActionListMyReplyForPages.class);
 
-	protected ActionResult<List<Wo>> execute(HttpServletRequest request, EffectivePerson effectivePerson, Integer page, Integer count) throws Exception {
+	protected ActionResult<List<Wo>> execute(HttpServletRequest request, EffectivePerson effectivePerson, Integer page,
+			Integer count) throws Exception {
 		ActionResult<List<Wo>> result = new ActionResult<>();
 		List<Wo> wraps = new ArrayList<>();
 		List<BBSReplyInfo> replyInfoList = null;
@@ -86,7 +87,7 @@ public class ActionListMyReplyForPages extends BaseAction {
 					replyInfoList_out.add(replyInfoList.get(i));
 				}
 			}
-			if ( ListTools.isNotEmpty( replyInfoList_out )) {
+			if (ListTools.isNotEmpty(replyInfoList_out)) {
 				try {
 					wraps = Wo.copier.copy(replyInfoList_out);
 				} catch (Exception e) {
@@ -98,13 +99,13 @@ public class ActionListMyReplyForPages extends BaseAction {
 			}
 		}
 		if (check) {
-			if( ListTools.isNotEmpty( wraps ) ) {
-				for( Wo wo : wraps ) {
-					if( StringUtils.isNotEmpty( wo.getCreatorName() ) ) {
-						wo.setCreatorNameShort( wo.getCreatorName().split( "@" )[0]);
+			if (ListTools.isNotEmpty(wraps)) {
+				for (Wo wo : wraps) {
+					if (StringUtils.isNotEmpty(wo.getCreatorName())) {
+						wo.setCreatorNameShort(wo.getCreatorName().split("@")[0]);
 					}
-					if( StringUtils.isNotEmpty( wo.getAuditorName() ) ) {
-						wo.setAuditorNameShort( wo.getAuditorName().split( "@" )[0]);
+					if (StringUtils.isNotEmpty(wo.getAuditorName())) {
+						wo.setAuditorNameShort(wo.getAuditorName().split("@")[0]);
 					}
 				}
 			}
@@ -113,19 +114,20 @@ public class ActionListMyReplyForPages extends BaseAction {
 		result.setCount(total);
 		return result;
 	}
-	
-	public static class Wo extends BBSReplyInfo{
-		
+
+	public static class Wo extends BBSReplyInfo {
+
 		private static final long serialVersionUID = -5076990764713538973L;
-		
+
 		public static List<String> Excludes = new ArrayList<String>();
-		
-		public static WrapCopier< BBSReplyInfo, Wo > copier = WrapCopierFactory.wo( BBSReplyInfo.class, Wo.class, null, JpaObject.FieldsInvisible);
-		
-		@FieldDescribe( "创建人姓名" )
+
+		public static WrapCopier<BBSReplyInfo, Wo> copier = WrapCopierFactory.wo(BBSReplyInfo.class, Wo.class, null,
+				JpaObject.FieldsInvisible);
+
+		@FieldDescribe("创建人姓名")
 		private String creatorNameShort = "";
-		
-		@FieldDescribe( "审核人姓名" )
+
+		@FieldDescribe("审核人姓名")
 		private String auditorNameShort = "";
 
 		public String getCreatorNameShort() {
@@ -144,12 +146,13 @@ public class ActionListMyReplyForPages extends BaseAction {
 			this.auditorNameShort = auditorNameShort;
 		}
 	}
-	
-	public static class Wi{
 
+	public static class Wi {
+
+		@FieldDescribe("主题Id")
 		private String subjectId = null;
-		
-		public static List<String> Excludes = new ArrayList<String>( JpaObject.FieldsUnmodify );
+
+		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
 
 		public String getSubjectId() {
 			return subjectId;

+ 81 - 71
o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/replyinfo/ActionListWithSubjectForPage.java

@@ -25,146 +25,156 @@ import com.x.bbs.entity.BBSReplyInfo;
 import net.sf.ehcache.Element;
 
 public class ActionListWithSubjectForPage extends BaseAction {
-	
-	private static  Logger logger = LoggerFactory.getLogger( ActionListWithSubjectForPage.class );
-	
+
+	private static Logger logger = LoggerFactory.getLogger(ActionListWithSubjectForPage.class);
+
 	@SuppressWarnings("unchecked")
-	protected ActionResult<List<Wo>> execute( HttpServletRequest request, EffectivePerson effectivePerson, Integer page, Integer count, JsonElement jsonElement ) throws Exception {
+	protected ActionResult<List<Wo>> execute(HttpServletRequest request, EffectivePerson effectivePerson, Integer page,
+			Integer count, JsonElement jsonElement) throws Exception {
 		ActionResult<List<Wo>> result = new ActionResult<>();
 		Wi wrapIn = null;
 		Boolean check = true;
-		
+
 		try {
-			wrapIn = this.convertToWrapIn( jsonElement, Wi.class );
-		} catch (Exception e ) {
+			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
+		} catch (Exception e) {
 			check = false;
-			Exception exception = new ExceptionReplyInfoProcess( e, "系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString() );
-			result.error( exception );
-			logger.error( e, effectivePerson, request, null);
+			Exception exception = new ExceptionReplyInfoProcess(e,
+					"系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString());
+			result.error(exception);
+			logger.error(e, effectivePerson, request, null);
 		}
-		
-		if( check ) {
+
+		if (check) {
 			String cacheKey = wrapIn.getSubjectId() + "#" + page + "#" + count;
-			Element element = cache.get( cacheKey );
-			
+			Element element = cache.get(cacheKey);
+
 			if ((null != element) && (null != element.getObjectValue())) {
 				ActionResult<List<Wo>> result_cache = (ActionResult<List<Wo>>) element.getObjectValue();
-				result.setData( result_cache.getData() );
-				result.setCount( result_cache.getCount() );
+				result.setData(result_cache.getData());
+				result.setCount(result_cache.getCount());
 			} else {
 				result = getReplyQueryResult(wrapIn, request, effectivePerson, page, count);
-				cache.put(new Element(cacheKey, result ));
+				cache.put(new Element(cacheKey, result));
 			}
 		}
 		return result;
 	}
 
-	public ActionResult<List<Wo>> getReplyQueryResult( Wi wrapIn, HttpServletRequest request, EffectivePerson effectivePerson, Integer page, Integer count ) {
+	public ActionResult<List<Wo>> getReplyQueryResult(Wi wrapIn, HttpServletRequest request,
+			EffectivePerson effectivePerson, Integer page, Integer count) {
 		ActionResult<List<Wo>> result = new ActionResult<>();
 		List<Wo> wraps = new ArrayList<>();
 		List<BBSReplyInfo> replyInfoList = null;
 		List<BBSReplyInfo> replyInfoList_out = new ArrayList<BBSReplyInfo>();
 		Long total = 0L;
 		Boolean check = true;
-		
-		if( check ){
-			if( page == null ){
+
+		if (check) {
+			if (page == null) {
 				check = false;
 				Exception exception = new ExceptionPageEmpty();
-				result.error( exception );
+				result.error(exception);
 			}
 		}
-		if( check ){
-			if( count == null ){
+		if (check) {
+			if (count == null) {
 				check = false;
 				Exception exception = new ExceptionCountEmpty();
-				result.error( exception );
+				result.error(exception);
 			}
 		}
-		if( check ){
-			try{
-				total = replyInfoService.countWithSubjectForPage( wrapIn.getSubjectId() );
+		if (check) {
+			try {
+				total = replyInfoService.countWithSubjectForPage(wrapIn.getSubjectId());
 			} catch (Exception e) {
 				check = false;
-				Exception exception = new ExceptionReplyInfoProcess( e, "根据主题ID查询主题内所有的回复数量时发生异常。Subject:" + wrapIn.getSubjectId() );
-				result.error( exception );
-				logger.error( e, effectivePerson, request, null);
+				Exception exception = new ExceptionReplyInfoProcess(e,
+						"根据主题ID查询主题内所有的回复数量时发生异常。Subject:" + wrapIn.getSubjectId());
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
 			}
 		}
-		if( check ){
-			if( total > 0 ){
-				try{
-					replyInfoList = replyInfoService.listWithSubjectForPage( wrapIn.getSubjectId(), page * count );
+		if (check) {
+			if (total > 0) {
+				try {
+					replyInfoList = replyInfoService.listWithSubjectForPage(wrapIn.getSubjectId(), page * count);
 				} catch (Exception e) {
 					check = false;
-					Exception exception = new ExceptionReplyInfoProcess( e, "根据主题ID查询主题内所有的回复列表时发生异常。Subject:" + wrapIn.getSubjectId() );
-					result.error( exception );
-					logger.error( e, effectivePerson, request, null);
+					Exception exception = new ExceptionReplyInfoProcess(e,
+							"根据主题ID查询主题内所有的回复列表时发生异常。Subject:" + wrapIn.getSubjectId());
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
 				}
 			}
 		}
-		if( check ){
-			if( page <= 0 ){
+		if (check) {
+			if (page <= 0) {
 				page = 1;
 			}
-			if( count <= 0 ){
+			if (count <= 0) {
 				count = 20;
 			}
-			int startIndex = ( page - 1 ) * count;
+			int startIndex = (page - 1) * count;
 			int endIndex = page * count;
-			for( int i=0; replyInfoList != null && i< replyInfoList.size(); i++ ){
-				if( i < replyInfoList.size() && i >= startIndex && i < endIndex ){
-					replyInfoList_out.add( replyInfoList.get( i ) );
+			for (int i = 0; replyInfoList != null && i < replyInfoList.size(); i++) {
+				if (i < replyInfoList.size() && i >= startIndex && i < endIndex) {
+					replyInfoList_out.add(replyInfoList.get(i));
 				}
 			}
-			if( ListTools.isNotEmpty( replyInfoList_out ) ){
+			if (ListTools.isNotEmpty(replyInfoList_out)) {
 				try {
-					wraps = Wo.copier.copy( replyInfoList_out );
+					wraps = Wo.copier.copy(replyInfoList_out);
 				} catch (Exception e) {
 					check = false;
-					Exception exception = new ExceptionReplyInfoProcess( e, "将查询结果转换成可以输出的数据信息时发生异常。" );
-					result.error( exception );
-					logger.error( e, effectivePerson, request, null);
+					Exception exception = new ExceptionReplyInfoProcess(e, "将查询结果转换成可以输出的数据信息时发生异常。");
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
 				}
 			}
 		}
 		if (check) {
-			if( ListTools.isNotEmpty( wraps ) ) {
-				for( Wo wo : wraps ) {
-					if( StringUtils.isNotEmpty( wo.getCreatorName() ) ) {
-						wo.setCreatorNameShort( wo.getCreatorName().split( "@" )[0]);
+			if (ListTools.isNotEmpty(wraps)) {
+				for (Wo wo : wraps) {
+					if (StringUtils.isNotEmpty(wo.getCreatorName())) {
+						wo.setCreatorNameShort(wo.getCreatorName().split("@")[0]);
 					}
-					if( StringUtils.isNotEmpty( wo.getAuditorName() ) ) {
-						wo.setAuditorNameShort( wo.getAuditorName().split( "@" )[0]);
+					if (StringUtils.isNotEmpty(wo.getAuditorName())) {
+						wo.setAuditorNameShort(wo.getAuditorName().split("@")[0]);
 					}
 				}
 			}
 		}
-		result.setData( wraps );
-		result.setCount( total );
+		result.setData(wraps);
+		result.setCount(total);
 		return result;
 	}
-	
-	public static class Wi{
-		private String subjectId = null;		
-		public static List<String> Excludes = new ArrayList<String>( JpaObject.FieldsUnmodify );
+
+	public static class Wi {
+
+		@FieldDescribe("主题Id")
+		private String subjectId = null;
+		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
+
 		public String getSubjectId() {
 			return subjectId;
 		}
+
 		public void setSubjectId(String subjectId) {
 			this.subjectId = subjectId;
 		}
 	}
-	
-	public static class Wo extends BBSReplyInfo{		
-		private static final long serialVersionUID = -5076990764713538973L;		
-		public static List<String> Excludes = new ArrayList<String>();		
-		public static WrapCopier< BBSReplyInfo, Wo > copier = WrapCopierFactory.wo( BBSReplyInfo.class, Wo.class, null, JpaObject.FieldsInvisible);		
-		
-		@FieldDescribe( "创建人姓名" )
+
+	public static class Wo extends BBSReplyInfo {
+		private static final long serialVersionUID = -5076990764713538973L;
+		public static List<String> Excludes = new ArrayList<String>();
+		public static WrapCopier<BBSReplyInfo, Wo> copier = WrapCopierFactory.wo(BBSReplyInfo.class, Wo.class, null,
+				JpaObject.FieldsInvisible);
+
+		@FieldDescribe("创建人姓名")
 		private String creatorNameShort = "";
-		
-		@FieldDescribe( "审核人姓名" )
+
+		@FieldDescribe("审核人姓名")
 		private String auditorNameShort = "";
 
 		public String getCreatorNameShort() {

+ 64 - 49
o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/jaxrs/roleinfo/ActionBindRoleToUser.java

@@ -6,6 +6,7 @@ import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 
 import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.WrapOutBoolean;
@@ -20,32 +21,35 @@ import com.x.bbs.assemble.control.jaxrs.roleinfo.exception.ExceptionRoleInfoProc
 import com.x.bbs.assemble.control.jaxrs.roleinfo.exception.ExceptionUnitNotExists;
 
 public class ActionBindRoleToUser extends BaseAction {
-	
-	private static  Logger logger = LoggerFactory.getLogger( ActionBindRoleToUser.class );
-	
-	protected ActionResult<WrapOutBoolean> execute( HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
+
+	private static Logger logger = LoggerFactory.getLogger(ActionBindRoleToUser.class);
+
+	protected ActionResult<WrapOutBoolean> execute(HttpServletRequest request, EffectivePerson effectivePerson,
+			JsonElement jsonElement) throws Exception {
 		ActionResult<WrapOutBoolean> result = new ActionResult<>();
 		WrapOutBoolean wrap = new WrapOutBoolean();
 		BindObject bindObject = null;
 		String object = null;
-		wrap.setValue( false );
+		wrap.setValue(false);
 		Wi wrapIn = null;
 		Boolean check = true;
-		
+
 		try {
-			wrapIn = this.convertToWrapIn( jsonElement, Wi.class );
-		} catch (Exception e ) {
+			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
+		} catch (Exception e) {
 			check = false;
-			Exception exception = new ExceptionRoleInfoProcess( e, "系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString() );
-			result.error( exception );
-			logger.error( e, effectivePerson, request, null);
+			Exception exception = new ExceptionRoleInfoProcess(e,
+					"系统在将JSON信息转换为对象时发生异常。JSON:" + jsonElement.toString());
+			result.error(exception);
+			logger.error(e, effectivePerson, request, null);
 		}
-		
+
 		if (check) {
-			if (wrapIn.getBindObject() == null || wrapIn.getBindObject().getObjectName() == null || wrapIn.getBindObject().getObjectName().isEmpty()) {
+			if (wrapIn.getBindObject() == null || wrapIn.getBindObject().getObjectName() == null
+					|| wrapIn.getBindObject().getObjectName().isEmpty()) {
 				check = false;
 				Exception exception = new ExceptionBindObjectNameEmpty();
-				result.error( exception );
+				result.error(exception);
 			} else {
 				bindObject = wrapIn.getBindObject();
 			}
@@ -57,64 +61,67 @@ public class ActionBindRoleToUser extends BaseAction {
 					object = userManagerService.getPersonNameByFlag(bindObject.getObjectName());
 					if (object == null) {
 						check = false;
-						Exception exception = new ExceptionPersonNotExists( bindObject.getObjectName() );
-						result.error( exception );
+						Exception exception = new ExceptionPersonNotExists(bindObject.getObjectName());
+						result.error(exception);
 					}
 				} catch (Exception e) {
 					check = false;
-					Exception exception = new ExceptionRoleInfoProcess( e, "人员信息查询时发生异常!Person:" + bindObject.getObjectName() );
-					result.error( exception );
-					logger.error( e, effectivePerson, request, null);
+					Exception exception = new ExceptionRoleInfoProcess(e,
+							"人员信息查询时发生异常!Person:" + bindObject.getObjectName());
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
 				}
 			} else if ("组织".equals(bindObject.getObjectType())) {
 				try {
-					object = userManagerService.checkUnitExistsWithFlag( bindObject.getObjectName() );
+					object = userManagerService.checkUnitExistsWithFlag(bindObject.getObjectName());
 					if (object == null) {
 						check = false;
-						Exception exception = new ExceptionUnitNotExists( bindObject.getObjectName() );
-						result.error( exception );
+						Exception exception = new ExceptionUnitNotExists(bindObject.getObjectName());
+						result.error(exception);
 					}
 				} catch (Exception e) {
 					check = false;
-					Exception exception = new ExceptionRoleInfoProcess( e, "组织信息查询时发生异常!Unit:" + bindObject.getObjectName() );
-					result.error( exception );
-					logger.error( e, effectivePerson, request, null);
+					Exception exception = new ExceptionRoleInfoProcess(e,
+							"组织信息查询时发生异常!Unit:" + bindObject.getObjectName());
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
 				}
 			} else if ("群组".equals(bindObject.getObjectType())) {
 				try {
 					object = userManagerService.checkGroupExsitsWithName(bindObject.getObjectName());
 					if (object == null) {
 						check = false;
-						Exception exception = new ExceptionGroupNotExists( bindObject.getObjectName() );
-						result.error( exception );
+						Exception exception = new ExceptionGroupNotExists(bindObject.getObjectName());
+						result.error(exception);
 					}
 				} catch (Exception e) {
 					check = false;
-					Exception exception = new ExceptionRoleInfoProcess( e, "群组信息查询时发生异常!Group:" + bindObject.getObjectName() );
-					result.error( exception );
-					logger.error( e, effectivePerson, request, null);
+					Exception exception = new ExceptionRoleInfoProcess(e,
+							"群组信息查询时发生异常!Group:" + bindObject.getObjectName());
+					result.error(exception);
+					logger.error(e, effectivePerson, request, null);
 				}
 			} else {
 				check = false;
-				Exception exception = new ExceptionBindObjectTypeInvalid( bindObject.getObjectType() );
-				result.error( exception );
+				Exception exception = new ExceptionBindObjectTypeInvalid(bindObject.getObjectType());
+				result.error(exception);
 			}
 		}
 		if (check) {
 			try {
 				roleInfoService.bindRoleToUser(wrapIn.getBindObject(), wrapIn.getBindRoleCodes());
-				wrap.setValue( true );
-				result.setData( wrap );
+				wrap.setValue(true);
+				result.setData(wrap);
 			} catch (Exception e) {
 				check = false;
-				Exception exception = new ExceptionRoleInfoProcess( e, "系统在根据人员姓名以及角色编码列表进行角色绑定时发生异常." );
-				result.error( exception );
-				logger.error( e, effectivePerson, request, null);
+				Exception exception = new ExceptionRoleInfoProcess(e, "系统在根据人员姓名以及角色编码列表进行角色绑定时发生异常.");
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
 			}
 		}
 		if (check) {
 			try {
-				checkUserPermission( wrapIn.getBindObject() );
+				checkUserPermission(wrapIn.getBindObject());
 			} catch (Exception e) {
 				logger.warn("system check user permission got an exception!");
 				logger.error(e);
@@ -122,25 +129,33 @@ public class ActionBindRoleToUser extends BaseAction {
 		}
 		return result;
 	}
-	
-	public static class Wi{
-		
+
+	public static class Wi {
+
 		public static List<String> Excludes = new ArrayList<String>();
-		
+
+		@FieldDescribe("组织名称")
 		private String unitName = null;
-		
+
+		@FieldDescribe("人员名称")
 		private String userName = null;
-		
+
+		@FieldDescribe("论坛Id")
 		private String forumId = null;
-		
+
+		@FieldDescribe("区段Id")
 		private String sectionId = null;
-		
+
+		@FieldDescribe("绑定角色")
 		private String bindRoleCode = null;
-		
+
+		@FieldDescribe("绑定对象")
 		private BindObject bindObject = null;
-		
+
+		@FieldDescribe("绑定角色列表")
 		private List<String> bindRoleCodes = null;
-		
+
+		@FieldDescribe("绑定对象列表")
 		private List<BindObject> bindObjectArray = null;
 
 		public String getUnitName() {

+ 8 - 4
o2server/x_calendar_core_entity/src/main/java/com/x/calendar/core/entity/Calendar_EventComment.java

@@ -38,7 +38,7 @@ public class Calendar_EventComment extends SliceJpaObject {
 
 	@FieldDescribe("数据库主键,自动生成.")
 	@Id
-	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME )
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
 	private String id = createId();
 
 	public void onPersist() throws Exception {
@@ -61,7 +61,7 @@ public class Calendar_EventComment extends SliceJpaObject {
 	@Lob
 	@Basic(fetch = FetchType.EAGER)
 	@FieldDescribe("COMMENT信息的LOB值")
-	@Column(name = "xlobValue", length = JpaObject.length_10M)
+	@Column(name = lobValue_FIELDNAME, length = JpaObject.length_10M)
 	private String lobValue = "";
 
 	public static final String checkTime_FIELDNAME = "checkTime";
@@ -71,9 +71,13 @@ public class Calendar_EventComment extends SliceJpaObject {
 	@CheckPersist(allowEmpty = true)
 	private Date checkTime = null;
 
-	public Date getCheckTime() { return checkTime; }
+	public Date getCheckTime() {
+		return checkTime;
+	}
 
-	public void setCheckTime(Date checkTime) { this.checkTime = checkTime; }
+	public void setCheckTime(Date checkTime) {
+		this.checkTime = checkTime;
+	}
 
 	public String getLobValue() {
 		return lobValue;

+ 13 - 31
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/Business.java

@@ -1,43 +1,17 @@
 package com.x.cms.assemble.control;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang3.StringUtils;
-
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.organization.OrganizationDefinition;
 import com.x.base.core.project.tools.ListTools;
-import com.x.cms.assemble.control.factory.AppDictFactory;
-import com.x.cms.assemble.control.factory.AppDictItemFactory;
-import com.x.cms.assemble.control.factory.AppInfoFactory;
-import com.x.cms.assemble.control.factory.CategoryExtFactory;
-import com.x.cms.assemble.control.factory.CategoryInfoFactory;
-import com.x.cms.assemble.control.factory.CmsBatchOperationFactory;
-import com.x.cms.assemble.control.factory.DocumentCommendFactory;
-import com.x.cms.assemble.control.factory.DocumentCommentCommendFactory;
-import com.x.cms.assemble.control.factory.DocumentCommentInfoFactory;
-import com.x.cms.assemble.control.factory.DocumentFactory;
-import com.x.cms.assemble.control.factory.DocumentViewRecordFactory;
-import com.x.cms.assemble.control.factory.FileFactory;
-import com.x.cms.assemble.control.factory.FileInfoFactory;
-import com.x.cms.assemble.control.factory.FormFactory;
-import com.x.cms.assemble.control.factory.FormFieldFactory;
-import com.x.cms.assemble.control.factory.ItemFactory;
-import com.x.cms.assemble.control.factory.LogFactory;
-import com.x.cms.assemble.control.factory.ReviewFactory;
-import com.x.cms.assemble.control.factory.ScriptFactory;
-import com.x.cms.assemble.control.factory.SearchFactory;
-import com.x.cms.assemble.control.factory.TemplateFormFactory;
-import com.x.cms.assemble.control.factory.ViewCategoryFactory;
-import com.x.cms.assemble.control.factory.ViewFactory;
-import com.x.cms.assemble.control.factory.ViewFieldConfigFactory;
+import com.x.cms.assemble.control.factory.*;
 import com.x.cms.assemble.control.factory.element.QueryViewFactory;
 import com.x.cms.core.entity.AppInfo;
 import com.x.organization.core.express.Organization;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.List;
 
 public class Business {
 
@@ -53,6 +27,7 @@ public class Business {
 
 	private TemplateFormFactory templateFormFactory;
 	private AppInfoFactory appInfoFactory;
+	private AppInfoConfigFactory appInfoConfigFactory;
 	private CategoryInfoFactory categoryInfoFactory;
 	private CategoryExtFactory categoryExtFactory;
 	private FileInfoFactory fileInfoFactory;
@@ -78,6 +53,13 @@ public class Business {
 	private DocumentCommentInfoFactory documentCommentInfoFactory;
 	private ReviewFactory reviewFactory;
 
+	public AppInfoConfigFactory appInfoConfigFactory() throws Exception {
+		if (null == this.appInfoConfigFactory) {
+			this.appInfoConfigFactory = new AppInfoConfigFactory(this);
+		}
+		return appInfoConfigFactory;
+	}
+
 	public DocumentCommentCommendFactory documentCommentCommendFactory() throws Exception {
 		if (null == this.documentCommentCommendFactory) {
 			this.documentCommentCommendFactory = new DocumentCommentCommendFactory(this);

+ 29 - 0
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/factory/AppInfoConfigFactory.java

@@ -0,0 +1,29 @@
+package com.x.cms.assemble.control.factory;
+
+import com.x.cms.assemble.control.AbstractFactory;
+import com.x.cms.assemble.control.Business;
+import com.x.cms.core.entity.AppInfoConfig;
+
+/**
+ * 栏目配置支持信息基础功能服务类
+ * 
+ * @author O2LEE
+ */
+public class AppInfoConfigFactory extends AbstractFactory {
+
+	public AppInfoConfigFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	public AppInfoConfig get( String id ) throws Exception {
+		return this.entityManagerContainer().find( id, AppInfoConfig.class );
+	}
+	
+	public String getContent( String id ) throws Exception {
+		AppInfoConfig AppInfoConfig = this.entityManagerContainer().find( id, AppInfoConfig.class );
+		if( AppInfoConfig != null ) {
+			return AppInfoConfig.getConfig();
+		}
+		return null;
+	}
+}

+ 5 - 4
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/ActionApplication.java

@@ -1,15 +1,12 @@
 package com.x.cms.assemble.control.jaxrs;
 
-import java.util.Set;
-
-import javax.ws.rs.ApplicationPath;
-
 import com.x.base.core.project.jaxrs.AbstractActionApplication;
 import com.x.cms.assemble.control.jaxrs.appdict.AppDictAction;
 import com.x.cms.assemble.control.jaxrs.appdict.AppDictAnonymousAction;
 import com.x.cms.assemble.control.jaxrs.appdictdesign.AppDictDesignAction;
 import com.x.cms.assemble.control.jaxrs.appinfo.AppInfoAction;
 import com.x.cms.assemble.control.jaxrs.appinfo.AppInfoAnonymousAction;
+import com.x.cms.assemble.control.jaxrs.appinfo.AppInfoConfigAction;
 import com.x.cms.assemble.control.jaxrs.categoryinfo.CategoryInfoAction;
 import com.x.cms.assemble.control.jaxrs.categoryinfo.CategoryInfoAnonymousAction;
 import com.x.cms.assemble.control.jaxrs.comment.DocumentCommentInfoAction;
@@ -40,6 +37,9 @@ import com.x.cms.assemble.control.jaxrs.view.ViewAction;
 import com.x.cms.assemble.control.jaxrs.viewcategory.ViewCategoryAction;
 import com.x.cms.assemble.control.jaxrs.viewfieldconfig.ViewFieldConfigAction;
 
+import javax.ws.rs.ApplicationPath;
+import java.util.Set;
+
 @ApplicationPath("jaxrs")
 public class ActionApplication extends AbstractActionApplication {
 
@@ -47,6 +47,7 @@ public class ActionApplication extends AbstractActionApplication {
 		
 		this.classes.add(TemplateFormAction.class);
 		this.classes.add(AppInfoAction.class);
+		this.classes.add(AppInfoConfigAction.class);
 		this.classes.add(CategoryInfoAction.class);
 		this.classes.add(DataAction.class);
 		this.classes.add(DocumentAction.class);

+ 3 - 2
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/CmsJaxrsFilter.java

@@ -1,9 +1,9 @@
 package com.x.cms.assemble.control.jaxrs;
 
-import javax.servlet.annotation.WebFilter;
-
 import com.x.base.core.project.jaxrs.ManagerUserJaxrsFilter;
 
+import javax.servlet.annotation.WebFilter;
+
 /**
  * web服务过滤器,将指定的URL定义为需要用户认证的服务,如果用户未登录,则无法访问该服务
  *
@@ -13,6 +13,7 @@ import com.x.base.core.project.jaxrs.ManagerUserJaxrsFilter;
         "/jaxrs/appcategoryadmin/*",
         "/jaxrs/appcategorypermission/*",
         "/jaxrs/appinfo/*",
+        "/jaxrs/appconfig/*",
         "/jaxrs/categoryinfo/*",
         "/jaxrs/data/*",
         "/jaxrs/document/*",

+ 22 - 5
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionGet.java

@@ -1,17 +1,16 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang3.StringUtils;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.cms.core.entity.AppInfo;
-
+import com.x.cms.core.entity.AppInfoConfig;
 import net.sf.ehcache.Element;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
 
 public class ActionGet extends BaseAction {
 
@@ -21,6 +20,7 @@ public class ActionGet extends BaseAction {
 		ActionResult<Wo> result = new ActionResult<>();
 		Wo wo = null;
 		AppInfo appInfo = null;
+		AppInfoConfig appInfoConfig = null;
 		Boolean check = true;
 		
 		if( StringUtils.isEmpty(flag) ){
@@ -51,9 +51,26 @@ public class ActionGet extends BaseAction {
 					logger.error( e, effectivePerson, request, null);
 				}
 			}
+			if( check ){
+				try {
+					appInfoConfig = appInfoServiceAdv.getConfigObject( appInfo.getId() );
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new ExceptionAppInfoProcess( e, "根据指定flag查询应用栏目信息对象时发生异常。flag:" + flag );
+					result.error( exception );
+					logger.error( e, effectivePerson, request, null);
+				}
+			}
 			if( check ){
 				try {
 					wo = Wo.copier.copy( appInfo );
+
+					if( appInfoConfig != null ){
+						wo.setConfig( appInfoConfig.getConfig() );
+					}else{
+						wo.setConfig( "{}" );
+					}
+
 					cache.put(new Element( cacheKey, wo ));
 					result.setData( wo );
 				} catch (Exception e) {

+ 61 - 0
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionGetConfig.java

@@ -0,0 +1,61 @@
+package com.x.cms.assemble.control.jaxrs.appinfo;
+
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoText;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.cms.core.entity.AppInfoConfig;
+import net.sf.ehcache.Element;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class ActionGetConfig extends BaseAction {
+
+	private static  Logger logger = LoggerFactory.getLogger( ActionGetConfig.class );
+	
+	protected ActionResult<WoText> execute(HttpServletRequest request, EffectivePerson effectivePerson, String id ) throws Exception {
+		ActionResult<WoText> result = new ActionResult<>();
+		WoText woText = new WoText();
+		AppInfoConfig appInfoConfig = null;
+		Boolean check = true;
+		
+		if( StringUtils.isEmpty(id) ){
+			check = false;
+			Exception exception = new ExceptionAppInfoIdEmpty();
+			result.error( exception );
+		}
+		
+		String cacheKey = ApplicationCache.concreteCacheKey( "appConfig", id );
+		Element element = cache.get( cacheKey );
+		
+		if (( null != element ) && ( null != element.getObjectValue()) ) {
+			woText = ( WoText ) element.getObjectValue();
+			result.setData( woText );
+		} else {
+			if( check ){
+				try {
+					appInfoConfig = appInfoServiceAdv.getConfigObject( id );
+					if( appInfoConfig == null ){
+						woText.setText("{}");
+					}else{
+						woText.setText( appInfoConfig.getConfig() );
+					}
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new ExceptionAppInfoProcess( e, "根据指定id查询栏目配置支持信息对象时发生异常。id:" + id );
+					result.error( exception );
+					logger.error( e, effectivePerson, request, null);
+				}
+			}
+			if( check ){
+				cache.put(new Element( cacheKey, woText ));
+				result.setData( woText );
+			}
+		}
+		
+		return result;
+	}
+}

+ 12 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanManage.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -14,9 +9,12 @@ import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
 import com.x.cms.core.entity.AppInfo;
 import com.x.cms.core.entity.CategoryInfo;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanManage extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanManage.class);
@@ -102,6 +100,14 @@ public class ActionListWhatICanManage extends BaseAction {
 				if ( wos != null && wos.size() > 0) {
 					List<String> query_categoryList = null;
 					for ( Wo wo : wos ) {
+						try {
+							wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+						} catch (Exception e) {
+							check = false;
+							Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+							result.error(exception);
+							logger.error(e, effectivePerson, request, null);
+						}
 						query_categoryList = new ArrayList<>();				
 						if( ListTools.isNotEmpty( wo.getCategoryList() )) {
 							for( String categoryId : wo.getCategoryList() ) {

+ 14 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanManage_WithAppType.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -14,9 +9,12 @@ import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
 import com.x.cms.core.entity.AppInfo;
 import com.x.cms.core.entity.CategoryInfo;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanManage_WithAppType extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanManage_WithAppType.class);
@@ -101,6 +99,16 @@ public class ActionListWhatICanManage_WithAppType extends BaseAction {
 				if ( wos != null && wos.size() > 0) {
 					List<String> query_categoryList = null;
 					for ( Wo wo : wos ) {
+
+						try {
+							wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+						} catch (Exception e) {
+							check = false;
+							Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+							result.error(exception);
+							logger.error(e, effectivePerson, request, null);
+						}
+
 						query_categoryList = new ArrayList<>();				
 						if( ListTools.isNotEmpty( wo.getCategoryList() )) {
 							for( String categoryId : wo.getCategoryList() ) {

+ 14 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanPublish.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -12,9 +7,12 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanPublish extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanPublish.class);
@@ -60,6 +58,16 @@ public class ActionListWhatICanPublish extends BaseAction {
 				if( ListTools.isNotEmpty( wos_out )){
 					for( Wo wo : wos_out ) {
 						if( ListTools.isNotEmpty( wo.getWrapOutCategoryList() )) {
+
+							try {
+								wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
+
 							wos.add( wo );
 						}
 					}

+ 13 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanPublish_WithAppType.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -12,9 +7,12 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanPublish_WithAppType extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanPublish_WithAppType.class);
@@ -58,6 +56,15 @@ public class ActionListWhatICanPublish_WithAppType extends BaseAction {
 			if( ListTools.isNotEmpty( wos_out )){
 				for( Wo wo : wos_out ) {
 					if( ListTools.isNotEmpty( wo.getWrapOutCategoryList() )) {
+						try {
+							wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+						} catch (Exception e) {
+							check = false;
+							Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+							result.error(exception);
+							logger.error(e, effectivePerson, request, null);
+						}
+
 						wos.add( wo );
 					}
 				}

+ 14 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewAllDocType.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -12,9 +7,12 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanViewAllDocType extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanViewAllDocType.class);
@@ -58,6 +56,16 @@ public class ActionListWhatICanViewAllDocType extends BaseAction {
 				if( ListTools.isNotEmpty( wos_out )){
 					for( Wo wo : wos_out ) {
 						if( ListTools.isNotEmpty( wo.getWrapOutCategoryList() )) {
+
+							try {
+								wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
+
 							wos.add( wo );
 						}
 					}

+ 14 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewAllDocType_WithAppType.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -12,9 +7,12 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanViewAllDocType_WithAppType extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanViewAllDocType_WithAppType.class);
@@ -58,6 +56,16 @@ public class ActionListWhatICanViewAllDocType_WithAppType extends BaseAction {
 				if( ListTools.isNotEmpty( wos_out )){
 					for( Wo wo : wos_out ) {
 						if( ListTools.isNotEmpty( wo.getWrapOutCategoryList() )) {
+
+							try {
+								wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
+
 							wos.add( wo );
 						}
 					}

+ 14 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewArticle.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -12,9 +7,12 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanViewArticle extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanViewArticle.class);
@@ -63,6 +61,16 @@ public class ActionListWhatICanViewArticle extends BaseAction {
 			if( ListTools.isNotEmpty( wos_out )){
 				for( Wo wo : wos_out ) {
 					if( ListTools.isNotEmpty( wo.getWrapOutCategoryList() )) {
+
+						try {
+							wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+						} catch (Exception e) {
+							check = false;
+							Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+							result.error(exception);
+							logger.error(e, effectivePerson, request, null);
+						}
+
 						wos.add( wo );
 					}
 				}

+ 14 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewArticle_WithAppType.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -12,9 +7,12 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanViewArticle_WithAppType extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanViewArticle_WithAppType.class);
@@ -63,6 +61,16 @@ public class ActionListWhatICanViewArticle_WithAppType extends BaseAction {
 			if( ListTools.isNotEmpty( wos_out )){
 				for( Wo wo : wos_out ) {
 					if( ListTools.isNotEmpty( wo.getWrapOutCategoryList() )) {
+
+						try {
+							wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+						} catch (Exception e) {
+							check = false;
+							Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+							result.error(exception);
+							logger.error(e, effectivePerson, request, null);
+						}
+
 						wos.add( wo );
 					}
 				}

+ 14 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewData.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -12,9 +7,12 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanViewData extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanViewData.class);
@@ -59,6 +57,16 @@ public class ActionListWhatICanViewData extends BaseAction {
 			if( ListTools.isNotEmpty( wos_out )){
 				for( Wo wo : wos_out ) {
 					if( ListTools.isNotEmpty( wo.getWrapOutCategoryList() )) {
+
+						try {
+							wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+						} catch (Exception e) {
+							check = false;
+							Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+							result.error(exception);
+							logger.error(e, effectivePerson, request, null);
+						}
+
 						wos.add( wo );
 					}
 				}

+ 14 - 6
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionListWhatICanViewData_WithAppType.java

@@ -1,10 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
@@ -12,9 +7,12 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
-
 import net.sf.ehcache.Element;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 public class ActionListWhatICanViewData_WithAppType extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger(ActionListWhatICanViewData_WithAppType.class);
@@ -58,6 +56,16 @@ public class ActionListWhatICanViewData_WithAppType extends BaseAction {
 				if( ListTools.isNotEmpty( wos_out )){
 					for( Wo wo : wos_out ) {
 						if( ListTools.isNotEmpty( wo.getWrapOutCategoryList() )) {
+
+							try {
+								wo.setConfig( appInfoServiceAdv.getConfigJson( wo.getId() ) );
+							} catch (Exception e) {
+								check = false;
+								Exception exception = new ExceptionAppInfoProcess(e, "系统根据ID查询栏目配置支持信息时发生异常。ID=" + wo.getId() );
+								result.error(exception);
+								logger.error(e, effectivePerson, request, null);
+							}
+
 							wos.add( wo );
 						}
 					}

+ 6 - 2
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionSave.java

@@ -148,7 +148,7 @@ public class ActionSave extends BaseAction {
 			}
 			
 			try {
-				appInfo = appInfoServiceAdv.save( wi, effectivePerson );
+				appInfo = appInfoServiceAdv.save( wi, wi.getConfig(), effectivePerson );
 				Wo wo = new Wo();
 				wo.setId( appInfo.getId() );
 				result.setData( wo );
@@ -196,10 +196,14 @@ public class ActionSave extends BaseAction {
 		@FieldDescribe("指定用于操作的身份,可选参数")
 		private String identity = null;
 
+		@FieldDescribe("栏目配置支持信息,JSON")
+		private String config = "{}";
+
+		public String getConfig() { return this.config; }
+		public void setConfig(final String config) { this.config = config; }
 		public String getIdentity() {
 			return identity;
 		}
-
 		public void setIdentity(String identity) {
 			this.identity = identity;
 		}

+ 63 - 0
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/ActionSaveConfig.java

@@ -0,0 +1,63 @@
+package com.x.cms.assemble.control.jaxrs.appinfo;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.AuditLog;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoId;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.cms.core.entity.AppInfo;
+import com.x.cms.core.entity.AppInfoConfig;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class ActionSaveConfig extends BaseAction {
+
+	private static  Logger logger = LoggerFactory.getLogger(ActionSaveConfig.class);
+
+	@AuditLog(operation = "保存栏目配置支持信息")
+	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson, String appId, JsonElement jsonElement ) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+
+		AppInfoConfig appInfoConfig = null;
+		String config = jsonElement.toString();
+		Boolean check = true;
+		
+		if (check) {
+			if ( StringUtils.isEmpty( appId ) ) {
+				check = false;
+				Exception exception = new ExceptionAppInfoIdEmpty();
+				result.error(exception);
+			}
+		}
+
+		if (check) {
+			try {
+
+				appInfoConfig = appInfoServiceAdv.saveConfig( appId, config, effectivePerson );
+
+				Wo wo = new Wo();
+				wo.setId( appInfoConfig.getId() );
+				result.setData( wo );
+				
+				// 更新缓存
+				ApplicationCache.notify( AppInfo.class );
+
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ExceptionAppInfoProcess(e, "应用栏目配置支持信息保存时发生异常。");
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		return result;
+	}
+
+	public static class Wo extends WoId {
+
+	}
+	
+}

+ 75 - 0
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/AppInfoConfigAction.java

@@ -0,0 +1,75 @@
+package com.x.cms.assemble.control.jaxrs.appinfo;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.JaxrsDescribe;
+import com.x.base.core.project.annotation.JaxrsMethodDescribe;
+import com.x.base.core.project.annotation.JaxrsParameterDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.http.HttpMediaType;
+import com.x.base.core.project.jaxrs.ResponseFactory;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.base.core.project.jaxrs.WoText;
+import com.x.base.core.project.jaxrs.proxy.StandardJaxrsActionProxy;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.cms.assemble.control.ThisApplication;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.*;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+@Path("appconfig")
+@JaxrsDescribe("信息发布(CMS)-栏目配置支持信息(APPINFOCONFIG)管理服务")
+public class AppInfoConfigAction extends StandardJaxrsAction {
+
+	private StandardJaxrsActionProxy proxy = new StandardJaxrsActionProxy(ThisApplication.context());
+	private static  Logger logger = LoggerFactory.getLogger(AppInfoConfigAction.class);
+
+	@JaxrsMethodDescribe(value = "更新栏目配置支持信息,JSON格式。", action = ActionSaveConfig.class)
+	@POST
+	@Path("{appId}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void save( @Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+					  @JaxrsParameterDescribe("栏目ID") @PathParam("appId") String appId,
+					  JsonElement jsonElement ) {
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		ActionResult<ActionSaveConfig.Wo> result = new ActionResult<>();
+		Boolean check = true;
+		if (check) {
+			try {
+				result = ((ActionSaveConfig)proxy.getProxy(ActionSaveConfig.class)).execute( request, effectivePerson, appId, jsonElement );
+			} catch (Exception e) {
+				result = new ActionResult<>();
+				Exception exception = new ExceptionAppInfoProcess(e, "栏目信息保存时发生异常。");
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+	@JaxrsMethodDescribe(value = "根据栏目ID获取栏目配置支持信息对象.", action = ActionGetConfig.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void get( @Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request, 
+			@JaxrsParameterDescribe("栏目ID") @PathParam("id") String id) {
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		ActionResult<WoText> result = new ActionResult<>();
+		try {
+			result = ((ActionGetConfig)proxy.getProxy(ActionGetConfig.class)).execute( request, effectivePerson, id );
+		} catch (Exception e) {
+			result = new ActionResult<>();
+			Exception exception = new ExceptionAppInfoProcess(e, "根据指定ID查询应用栏目配置支持信息时发生异常。id:" + id );
+			result.error(exception);
+			logger.error(e, effectivePerson, request, null);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+}

+ 26 - 33
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/appinfo/BaseAction.java

@@ -1,34 +1,19 @@
 package com.x.cms.assemble.control.jaxrs.appinfo;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.lang3.StringUtils;
-
 import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
 import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.jaxrs.StandardJaxrsAction;
 import com.x.base.core.project.tools.ListTools;
-import com.x.cms.assemble.control.service.AppDictServiceAdv;
-import com.x.cms.assemble.control.service.AppInfoServiceAdv;
-import com.x.cms.assemble.control.service.CategoryInfoServiceAdv;
-import com.x.cms.assemble.control.service.DocumentQueryService;
-import com.x.cms.assemble.control.service.FormServiceAdv;
-import com.x.cms.assemble.control.service.PermissionOperateService;
-import com.x.cms.assemble.control.service.PermissionQueryService;
-import com.x.cms.assemble.control.service.ScriptServiceAdv;
-import com.x.cms.assemble.control.service.UserManagerService;
-import com.x.cms.assemble.control.service.ViewServiceAdv;
+import com.x.cms.assemble.control.service.*;
 import com.x.cms.core.entity.AppInfo;
 import com.x.cms.core.entity.CategoryInfo;
-
 import net.sf.ehcache.Ehcache;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
 
 public class BaseAction extends StandardJaxrsAction {
 
@@ -213,9 +198,9 @@ public class BaseAction extends StandardJaxrsAction {
 		}
 		return wraps;
 	}
-		
+
 	public static class Wo extends AppInfo {
-		
+
 		private Long rank;
 
 		public Long getRank() {
@@ -225,32 +210,40 @@ public class BaseAction extends StandardJaxrsAction {
 		public void setRank(Long rank) {
 			this.rank = rank;
 		}
-		
+
 		private static final long serialVersionUID = -5076990764713538973L;
-		
+
 		public static List<String> Excludes = new ArrayList<String>();
 
+		@FieldDescribe("栏目下的分类信息列表")
 		private List<WoCategory> wrapOutCategoryList = null;
-		
+
+		@FieldDescribe("配置支持信息JSON内容")
+		private String config = null;
+
 		public List<WoCategory> getWrapOutCategoryList() {
 			return wrapOutCategoryList;
 		}
 		public void setWrapOutCategoryList(List<WoCategory> wrapOutCategoryList) {
 			this.wrapOutCategoryList = wrapOutCategoryList;
 		}
-		
+
+		public String getConfig() { return this.config; }
+
+		public void setConfig(final String config) { this.config = config; }
+
 		static WrapCopier<AppInfo, Wo> copier = WrapCopierFactory.wo( AppInfo.class, Wo.class, null, ListTools.toList(JpaObject.FieldsInvisible));
-		
+
 	}
-	
+
 	public static class WoCategory extends CategoryInfo {
-		
+
 		private static final long serialVersionUID = -5076990764713538973L;
-		
+
 		public static List<String> Excludes = new ArrayList<String>();
-		
+
 		static WrapCopier<CategoryInfo, WoCategory> copier = WrapCopierFactory.wo( CategoryInfo.class, WoCategory.class, null, ListTools.toList(JpaObject.FieldsInvisible));
-		
+
 	}
-			
+
 }

+ 3 - 2
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistDraftDocument.java

@@ -1,7 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.document;
 
-import javax.servlet.http.HttpServletRequest;
-
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.project.cache.ApplicationCache;
@@ -13,6 +11,8 @@ import com.x.base.core.project.logger.LoggerFactory;
 import com.x.cms.assemble.control.Business;
 import com.x.cms.core.entity.Document;
 
+import javax.servlet.http.HttpServletRequest;
+
 public class ActionPersistDraftDocument extends BaseAction {
 
 	private static  Logger logger = LoggerFactory.getLogger( ActionPersistDraftDocument.class );
@@ -29,6 +29,7 @@ public class ActionPersistDraftDocument extends BaseAction {
 				result.error( exception );
 				throw exception;
 			}
+
 			try {
 				modifyDocStatus( id, "draft", effectivePerson.getDistinguishedName() );
 				document.setDocStatus( "draft" );

+ 1 - 1
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistImportDataExcel.java

@@ -169,7 +169,7 @@ public class ActionPersistImportDataExcel extends BaseAction {
 				template.setTitle(  wi.getTitle() );
 			}else {
 				//暂不设置标题
-				template.setTitle( "" );
+				template.setTitle( appInfo.getAppName() + " - " + categoryInfo.getCategoryName() + " - 无标题文档" );
 			}
 			
 			if( StringUtils.isNotEmpty( wi.getIdentity() )) {

+ 17 - 18
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistPublishByWorkFlow.java

@@ -58,14 +58,6 @@ public class ActionPersistPublishByWorkFlow extends BaseAction {
 			logger.error( e, effectivePerson, request, null);
 		}
 
-		if (check) {
-			if ( StringUtils.isEmpty(wi.getTitle())) {
-				check = false;
-				Exception exception = new ExceptionDocumentTitleEmpty();
-				result.error(exception);
-			}
-		}
-
 		if (check) {
 			if ( StringUtils.isEmpty(wi.getCategoryId())) {
 				check = false;
@@ -76,16 +68,15 @@ public class ActionPersistPublishByWorkFlow extends BaseAction {
 
 		if (check) {
 			try {
-				appInfo = appInfoServiceAdv.get(wi.getAppId());
-				if (appInfo == null) {
+				categoryInfo = categoryInfoServiceAdv.get( wi.getCategoryId() );
+				if (categoryInfo == null) {
 					check = false;
-					Exception exception = new ExceptionAppInfoNotExists(wi.getAppId());
+					Exception exception = new ExceptionCategoryInfoNotExists(wi.getCategoryId());
 					result.error(exception);
 				}
 			} catch (Exception e) {
 				check = false;
-				Exception exception = new ExceptionDocumentInfoProcess(e,
-						"系统在根据ID查询应用栏目信息时发生异常!ID:" + wi.getAppId());
+				Exception exception = new ExceptionDocumentInfoProcess(e,"系统在根据ID查询分类信息时发生异常!ID:" + wi.getCategoryId());
 				result.error(exception);
 				logger.error(e, effectivePerson, request, null);
 			}
@@ -93,16 +84,15 @@ public class ActionPersistPublishByWorkFlow extends BaseAction {
 
 		if (check) {
 			try {
-				categoryInfo = categoryInfoServiceAdv.get(wi.getCategoryId());
-				if (categoryInfo == null) {
+				appInfo = appInfoServiceAdv.get( categoryInfo.getAppId() );
+				if (appInfo == null) {
 					check = false;
-					Exception exception = new ExceptionCategoryInfoNotExists(wi.getCategoryId());
+					Exception exception = new ExceptionAppInfoNotExists(categoryInfo.getAppId());
 					result.error(exception);
 				}
 			} catch (Exception e) {
 				check = false;
-				Exception exception = new ExceptionDocumentInfoProcess(e,
-						"系统在根据ID查询分类信息时发生异常!ID:" + wi.getCategoryId());
+				Exception exception = new ExceptionDocumentInfoProcess(e, "系统在根据ID查询应用栏目信息时发生异常!ID:" + categoryInfo.getAppId());
 				result.error(exception);
 				logger.error(e, effectivePerson, request, null);
 			}
@@ -199,6 +189,15 @@ public class ActionPersistPublishByWorkFlow extends BaseAction {
 			}
 		}
 
+		if (check) {
+			if ( StringUtils.isEmpty(wi.getTitle())) {
+//				check = false;
+//				Exception exception = new ExceptionDocumentTitleEmpty();
+//				result.error(exception);
+				wi.setTitle( appInfo.getAppName() + " - " + categoryInfo.getCategoryName() + " - 无标题文档" );
+			}
+		}
+
 		if (check) {
 			try {
 				JsonElement docData = XGsonBuilder.instance().toJsonTree(wi.getDocData(), Map.class);

+ 17 - 18
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistPublishContent.java

@@ -58,14 +58,6 @@ public class ActionPersistPublishContent extends BaseAction {
 			result.error( exception );
 			logger.error( e, effectivePerson, request, null);
 		}
-		
-		if (check) {
-			if ( StringUtils.isEmpty(wi.getTitle())) {
-				check = false;
-				Exception exception = new ExceptionDocumentTitleEmpty();
-				result.error(exception);
-			}
-		}
 
 		if (check) {
 			if ( StringUtils.isEmpty(wi.getCategoryId())) {
@@ -77,16 +69,15 @@ public class ActionPersistPublishContent extends BaseAction {
 
 		if (check) {
 			try {
-				appInfo = appInfoServiceAdv.get(wi.getAppId());
-				if (appInfo == null) {
+				categoryInfo = categoryInfoServiceAdv.get( wi.getCategoryId() );
+				if (categoryInfo == null) {
 					check = false;
-					Exception exception = new ExceptionAppInfoNotExists(wi.getAppId());
+					Exception exception = new ExceptionCategoryInfoNotExists(wi.getCategoryId());
 					result.error(exception);
 				}
 			} catch (Exception e) {
 				check = false;
-				Exception exception = new ExceptionDocumentInfoProcess(e,
-						"系统在根据ID查询应用栏目信息时发生异常!ID:" + wi.getAppId());
+				Exception exception = new ExceptionDocumentInfoProcess(e,"系统在根据ID查询分类信息时发生异常!ID:" + wi.getCategoryId());
 				result.error(exception);
 				logger.error(e, effectivePerson, request, null);
 			}
@@ -94,16 +85,15 @@ public class ActionPersistPublishContent extends BaseAction {
 
 		if (check) {
 			try {
-				categoryInfo = categoryInfoServiceAdv.get(wi.getCategoryId());
-				if (categoryInfo == null) {
+				appInfo = appInfoServiceAdv.get( categoryInfo.getAppId() );
+				if (appInfo == null) {
 					check = false;
-					Exception exception = new ExceptionCategoryInfoNotExists(wi.getCategoryId());
+					Exception exception = new ExceptionAppInfoNotExists(categoryInfo.getAppId());
 					result.error(exception);
 				}
 			} catch (Exception e) {
 				check = false;
-				Exception exception = new ExceptionDocumentInfoProcess(e,
-						"系统在根据ID查询分类信息时发生异常!ID:" + wi.getCategoryId());
+				Exception exception = new ExceptionDocumentInfoProcess(e, "系统在根据ID查询应用栏目信息时发生异常!ID:" + categoryInfo.getAppId());
 				result.error(exception);
 				logger.error(e, effectivePerson, request, null);
 			}
@@ -206,6 +196,15 @@ public class ActionPersistPublishContent extends BaseAction {
 			}
 		}
 
+		if (check) {
+			if ( StringUtils.isEmpty(wi.getTitle())) {
+//				check = false;
+//				Exception exception = new ExceptionDocumentTitleEmpty();
+//				result.error(exception);
+				wi.setTitle( appInfo.getAppName() + " - " + categoryInfo.getCategoryName() + " - 无标题文档" );
+			}
+		}
+
 		if (check) {
 			try {
 				JsonElement docData = XGsonBuilder.instance().toJsonTree(wi.getDocData(), Map.class);

+ 11 - 10
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionPersistSaveDocument.java

@@ -70,14 +70,6 @@ public class ActionPersistSaveDocument extends BaseAction {
 			}
 		}
 
-		if (check) {
-			if ( StringUtils.isEmpty(wi.getTitle()) ) {
-				check = false;
-				Exception exception = new ExceptionDocumentTitleEmpty();
-				result.error(exception);
-			}
-		}
-
 		if (check) {
 			if ( StringUtils.isEmpty( wi.getCategoryId() ) ) {
 				check = false;
@@ -118,7 +110,7 @@ public class ActionPersistSaveDocument extends BaseAction {
 				logger.error(e, effectivePerson, request, null);
 			}
 		}
-		
+
 		// 查询分类设置的编辑表单
 		if (check) {
 			if ( StringUtils.isEmpty(categoryInfo.getFormId() )) {
@@ -221,7 +213,16 @@ public class ActionPersistSaveDocument extends BaseAction {
 				}
 			}
 		}
-		
+
+		if (check) {
+			if ( StringUtils.isEmpty(document.getTitle())) {
+//				check = false;
+//				Exception exception = new ExceptionDocumentTitleEmpty();
+//				result.error(exception);
+				document.setTitle( appInfo.getAppName() + " - " + categoryInfo.getCategoryName() + " - 无标题文档" );
+			}
+		}
+
 		if (check) {
 			try {
 				JsonElement dataJson = null;

+ 3 - 0
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ActionQueryListPrevWithFilter.java

@@ -166,6 +166,7 @@ public class ActionQueryListPrevWithFilter extends BaseAction {
 							int index = -1;
 							//放一页到searchResultList中进行返回
 							for( int i = 0; i< documentList.size(); i++ ) {
+								document = documentList.get(i);
 								if( StringUtils.isEmpty( id ) || document.getId().equalsIgnoreCase( id ) ) {
 									index = i;
 								}
@@ -189,11 +190,13 @@ public class ActionQueryListPrevWithFilter extends BaseAction {
 							int index = -1;
 							//放一页到searchResultList中进行返回
 							for( int i = 0; i< reviewList.size(); i++ ) {
+								review = reviewList.get(i);
 								if( StringUtils.isEmpty( id ) || review.getDocId().equalsIgnoreCase( id ) ) {
 									index = i;
 								}
 							}
 							for( ; index >=0; index-- ){
+								review = reviewList.get( index );
 								searchResultList.add(documentQueryService.get( review.getDocId() ) );
 								if( searchResultList.size() >= count ) { break; }
 							}

+ 1 - 1
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/DocumentAction.java

@@ -586,7 +586,7 @@ public class DocumentAction extends StandardJaxrsAction{
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 	}
 
-	@JaxrsMethodDescribe(value = "列示符合过滤条件的已发布的信息内容, 下一页.", action = ActionQueryListWithFilterPaging.class)
+	@JaxrsMethodDescribe(value = "分页查询符合过滤条件的已发布的信息内容.", action = ActionQueryListWithFilterPaging.class)
 	@PUT
 	@Path("filter/list/{page}/size/{size}")
 	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)

+ 0 - 12
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/document/ExceptionDocumentTitleEmpty.java

@@ -1,12 +0,0 @@
-package com.x.cms.assemble.control.jaxrs.document;
-
-import com.x.base.core.project.exception.PromptException;
-
-class ExceptionDocumentTitleEmpty extends PromptException {
-
-	private static final long serialVersionUID = 1859164370743532895L;
-
-	ExceptionDocumentTitleEmpty() {
-		super("文档标题为空,无法创建文档信息。" );
-	}
-}

+ 4 - 3
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/ActionFileUpdate.java

@@ -31,14 +31,16 @@ public class ActionFileUpdate extends BaseAction {
 
 	@AuditLog(operation = "更新附件")
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, 
-			String docId, String old_attId, String site, byte[] bytes, FormDataContentDisposition disposition) {
+			String docId, String old_attId, String site, String fileName, byte[] bytes, FormDataContentDisposition disposition) {
 		ActionResult<Wo> result = new ActionResult<>();
 		FileInfo attachment = null;
 		Document document = null;
 		AppInfo appInfo = null;
 		CategoryInfo categoryInfo = null;
 		StorageMapping mapping = null;
-		String fileName = null;
+		if (StringUtils.isEmpty(fileName)) {
+			fileName = this.fileName(disposition);
+		}
 		Boolean check = true;	
 		
 		if( check ){
@@ -152,7 +154,6 @@ public class ActionFileUpdate extends BaseAction {
 		
 		if( check ){
 			try {
-				fileName = FilenameUtils.getName(new String(disposition.getFileName().getBytes(DefaultCharset.name_iso_8859_1), DefaultCharset.name));
 				/** 禁止不带扩展名的文件上传 */
 				if (StringUtils.isEmpty(fileName)) {
 					check = false;

+ 5 - 4
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/ActionFileUpdateCallback.java

@@ -29,13 +29,15 @@ public class ActionFileUpdateCallback extends BaseAction {
 	private static Logger logger = LoggerFactory.getLogger(ActionFileUpdateCallback.class);
 
 	@AuditLog(operation = "更新附件")
-	protected ActionResult<Wo<WoObject>> execute( HttpServletRequest request, EffectivePerson effectivePerson, 
-			String docId, String old_attId, String callback, String site, byte[] bytes, FormDataContentDisposition disposition) {
+	protected ActionResult<Wo<WoObject>> execute( HttpServletRequest request, EffectivePerson effectivePerson, String docId,
+			String old_attId, String callback, String site, String fileName, byte[] bytes, FormDataContentDisposition disposition) {
 		ActionResult<Wo<WoObject>> result = new ActionResult<>();
 		FileInfo attachment = null;
 		Document document = null;
 		StorageMapping mapping = null;
-		String fileName = null;
+		if (StringUtils.isEmpty(fileName)) {
+			fileName = this.fileName(disposition);
+		}
 		Boolean check = true;		
 		
 		if( check ){
@@ -85,7 +87,6 @@ public class ActionFileUpdateCallback extends BaseAction {
 		
 		if( check ){
 			try {
-				fileName = FilenameUtils.getName(new String(disposition.getFileName().getBytes(DefaultCharset.name_iso_8859_1), DefaultCharset.name));
 				/** 禁止不带扩展名的文件上传 */
 				if (StringUtils.isEmpty(fileName)) {
 					check = false;

+ 4 - 3
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/ActionFileUpload.java

@@ -29,12 +29,14 @@ public class ActionFileUpload extends BaseAction {
 
 	@AuditLog(operation = "上传附件")
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, 
-			String docId, String site, byte[] bytes, FormDataContentDisposition disposition) {
+			String docId, String site, String fileName, byte[] bytes, FormDataContentDisposition disposition) {
 		ActionResult<Wo> result = new ActionResult<>();
 		FileInfo attachment = null;
 		Document document = null;
 		StorageMapping mapping = null;
-		String fileName = null;
+		if (StringUtils.isEmpty(fileName)) {
+			fileName = this.fileName(disposition);
+		}
 		Boolean check = true;		
 		
 		if( check ){
@@ -77,7 +79,6 @@ public class ActionFileUpload extends BaseAction {
 		
 		if( check ){
 			try {
-				fileName = FilenameUtils.getName(new String(disposition.getFileName().getBytes(DefaultCharset.name_iso_8859_1), DefaultCharset.name));
 				/** 禁止不带扩展名的文件上传 */
 				if (StringUtils.isEmpty(fileName)) {
 					check = false;

+ 5 - 3
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/ActionFileUploadCallback.java

@@ -29,12 +29,15 @@ public class ActionFileUploadCallback extends BaseAction {
 	private static Logger logger = LoggerFactory.getLogger(ActionFileUploadCallback.class);
 
 	@AuditLog(operation = "上传附件")
-	protected ActionResult<Wo<WoObject>> execute( HttpServletRequest request, EffectivePerson effectivePerson, String docId, String callback, String site, byte[] bytes, FormDataContentDisposition disposition) {
+	protected ActionResult<Wo<WoObject>> execute( HttpServletRequest request, EffectivePerson effectivePerson, String docId, String callback,
+			String site, String fileName, byte[] bytes, FormDataContentDisposition disposition) {
 		ActionResult<Wo<WoObject>> result = new ActionResult<>();
 		FileInfo attachment = null;
 		Document document = null;
 		StorageMapping mapping = null;
-		String fileName = null;
+		if (StringUtils.isEmpty(fileName)) {
+			fileName = this.fileName(disposition);
+		}
 		Boolean check = true;		
 		
 		if( check ){
@@ -77,7 +80,6 @@ public class ActionFileUploadCallback extends BaseAction {
 		
 		if( check ){
 			try {
-				fileName = FilenameUtils.getName(new String(disposition.getFileName().getBytes(DefaultCharset.name_iso_8859_1), DefaultCharset.name));
 				/** 禁止不带扩展名的文件上传 */
 				if (StringUtils.isEmpty(fileName)) {
 					check = false;

+ 12 - 8
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/fileinfo/FileInfoAction.java

@@ -191,13 +191,14 @@ public class FileInfoAction extends StandardJaxrsAction{
 	public void attachmentUpload(@Suspended final AsyncResponse asyncResponse, 
 			@Context HttpServletRequest request, 
 			@JaxrsParameterDescribe("文档ID") @PathParam("docId") String docId, 
-			@JaxrsParameterDescribe("位置") @FormDataParam("site") String site, 
+			@JaxrsParameterDescribe("位置") @FormDataParam("site") String site,
+			@JaxrsParameterDescribe("附件名称") @FormDataParam(FILENAME_FIELD) String fileName,
 			@FormDataParam(FILE_FIELD) final byte[] bytes,
 			@JaxrsParameterDescribe("附件") @FormDataParam(FILE_FIELD) final FormDataContentDisposition disposition) {
 		ActionResult<ActionFileUpload.Wo> result = new ActionResult<>();
 		EffectivePerson effectivePerson = this.effectivePerson(request);
 		try {
-			result = ((ActionFileUpload)proxy.getProxy(ActionFileUpload.class)).execute(request, effectivePerson, docId, site, bytes, disposition);
+			result = ((ActionFileUpload)proxy.getProxy(ActionFileUpload.class)).execute(request, effectivePerson, docId, site, fileName, bytes, disposition);
 		} catch (Exception e) {
 			logger.error(e, effectivePerson, request, null);
 			result.error(e);
@@ -214,13 +215,14 @@ public class FileInfoAction extends StandardJaxrsAction{
 			@Context HttpServletRequest request, 
 			@JaxrsParameterDescribe("文档ID") @PathParam("docId") String docId, 
 			@JaxrsParameterDescribe("附件ID") @PathParam("id") String id, 
-			@JaxrsParameterDescribe("位置") @FormDataParam("site") String site, 
+			@JaxrsParameterDescribe("位置") @FormDataParam("site") String site,
+			@JaxrsParameterDescribe("附件名称") @FormDataParam(FILENAME_FIELD) String fileName,
 			@FormDataParam(FILE_FIELD) final byte[] bytes,
 			@JaxrsParameterDescribe("附件") @FormDataParam(FILE_FIELD) final FormDataContentDisposition disposition) {
 		ActionResult<ActionFileUpdate.Wo> result = new ActionResult<>();
 		EffectivePerson effectivePerson = this.effectivePerson(request);
 		try {
-			result = ((ActionFileUpdate)proxy.getProxy(ActionFileUpdate.class)).execute(request, effectivePerson, docId, id, site, bytes, disposition);
+			result = ((ActionFileUpdate)proxy.getProxy(ActionFileUpdate.class)).execute(request, effectivePerson, docId, id, site, fileName, bytes, disposition);
 		} catch (Exception e) {
 			logger.error(e, effectivePerson, request, null);
 			result.error(e);
@@ -236,13 +238,14 @@ public class FileInfoAction extends StandardJaxrsAction{
 			@Context HttpServletRequest request, 
 			@JaxrsParameterDescribe("文档ID") @PathParam("docId") String docId, 
 			@JaxrsParameterDescribe("回调函数名") @PathParam("callback") String callback,
-			@JaxrsParameterDescribe("位置") @FormDataParam("site") String site, 
+			@JaxrsParameterDescribe("位置") @FormDataParam("site") String site,
+			@JaxrsParameterDescribe("附件名称") @FormDataParam(FILENAME_FIELD) String fileName,
 			@FormDataParam(FILE_FIELD) final byte[] bytes,
 			@JaxrsParameterDescribe("附件") @FormDataParam(FILE_FIELD) final FormDataContentDisposition disposition) {
 		ActionResult<ActionFileUploadCallback.Wo<ActionFileUploadCallback.WoObject>> result = new ActionResult<>();
 		EffectivePerson effectivePerson = this.effectivePerson(request);
 		try {
-			result = ((ActionFileUploadCallback)proxy.getProxy(ActionFileUploadCallback.class)).execute(request, effectivePerson, docId, callback, site, bytes, disposition);
+			result = ((ActionFileUploadCallback)proxy.getProxy(ActionFileUploadCallback.class)).execute(request, effectivePerson, docId, callback, site, fileName, bytes, disposition);
 		} catch (Exception e) {
 			logger.error(e, effectivePerson, request, null);
 			result.error(e);
@@ -260,13 +263,14 @@ public class FileInfoAction extends StandardJaxrsAction{
 			@JaxrsParameterDescribe("文档ID") @PathParam("docId") String docId, 
 			@JaxrsParameterDescribe("附件ID") @PathParam("id") String id, 
 			@JaxrsParameterDescribe("回调函数名") @PathParam("callback") String callback,
-			@JaxrsParameterDescribe("位置") @FormDataParam("site") String site, 
+			@JaxrsParameterDescribe("位置") @FormDataParam("site") String site,
+			@JaxrsParameterDescribe("附件名称") @FormDataParam(FILENAME_FIELD) String fileName,
 			@FormDataParam(FILE_FIELD) final byte[] bytes,
 			@JaxrsParameterDescribe("附件") @FormDataParam(FILE_FIELD) final FormDataContentDisposition disposition) {
 		ActionResult<ActionFileUpdateCallback.Wo<ActionFileUpdateCallback.WoObject>> result = new ActionResult<>();
 		EffectivePerson effectivePerson = this.effectivePerson(request);
 		try {
-			result = ((ActionFileUpdateCallback)proxy.getProxy(ActionFileUpdateCallback.class)).execute(request, effectivePerson, docId, id, callback, site, bytes, disposition);
+			result = ((ActionFileUpdateCallback)proxy.getProxy(ActionFileUpdateCallback.class)).execute(request, effectivePerson, docId, id, callback, site, fileName, bytes, disposition);
 		} catch (Exception e) {
 			logger.error(e, effectivePerson, request, null);
 			result.error(e);

+ 36 - 25
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/input/ActionCover.java

@@ -1,26 +1,12 @@
 package com.x.cms.assemble.control.jaxrs.input;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Predicate;
-import javax.persistence.criteria.Root;
-
-import com.x.base.core.entity.annotation.CheckPersistType;
-import com.x.base.core.project.cache.ApplicationCache;
-import com.x.cms.core.entity.CategoryExt;
-import com.x.cms.core.entity.element.wrap.*;
-import org.apache.commons.collections4.ListUtils;
-import org.apache.commons.lang3.StringUtils;
-
 import com.google.gson.JsonElement;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.entity.dataitem.DataItemConverter;
+import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
@@ -28,14 +14,19 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.StringTools;
 import com.x.cms.assemble.control.Business;
-import com.x.cms.core.entity.AppInfo;
-import com.x.cms.core.entity.CategoryInfo;
-import com.x.cms.core.entity.CategoryInfo_;
-import com.x.cms.core.entity.element.AppDict;
-import com.x.cms.core.entity.element.AppDictItem;
-import com.x.cms.core.entity.element.File;
-import com.x.cms.core.entity.element.Form;
-import com.x.cms.core.entity.element.Script;
+import com.x.cms.core.entity.*;
+import com.x.cms.core.entity.element.*;
+import com.x.cms.core.entity.element.wrap.*;
+import org.apache.commons.collections4.ListUtils;
+import org.apache.commons.lang3.StringUtils;
+
+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 java.util.ArrayList;
+import java.util.List;
 
 class ActionCover extends BaseAction {
 
@@ -60,10 +51,24 @@ class ActionCover extends BaseAction {
 		List<JpaObject> removeObjects = new ArrayList<>();
 		List<JpaObject> checkPersistObjects = new ArrayList<>();
 		AppInfo appInfo = business.entityManagerContainer().find(wi.getId(), AppInfo.class);
+
 		if (null == appInfo) {
 			throw new ExceptionAppInfoNotExist(wi.getId());
 		}
-		
+
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->start
+		AppInfoConfig appInfoConfig = business.entityManagerContainer().find(wi.getId(), AppInfoConfig.class);
+		if (null == appInfoConfig) {
+			appInfoConfig = new AppInfoConfig();
+			appInfoConfig.setId( wi.getId() );
+			appInfoConfig.setConfig( wi.getConfig() );
+			persistObjects.add( appInfoConfig );
+		}else{
+			appInfoConfig.setConfig( wi.getConfig() );
+			checkPersistObjects.add( appInfoConfig );
+		}
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->end
+
 		for (WrapForm _o : wi.getFormList() ) {
 			Form obj = business.entityManagerContainer().find( _o.getId(), Form.class );
 			if ( null != obj ) {
@@ -193,6 +198,9 @@ class ActionCover extends BaseAction {
 		business.entityManagerContainer().beginTransaction(AppDictItem.class);
 		business.entityManagerContainer().beginTransaction(CategoryInfo.class);
 		business.entityManagerContainer().beginTransaction(CategoryExt.class);
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->start
+		business.entityManagerContainer().beginTransaction(AppInfoConfig.class);
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->end
 
 		for (JpaObject o : removeObjects) {
 			business.entityManagerContainer().remove(o);
@@ -212,6 +220,9 @@ class ActionCover extends BaseAction {
 		ApplicationCache.notify(Form.class);
 		ApplicationCache.notify(Script.class);
 		ApplicationCache.notify(AppInfo.class);
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->start
+		ApplicationCache.notify(AppInfoConfig.class);
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->end
 
 		return appInfo;
 	}

+ 33 - 8
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/input/ActionCreate.java

@@ -1,13 +1,11 @@
 package com.x.cms.assemble.control.jaxrs.input;
 
-import java.util.ArrayList;
-import java.util.List;
-
 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.DataItemConverter;
+import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
@@ -15,15 +13,15 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.cms.assemble.control.Business;
 import com.x.cms.core.entity.AppInfo;
+import com.x.cms.core.entity.AppInfoConfig;
 import com.x.cms.core.entity.CategoryExt;
 import com.x.cms.core.entity.CategoryInfo;
-import com.x.cms.core.entity.element.AppDict;
-import com.x.cms.core.entity.element.AppDictItem;
-import com.x.cms.core.entity.element.File;
-import com.x.cms.core.entity.element.Form;
-import com.x.cms.core.entity.element.Script;
+import com.x.cms.core.entity.element.*;
 import com.x.cms.core.entity.element.wrap.*;
 
+import java.util.ArrayList;
+import java.util.List;
+
 class ActionCreate extends BaseAction {
 
 	private static Logger logger = LoggerFactory.getLogger(ActionCreate.class);
@@ -52,13 +50,26 @@ class ActionCreate extends BaseAction {
 	private AppInfo create( Business business, Wi wi ) throws Exception {
 		List<JpaObject> persistObjects = new ArrayList<>();
 		AppInfo appInfo = business.entityManagerContainer().find(wi.getId(), AppInfo.class);
+
 		if (null != appInfo) {
 			throw new ExceptionAppInfoExist(wi.getId());
 		}
+
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->start
+		AppInfoConfig appInfoConfig = business.entityManagerContainer().find(wi.getId(), AppInfoConfig.class);
+		if (null == appInfoConfig) {
+			appInfoConfig = new AppInfoConfig();
+			appInfoConfig.setId( wi.getId() );
+			appInfoConfig.setConfig( wi.getConfig() );
+			persistObjects.add( appInfoConfig );
+		}
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->end
+
 		appInfo = WrapCms.inCopier.copy(wi);
 		appInfo.setAppName(this.idleAppInfoName(business, appInfo.getAppName(), appInfo.getId()));
 		appInfo.setAppAlias(this.idleAppInfoAlias(business, appInfo.getAppAlias(), appInfo.getId()));
 		persistObjects.add(appInfo);
+
 		for (WrapForm _o : wi.getFormList()) {
 			Form obj = business.entityManagerContainer().find(_o.getId(), Form.class);
 			if (null != obj) {
@@ -134,11 +145,25 @@ class ActionCreate extends BaseAction {
 		business.entityManagerContainer().beginTransaction(AppDictItem.class);
 		business.entityManagerContainer().beginTransaction(CategoryInfo.class);
 		business.entityManagerContainer().beginTransaction(CategoryExt.class);
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->start
+		business.entityManagerContainer().beginTransaction(AppInfoConfig.class);
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->end
 
 		for (JpaObject o : persistObjects) {
 			business.entityManagerContainer().persist(o);
 		}
 		business.entityManagerContainer().commit();
+
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->start
+		ApplicationCache.notify(CategoryInfo.class);
+		ApplicationCache.notify(AppDictItem.class);
+		ApplicationCache.notify(AppDict.class);
+		ApplicationCache.notify(Form.class);
+		ApplicationCache.notify(Script.class);
+		ApplicationCache.notify(AppInfo.class);
+		ApplicationCache.notify(AppInfoConfig.class);
+		//2020年1月16日 O2LEE 保存栏目信息对应的配置支持信息JSON ---->end
+
 		return appInfo;
 	}
 

+ 13 - 5
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/output/ActionList.java

@@ -1,8 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.output;
 
-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;
@@ -11,8 +8,8 @@ import com.x.base.core.project.bean.WrapCopierFactory;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.tools.ListTools;
+import com.x.cms.assemble.control.Business;
 import com.x.cms.core.entity.AppInfo;
-import com.x.cms.core.entity.CategoryExt;
 import com.x.cms.core.entity.CategoryInfo;
 import com.x.cms.core.entity.element.AppDict;
 import com.x.cms.core.entity.element.File;
@@ -20,6 +17,10 @@ import com.x.cms.core.entity.element.Form;
 import com.x.cms.core.entity.element.Script;
 import com.x.cms.core.entity.element.wrap.*;
 
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
 class ActionList extends BaseAction {
 
 	ActionResult<List<Wo>> execute(EffectivePerson effectivePerson) throws Exception {
@@ -38,7 +39,14 @@ class ActionList extends BaseAction {
 			ListTools.groupStick(wos, scriptList, "id", "appId", "scriptList");
 			ListTools.groupStick(wos, appDictList, "id", "appId", "appDictList");
 			ListTools.groupStick(wos, fileList, AppInfo.id_FIELDNAME, File.appId_FIELDNAME, "fileList");
-			
+
+			//2020年1月16日 O2LEE 查询每个栏目信息对应的配置支持信息JSON以字符串形式放到WrapCms对象中输出 ---->start
+			Business business = new Business(emc);
+			for( Wo wo : wos ){
+				wo.setConfig(business.appInfoConfigFactory().getContent(wo.getId()));
+			}
+			//2020年1月16日 O2LEE 查询每个栏目信息对应的配置支持信息JSON以字符串形式放到WrapCms对象中输出 ---->end
+
 			wos = wos.stream()
 					.sorted(Comparator.comparing(Wo::getAppAlias, Comparator.nullsLast(String::compareTo))
 							.thenComparing(Wo::getAppName, Comparator.nullsLast(String::compareTo)))

+ 15 - 16
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/output/ActionSelect.java

@@ -1,14 +1,5 @@
 package com.x.cms.assemble.control.jaxrs.output;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.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;
@@ -22,16 +13,18 @@ import com.x.cms.assemble.control.Business;
 import com.x.cms.core.entity.AppInfo;
 import com.x.cms.core.entity.CategoryExt;
 import com.x.cms.core.entity.CategoryInfo;
-import com.x.cms.core.entity.element.AppDict;
-import com.x.cms.core.entity.element.AppDictItem;
-import com.x.cms.core.entity.element.AppDictItem_;
-import com.x.cms.core.entity.element.File;
-import com.x.cms.core.entity.element.Form;
-import com.x.cms.core.entity.element.Script;
+import com.x.cms.core.entity.element.*;
 import com.x.cms.core.entity.element.wrap.*;
-
 import net.sf.ehcache.Element;
 
+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 java.util.ArrayList;
+import java.util.List;
+
 class ActionSelect extends BaseAction {
 
 	ActionResult<Wo> execute(EffectivePerson effectivePerson, String appInfoFlag, JsonElement jsonElement)
@@ -50,6 +43,12 @@ class ActionSelect extends BaseAction {
 
 			WrapCms wrapAppInfo = this.get(business, appInfo, wi);
 
+			//2020年1月16日 O2LEE 查询栏目信息对应的配置支持信息JSON以字符串形式放到WrapCms对象中输出 ---->start
+			if( wrapAppInfo != null ){
+				wrapAppInfo.setConfig( business.appInfoConfigFactory().getContent( appInfo.getId() ) );
+			}
+			//2020年1月16日 O2LEE 查询每个栏目信息对应的配置支持信息JSON以字符串形式放到WrapCms对象中输出 ---->end
+
 			OutputCacheObject outputCacheObject = new OutputCacheObject();
 			outputCacheObject.setName(appInfo.getAppName());
 			outputCacheObject.setCmsAppInfo(wrapAppInfo);

+ 8 - 8
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/queue/QueueSendDocumentNotify.java

@@ -1,11 +1,4 @@
 package com.x.cms.assemble.control.queue;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.JpaObject;
@@ -22,6 +15,12 @@ import com.x.cms.assemble.control.service.UserManagerService;
 import com.x.cms.core.entity.AppInfo;
 import com.x.cms.core.entity.CategoryInfo;
 import com.x.cms.core.entity.Document;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
 
 /**
  * Document正式发布后,向所有的阅读者推送消息通知
@@ -97,8 +96,9 @@ public class QueueSendDocumentNotify extends AbstractQueue<Document> {
 				}
 				logger.info("cms send publish notify for new document completed! " );
 				//}
+			}else{
+				logger.info("can not send publish notify for document, category or  appinfo not exists! ID: " + document.getId() );
 			}
-			logger.info("can not send publish notify for document, category or  appinfo not exists! ID: " + document.getId() );
 		}
 	}
 

+ 89 - 19
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/service/AppInfoService.java

@@ -1,9 +1,5 @@
 package com.x.cms.assemble.control.service;
 
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.annotation.CheckPersistType;
@@ -11,14 +7,24 @@ import com.x.base.core.entity.annotation.CheckRemoveType;
 import com.x.base.core.project.tools.ListTools;
 import com.x.cms.assemble.control.Business;
 import com.x.cms.core.entity.AppInfo;
-import com.x.cms.core.entity.element.AppDict;
-import com.x.cms.core.entity.element.AppDictItem;
-import com.x.cms.core.entity.element.View;
-import com.x.cms.core.entity.element.ViewCategory;
-import com.x.cms.core.entity.element.ViewFieldConfig;
+import com.x.cms.core.entity.AppInfoConfig;
+import com.x.cms.core.entity.element.*;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
 
 public class AppInfoService {
 
+	public AppInfoConfig getConfigObject(EntityManagerContainer emc, String id ) throws Exception {
+		Business business = new Business( emc );
+		return business.appInfoConfigFactory().get(id);
+	}
+
+	public String getConfigJson(EntityManagerContainer emc, String id ) throws Exception {
+		Business business = new Business( emc );
+		return business.appInfoConfigFactory().getContent(id);
+	}
+
 	public List<String> listAllIds(EntityManagerContainer emc, String documentType ) throws Exception {
 		Business business = new Business( emc );
 		return business.getAppInfoFactory().listAllIds(documentType);
@@ -38,6 +44,7 @@ public class AppInfoService {
 		Business business = new Business( emc );
 		
 		emc.beginTransaction( AppInfo.class );
+		emc.beginTransaction( AppInfoConfig.class );
 		emc.beginTransaction( AppDict.class );
 		emc.beginTransaction( AppDictItem.class );
 		emc.beginTransaction( View.class );
@@ -101,7 +108,13 @@ public class AppInfoService {
 				
 			}
 		}
-	
+
+		//删除栏目配置支持信息
+		AppInfoConfig appInfoConfig = business.appInfoConfigFactory().get( id );
+		if( appInfoConfig != null ){
+			emc.remove( appInfoConfig, CheckRemoveType.all );
+		}
+
 		//删除栏目信息
 		appInfo = emc.find( id, AppInfo.class );
 		if( appInfo != null ){
@@ -128,20 +141,31 @@ public class AppInfoService {
 		Business business = new Business( emc );
 		return business.getCategoryInfoFactory().countByAppId( id, documentType );
 	}
-	
-	public AppInfo save( EntityManagerContainer emc, AppInfo wrapIn ) throws Exception {
+
+	/**
+	 * 新增或者更新栏目信息
+	 * @param emc
+	 * @param wrapIn
+	 * @param config
+	 * @return
+	 * @throws Exception
+	 */
+	public AppInfo save( EntityManagerContainer emc, AppInfo wrapIn, String config ) throws Exception {
 		AppInfo appInfo = null;
+		AppInfoConfig appInfoConfig = null;
 		if( wrapIn.getId() == null ){
 			wrapIn.setId( AppInfo.createId() );
 		}
-		appInfo = emc.find( wrapIn.getId(), AppInfo.class );		
+		appInfo = emc.find( wrapIn.getId(), AppInfo.class );
+		appInfoConfig = emc.find( wrapIn.getId(), AppInfoConfig.class );
+
+		emc.beginTransaction( AppInfo.class );
 		if( appInfo == null ){//新增一个栏目信息
 			appInfo = new AppInfo();
 			wrapIn.copyTo( appInfo );
 			if( StringUtils.isNotEmpty( wrapIn.getId() ) ){
 				appInfo.setId( wrapIn.getId() );
 			}
-			emc.beginTransaction( AppInfo.class );
 			if( StringUtils.isEmpty( appInfo.getAppAlias() )) {
 				appInfo.setAppAlias( appInfo.getAppName() );
 			}
@@ -149,23 +173,69 @@ public class AppInfoService {
 				appInfo.setAppType( "未分类" );
 			}
 			emc.persist( appInfo, CheckPersistType.all);
-			emc.commit();
 		}else{
 			wrapIn.copyTo(appInfo, JpaObject.FieldsUnmodify );
 			appInfo.setAppIcon( appInfo.getAppIcon() );
 			if( StringUtils.isEmpty( appInfo.getAppAlias() )) {
 				appInfo.setAppAlias( appInfo.getAppName() );
 			}
-			emc.beginTransaction( AppInfo.class );
 			if( StringUtils.isEmpty( appInfo.getAppType() )) {
 				appInfo.setAppType( "未分类" );
 			}
-			emc.check( appInfo, CheckPersistType.all );	
-			emc.commit();
-		}		
+			emc.check( appInfo, CheckPersistType.all );
+		}
+
+		emc.beginTransaction( AppInfoConfig.class );
+		if( appInfoConfig == null ){
+			appInfoConfig = new AppInfoConfig();
+			appInfoConfig.setId( appInfo.getId() );
+			appInfoConfig.setConfig( config );
+			emc.beginTransaction( AppInfoConfig.class );
+			emc.persist( appInfoConfig, CheckPersistType.all);
+		}else{
+			appInfoConfig.setConfig( config );
+			emc.beginTransaction( AppInfoConfig.class );
+			emc.check( appInfoConfig, CheckPersistType.all );
+		}
+
+		emc.commit();
 		return appInfo;
 	}
 
+	/**
+	 * 新增或者更新栏目配置支持信息
+	 * @param emc
+	 * @param appId
+	 * @param config
+	 * @return
+	 * @throws Exception
+	 */
+	public AppInfoConfig saveConfig( EntityManagerContainer emc, String appId, String config ) throws Exception {
+		AppInfo appInfo = null;
+		AppInfoConfig appInfoConfig = null;
+		appInfo = emc.find( appId, AppInfo.class );
+		appInfoConfig = emc.find( appId, AppInfoConfig.class );
+
+		if( appInfo == null ){//新增一个栏目信息
+			throw new Exception("appinfo not exists!id=" + appId );
+		}
+
+		emc.beginTransaction( AppInfoConfig.class );
+		if( appInfoConfig == null ){
+			appInfoConfig = new AppInfoConfig();
+			appInfoConfig.setId( appInfo.getId() );
+			appInfoConfig.setConfig( config );
+			emc.beginTransaction( AppInfoConfig.class );
+			emc.persist( appInfoConfig, CheckPersistType.all);
+		}else{
+			appInfoConfig.setConfig( config );
+			emc.beginTransaction( AppInfoConfig.class );
+			emc.check( appInfoConfig, CheckPersistType.all );
+		}
+		emc.commit();
+		return appInfoConfig;
+	}
+
 	public List<String> listByAppName( EntityManagerContainer emc, String appName) throws Exception {
 		if( StringUtils.isEmpty(appName ) ){
 			throw new Exception( "appName is null!" );

+ 70 - 18
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/service/AppInfoServiceAdv.java

@@ -1,15 +1,15 @@
 package com.x.cms.assemble.control.service;
 
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.tools.ListTools;
 import com.x.cms.core.entity.AppInfo;
+import com.x.cms.core.entity.AppInfoConfig;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
 
 /**
  * 对栏目信息进行管理的服务类(高级)
@@ -31,6 +31,28 @@ public class AppInfoServiceAdv {
 			throw e;
 		}
 	}
+
+	public AppInfoConfig getConfigObject(String id ) throws Exception {
+		if ( StringUtils.isEmpty(id )) {
+			throw new Exception("id is null.");
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return appInfoService.getConfigObject( emc, id );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	public String getConfigJson(String id ) throws Exception {
+		if ( StringUtils.isEmpty(id )) {
+			throw new Exception("id is null.");
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return appInfoService.getConfigJson( emc, id );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
 	
 	public AppInfo getWithFlag( String flag ) throws Exception {
 		if ( StringUtils.isEmpty( flag )) {
@@ -93,7 +115,15 @@ public class AppInfoServiceAdv {
 		}
 	}
 
-	public AppInfo save( AppInfo appInfo, EffectivePerson currentPerson) throws Exception {
+	/**
+	 * 栏目信息保存服务
+	 * @param appInfo
+	 * @param config
+	 * @param currentPerson
+	 * @return
+	 * @throws Exception
+	 */
+	public AppInfo save( AppInfo appInfo, String config, EffectivePerson currentPerson) throws Exception {
 		if ( appInfo == null) {
 			throw new Exception("appInfo is null.");
 		}
@@ -106,13 +136,27 @@ public class AppInfoServiceAdv {
 					appInfo.addManageablePerson( currentPerson.getDistinguishedName() );
 				}
 			}
-			appInfo = appInfoService.save( emc, appInfo );
+			appInfo = appInfoService.save( emc, appInfo, config );
 		} catch (Exception e) {
 			throw e;
 		}
 		return appInfo;
 	}
 
+	public AppInfoConfig saveConfig( String appId, String config, EffectivePerson currentPerson) throws Exception {
+		if ( StringUtils.isEmpty( appId )) {
+			throw new Exception("appId is null.");
+		}
+		if ( StringUtils.isEmpty( config )) {
+			throw new Exception("config content is null.");
+		}
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return appInfoService.saveConfig( emc, appId, config );
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
 	public List<String> listByAppName(String appName) throws Exception {
 		if ( StringUtils.isEmpty(appName )) {
 			return null;
@@ -290,14 +334,16 @@ public class AppInfoServiceAdv {
 			throw e;
 		}
 	}
-	
+
 
 	/**
 	 * 判断用户是否拥有指定栏目的发布者权限
 	 * @param appId
-	 * @param distinguishedName
+	 * @param personName
+	 * @param unitNames
+	 * @param groupNames
 	 * @return
-	 * @throws Exception 
+	 * @throws Exception
 	 */
 	public Boolean isAppInfoPublisher(String appId, String personName, List<String> unitNames, List<String> groupNames ) throws Exception {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
@@ -307,13 +353,15 @@ public class AppInfoServiceAdv {
 			throw e;
 		}
 	}
-	
+
 	/**
 	 * 判断用户是否拥有指定栏目的访问权限
 	 * @param appId
-	 * @param distinguishedName
+	 * @param personName
+	 * @param unitNames
+	 * @param groupNames
 	 * @return
-	 * @throws Exception 
+	 * @throws Exception
 	 */
 	public Boolean isAppInfoViewer(String appId, String personName, List<String> unitNames, List<String> groupNames ) throws Exception {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
@@ -353,13 +401,15 @@ public class AppInfoServiceAdv {
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 判断用户是否拥有指定栏目的发布者权限
 	 * @param appInfo
-	 * @param distinguishedName
+	 * @param personName
+	 * @param unitNames
+	 * @param groupNames
 	 * @return
-	 * @throws Exception 
+	 * @throws Exception
 	 */
 	public Boolean isAppInfoPublisher( AppInfo appInfo, String personName, List<String> unitNames, List<String> groupNames ) throws Exception {
 		if( appInfo != null )  {
@@ -399,13 +449,15 @@ public class AppInfoServiceAdv {
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 判断用户是否拥有指定栏目的访问权限
 	 * @param appInfo
-	 * @param distinguishedName
+	 * @param personName
+	 * @param unitNames
+	 * @param groupNames
 	 * @return
-	 * @throws Exception 
+	 * @throws Exception
 	 */
 	public Boolean isAppInfoViewer( AppInfo appInfo, String personName, List<String> unitNames, List<String> groupNames ) throws Exception {
 		if( appInfo != null ) {

+ 72 - 0
o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/AppInfoConfig.java

@@ -0,0 +1,72 @@
+package com.x.cms.core.entity;
+
+import com.alibaba.druid.util.StringUtils;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.SliceJpaObject;
+import com.x.base.core.entity.annotation.ContainerEntity;
+import com.x.base.core.project.annotation.FieldDescribe;
+
+import javax.persistence.*;
+
+/**
+ * 内容管理栏目配置支持信息
+ * 
+ * @author O2LEE
+ *
+ */
+@ContainerEntity
+@Entity
+@Table(name = PersistenceProperties.AppInfoConfig.table, uniqueConstraints = {
+		@UniqueConstraint(name = PersistenceProperties.AppInfoConfig.table + JpaObject.IndexNameMiddle
+				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
+						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class AppInfoConfig extends SliceJpaObject {
+
+	private static final long serialVersionUID = 3856138316794473794L;
+	@SuppressWarnings("unused")
+	private static final String TABLE = PersistenceProperties.AppInfoConfig.table;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@FieldDescribe("数据库主键,自动生成.")
+	@Id
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
+	private String id = createId();
+
+	public void onPersist() throws Exception {
+	}
+	/*
+	 * =============================================================================
+	 * ===== 以上为 JpaObject 默认字段
+	 * =============================================================================
+	 * =====
+	 */
+
+	/*
+	 * =============================================================================
+	 * ===== 以下为具体不同的业务及数据表字段要求
+	 * =============================================================================
+	 * =====
+	 */
+	public static final String config_FIELDNAME = "config";
+	@FieldDescribe("配置支持信息JSON内容")
+	@Lob
+	@Basic(fetch = FetchType.EAGER)
+	@Column(length = JpaObject.length_1M, name = ColumnNamePrefix + config_FIELDNAME)
+	private String config;
+
+	public String getConfig() {
+		return StringUtils.isEmpty( config ) ? "{}" : config;
+	}
+
+	public void setConfig(String config) {
+		this.config = config;
+	}
+}

+ 5 - 1
o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/PersistenceProperties.java

@@ -43,7 +43,11 @@ public final class PersistenceProperties extends AbstractPersistenceProperties {
 	public static class AppInfo {
 		public static final String table = "CMS_APPINFO";
 	}
-	
+
+	public static class AppInfoConfig {
+		public static final String table = "CMS_APPINFO_CONFIG";
+	}
+
 	public static class CategoryInfo {
 		public static final String table = "CMS_CATEGORYINFO";
 	}

+ 12 - 5
o2server/x_cms_core_entity/src/main/java/com/x/cms/core/entity/element/wrap/WrapCms.java

@@ -1,8 +1,5 @@
 package com.x.cms.core.entity.element.wrap;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.bean.WrapCopier;
@@ -10,6 +7,9 @@ import com.x.base.core.project.bean.WrapCopierFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.cms.core.entity.AppInfo;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class WrapCms extends AppInfo {
 
 	private static final long serialVersionUID = 1863166064194774704L;
@@ -53,8 +53,15 @@ public class WrapCms extends AppInfo {
 	private List<WrapScript> scriptList = new ArrayList<>();
 	
 	@FieldDescribe("导出的文件")
-	private List<WrapFile> fileList = new ArrayList<>();	
-	
+	private List<WrapFile> fileList = new ArrayList<>();
+
+	@FieldDescribe("导出的栏目配置支持信息,JSON配置项")
+	private String config = "{}";
+
+	public String getConfig() { return this.config; }
+
+	public void setConfig(final String config) { this.config = config; }
+
 	public List<WrapForm> getFormList() {
 		return formList;
 	}

+ 2 - 0
o2server/x_console/src/main/java/com/x/server/console/ResourceFactory.java

@@ -108,6 +108,8 @@ public class ResourceFactory {
 			dataSource.setPassword(ds.getPassword());
 			dataSource.setMaxPoolSize(ds.getMaxTotal());
 			dataSource.setMinPoolSize(ds.getMaxIdle());
+			/* 增加校验 */
+			dataSource.setTestConnectionOnCheckin(true);
 			dataSource.setAcquireIncrement(0);
 			if (ds.getStatEnable()) {
 				dataSource.setFilters(ds.getStatFilter());

+ 1 - 1
o2server/x_jpush_assemble_control/src/main/java/com/x/jpush/assemble/control/jaxrs/message/ActionSendMessage.java

@@ -105,7 +105,7 @@ public class ActionSendMessage  extends StandardJaxrsAction {
 
 
 
-        @FieldDescribe("设备id")
+        @FieldDescribe("人员")
         private String person;
 
         @FieldDescribe("消息内容")

+ 114 - 1
o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/DingdingConsumeQueue.java

@@ -1,5 +1,7 @@
 package com.x.message.assemble.communicate;
 
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.project.config.Config;
@@ -7,9 +9,15 @@ import com.x.base.core.project.connection.HttpConnection;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.message.DingdingMessage;
+import com.x.base.core.project.message.MessageConnector;
 import com.x.base.core.project.queue.AbstractQueue;
+import com.x.base.core.project.tools.DefaultCharset;
 import com.x.message.core.entity.Message;
 
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
 public class DingdingConsumeQueue extends AbstractQueue<Message> {
 
 	private static Logger logger = LoggerFactory.getLogger(DingdingConsumeQueue.class);
@@ -22,7 +30,20 @@ public class DingdingConsumeQueue extends AbstractQueue<Message> {
 				DingdingMessage m = new DingdingMessage();
 				m.setAgent_id(Long.parseLong(Config.dingding().getAgentId(), 10));
 				m.setUserid_list(business.organization().person().getObject(message.getPerson()).getDingdingId());
-				m.getMsg().getText().setContent(message.getTitle());
+
+				if (needTransferLink(message.getType())) {
+					String workUrl = getDingdingOpenWorkUrl(message.getBody());
+					if (workUrl != null && !"".equals(workUrl)) {
+						m.getMsg().setMsgtype("markdown");
+						m.getMsg().getMarkdown().setTitle(message.getTitle());
+						m.getMsg().getMarkdown().setText("["+message.getTitle()+"]("+workUrl+")");
+					}else {
+						m.getMsg().getText().setContent(message.getTitle());
+					}
+				}else {
+					m.getMsg().getText().setContent(message.getTitle());
+				}
+
 				// https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=ACCESS_TOKEN
 				String address = Config.dingding().getOapiAddress()
 						+ "/topapi/message/corpconversation/asyncsend_v2?access_token="
@@ -44,6 +65,98 @@ public class DingdingConsumeQueue extends AbstractQueue<Message> {
 		}
 	}
 
+
+	/**
+	 * 生成单点登录和打开工作的地址
+	 * @param messageBody
+	 * @return
+	 */
+	private String getDingdingOpenWorkUrl(String messageBody) {
+		try {
+			String work = getWorkIdFromBody(messageBody);
+			String o2oaUrl = Config.dingding().getWorkUrl();
+			if (work == null || "".equals(work) || o2oaUrl == null || "".equals(o2oaUrl)) {
+				return null;
+			}
+
+			String workUrl = "workmobilewithaction.html?workid=" + work;
+			String messageRedirectPortal = Config.dingding().getMessageRedirectPortal();
+			if (messageRedirectPortal != null && !"".equals(messageRedirectPortal)) {
+				String portal = "portalmobile.html?id="+messageRedirectPortal;
+				portal = URLEncoder.encode(portal, DefaultCharset.name);
+				workUrl += "&redirectlink=" + portal;
+			}
+			workUrl = URLEncoder.encode(workUrl, DefaultCharset.name);
+			logger.info("o2oa workUrl:"+workUrl);
+			o2oaUrl = o2oaUrl + "ddsso.html?redirect=" + workUrl;
+			logger.info("o2oa 地址:"+o2oaUrl);
+			return o2oaUrl;
+		}catch (Exception e) {
+			logger.error(e);
+		}
+
+		return "";
+	}
+
+	/**
+	 * 获取workid
+	 * @param messageBody
+	 * @return
+	 */
+	private String getWorkIdFromBody(String messageBody) {
+		try {
+			JsonObject object =new JsonParser().parse(messageBody).getAsJsonObject();
+			return object.get("work").getAsString();
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return "";
+	}
+
+	/**
+	 * 是否需要把钉钉消息转成markdown格式消息
+	 * 根据是否配置了钉钉工作链接、是否是工作消息(目前只支持工作消息)
+	 * @param messageType 消息类型 判断是否是工作消息
+	 * @return
+	 */
+	private boolean needTransferLink(String messageType) {
+		try {
+			String workUrl = Config.dingding().getWorkUrl();
+			if (workUrl != null && !"".equals(workUrl) && workMessageTypeList().contains(messageType)) {
+				return true;
+			}
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return false;
+	}
+
+	private List<String> workMessageTypeList() {
+		List<String> list = new ArrayList<>();
+		list.add(MessageConnector.TYPE_WORK_TO_WORKCOMPLETED);
+		list.add(MessageConnector.TYPE_WORK_CREATE);
+		list.add(MessageConnector.TYPE_WORK_DELETE);
+		list.add(MessageConnector.TYPE_WORKCOMPLETED_CREATE);
+		list.add(MessageConnector.TYPE_WORKCOMPLETED_DELETE);
+		list.add(MessageConnector.TYPE_TASK_TO_TASKCOMPLETED);
+		list.add(MessageConnector.TYPE_TASK_CREATE);
+		list.add(MessageConnector.TYPE_TASK_DELETE);
+		list.add(MessageConnector.TYPE_TASK_URGE);
+		list.add(MessageConnector.TYPE_TASK_EXPIRE);
+		list.add(MessageConnector.TYPE_TASK_PRESS);
+		list.add(MessageConnector.TYPE_TASKCOMPLETED_CREATE);
+		list.add(MessageConnector.TYPE_TASKCOMPLETED_DELETE);
+		list.add(MessageConnector.TYPE_READ_TO_READCOMPLETED);
+		list.add(MessageConnector.TYPE_READ_CREATE);
+		list.add(MessageConnector.TYPE_READ_DELETE);
+		list.add(MessageConnector.TYPE_READCOMPLETED_CREATE);
+		list.add(MessageConnector.TYPE_READCOMPLETED_DELETE);
+		list.add(MessageConnector.TYPE_REVIEW_CREATE);
+		list.add(MessageConnector.TYPE_REVIEW_DELETE);
+
+		return list;
+	}
+
 	public static class DingdingMessageResp {
 
 		private Integer errcode;

+ 144 - 1
o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/QiyeweixinConsumeQueue.java

@@ -1,15 +1,22 @@
 package com.x.message.assemble.communicate;
 
+import com.google.gson.*;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.project.config.Config;
 import com.x.base.core.project.connection.HttpConnection;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.message.MessageConnector;
 import com.x.base.core.project.message.QiyeweixinMessage;
 import com.x.base.core.project.queue.AbstractQueue;
+import com.x.base.core.project.tools.DefaultCharset;
 import com.x.message.core.entity.Message;
 
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
 public class QiyeweixinConsumeQueue extends AbstractQueue<Message> {
 
 	private static Logger logger = LoggerFactory.getLogger(QiyeweixinConsumeQueue.class);
@@ -22,7 +29,15 @@ public class QiyeweixinConsumeQueue extends AbstractQueue<Message> {
 				QiyeweixinMessage m = new QiyeweixinMessage();
 				m.setAgentid(Long.parseLong(Config.qiyeweixin().getAgentId(), 10));
 				m.setTouser(business.organization().person().getObject(message.getPerson()).getQiyeweixinId());
-				m.getText().setContent(message.getTitle());
+				String content = message.getTitle();
+				if (needTransferLink(message.getType())) {
+					String workUrl = getQywxOpenWorkUrl(message.getBody());
+					if (workUrl != null && !"".equals(workUrl)) {
+						content = "<a href=\"" + workUrl +"\">" + message.getTitle() + "</a>";
+					}
+				}
+				m.getText().setContent(content);
+				logger.info("微信消息:"+m.toString());
 				String address = Config.qiyeweixin().getApiAddress() + "/cgi-bin/message/send?access_token="
 						+ Config.qiyeweixin().corpAccessToken();
 				QiyeweixinMessageResp resp = HttpConnection.postAsObject(address, null, m.toString(),
@@ -42,6 +57,134 @@ public class QiyeweixinConsumeQueue extends AbstractQueue<Message> {
 		}
 	}
 
+	/**
+	 * 生成单点登录和打开工作的地址
+	 * @param messageBody
+	 * @return
+	 */
+	private String getQywxOpenWorkUrl(String messageBody) {
+		try {
+			String work = getWorkIdFromBody(messageBody);
+			String o2oaUrl = Config.qiyeweixin().getWorkUrl();
+			String corpId = Config.qiyeweixin().getCorpId();
+			String agentId = Config.qiyeweixin().getAgentId();
+			if (work == null || "".equals(work) || o2oaUrl == null || "".equals(o2oaUrl) || corpId == null
+			 || "".equals(corpId) || agentId == null || "".equals(agentId)) {
+				return null;
+			}
+			String workUrl = "workmobilewithaction.html?workid=" + work;
+			String messageRedirectPortal = Config.qiyeweixin().getMessageRedirectPortal();
+			if (messageRedirectPortal != null && !"".equals(messageRedirectPortal)) {
+				String portal = "portalmobile.html?id="+messageRedirectPortal;
+				portal = URLEncoder.encode(portal, DefaultCharset.name);
+				workUrl += "&redirectlink=" + portal;
+			}
+			workUrl = URLEncoder.encode(workUrl, DefaultCharset.name);
+			o2oaUrl = o2oaUrl+"qiyeweixinsso.html?redirect="+workUrl;
+			logger.info("o2oa 地址:"+o2oaUrl);
+			o2oaUrl = URLEncoder.encode(o2oaUrl, DefaultCharset.name);
+			logger.info("encode url :"+o2oaUrl);
+			String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+corpId
+					+"&response_type=code&scope=snsapi_base"
+					+"&agentid="+agentId
+					+"&redirect_uri="+o2oaUrl
+					+"&#wechat_redirect" ;
+			logger.info("final url :" +url);
+			return url;
+		}catch (Exception e) {
+			logger.error(e);
+		}
+
+		return "";
+	}
+
+	/**
+	 * 获取workid
+	 * @param messageBody
+	 * @return
+	 */
+	private String getWorkIdFromBody(String messageBody) {
+		try {
+			JsonObject object =new JsonParser().parse(messageBody).getAsJsonObject();
+			return object.get("work").getAsString();
+//			if (messageType.startsWith("task_")) {
+//				JsonObject object =new JsonParser().parse(messageBody).getAsJsonObject();
+//				return object.get("work").getAsString();
+//			}else if (messageType.startsWith("taskCompleted_")) {
+//				JsonObject object =new JsonParser().parse(messageBody).getAsJsonObject();
+//				String work =  object.get("work").getAsString();
+//				String workCompleted = object.get("workCompleted").getAsString();
+//				if (workCompleted != null && !"".equals(workCompleted)) {
+//					return  workCompleted;
+//				}else {
+//					return work;
+//				}
+//			}else if (messageType.startsWith("read_")) {
+//				JsonObject object =new JsonParser().parse(messageBody).getAsJsonObject();
+//				return object.get("work").getAsString();
+//			}else if (messageType.startsWith("readCompleted_")) {
+//				JsonObject object =new JsonParser().parse(messageBody).getAsJsonObject();
+//				String work =  object.get("work").getAsString();
+//				String workCompleted = object.get("workCompleted").getAsString();
+//				if (workCompleted != null && !"".equals(workCompleted)) {
+//					return  workCompleted;
+//				}else {
+//					return work;
+//				}
+//			}else if (messageType.startsWith("review_")) {
+//				JsonObject object =new JsonParser().parse(messageBody).getAsJsonObject();
+//				return object.get("work").getAsString();
+//			}
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return "";
+	}
+
+	/**
+	 * 是否需要把企业微信消息转成超链接消息
+	 * 根据是否配置了企业微信应用链接、是否是工作消息(目前只支持工作消息)
+	 * @param messageType 消息类型 判断是否是工作消息
+	 * @return
+	 */
+	private boolean needTransferLink(String messageType) {
+		try {
+			String workUrl = Config.qiyeweixin().getWorkUrl();
+			if (workUrl != null && !"".equals(workUrl) && workMessageTypeList().contains(messageType)) {
+				return true;
+			}
+		} catch (Exception e) {
+			logger.error(e);
+		}
+		return false;
+	}
+
+	private List<String> workMessageTypeList() {
+		List<String> list = new ArrayList<>();
+		list.add(MessageConnector.TYPE_WORK_TO_WORKCOMPLETED);
+		list.add(MessageConnector.TYPE_WORK_CREATE);
+		list.add(MessageConnector.TYPE_WORK_DELETE);
+		list.add(MessageConnector.TYPE_WORKCOMPLETED_CREATE);
+		list.add(MessageConnector.TYPE_WORKCOMPLETED_DELETE);
+		list.add(MessageConnector.TYPE_TASK_TO_TASKCOMPLETED);
+		list.add(MessageConnector.TYPE_TASK_CREATE);
+		list.add(MessageConnector.TYPE_TASK_DELETE);
+		list.add(MessageConnector.TYPE_TASK_URGE);
+		list.add(MessageConnector.TYPE_TASK_EXPIRE);
+		list.add(MessageConnector.TYPE_TASK_PRESS);
+		list.add(MessageConnector.TYPE_TASKCOMPLETED_CREATE);
+		list.add(MessageConnector.TYPE_TASKCOMPLETED_DELETE);
+		list.add(MessageConnector.TYPE_READ_TO_READCOMPLETED);
+		list.add(MessageConnector.TYPE_READ_CREATE);
+		list.add(MessageConnector.TYPE_READ_DELETE);
+		list.add(MessageConnector.TYPE_READCOMPLETED_CREATE);
+		list.add(MessageConnector.TYPE_READCOMPLETED_DELETE);
+		list.add(MessageConnector.TYPE_REVIEW_CREATE);
+		list.add(MessageConnector.TYPE_REVIEW_DELETE);
+
+		return list;
+	}
+
 	public static class QiyeweixinMessageResp {
 
 		// {

+ 65 - 14
o2server/x_message_assemble_communicate/src/main/java/com/x/message/assemble/communicate/jaxrs/connector/ActionCreate.java

@@ -1,29 +1,40 @@
 package com.x.message.assemble.communicate.jaxrs.connector;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.project.config.Config;
+import com.x.base.core.project.gson.XGsonBuilder;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WrapBoolean;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.message.MessageConnector;
+import com.x.base.core.project.script.ScriptFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.message.assemble.communicate.Business;
 import com.x.message.assemble.communicate.ThisApplication;
 import com.x.message.core.entity.Instant;
 import com.x.message.core.entity.Message;
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.script.Bindings;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.SimpleScriptContext;
 
 class ActionCreate extends BaseAction {
 
 	private static Logger logger = LoggerFactory.getLogger(ActionCreate.class);
+	private static ConcurrentMap<String,CompiledScript> scriptMap = new ConcurrentHashMap<>();
 
 	ActionResult<Wo> execute(EffectivePerson effectivePerson, JsonElement jsonElement) throws Exception {
 		List<Message> messages = new ArrayList<>();
@@ -32,34 +43,74 @@ class ActionCreate extends BaseAction {
 			Business business = new Business(emc);
 			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
 			List<String> consumers = Config.messages().getConsumers(wi.getType());
-			Instant instant = this.instant(effectivePerson, business, wi, consumers);
-			if (ListTools.isNotEmpty(consumers)) {
-				for (String consumer : consumers) {
+			Map<String,String> consumersV2 = Config.messages().getConsumersV2(wi.getType());
+			for(String consumer: consumers){
+				if(!consumersV2.containsKey(consumer)){
+					consumersV2.put(consumer,"");
+				}
+			}
+			Instant instant = this.instant(effectivePerson, business, wi, new ArrayList<>(consumersV2.keySet()));
+			if (!consumersV2.isEmpty()) {
+				for (String consumer : consumersV2.keySet()) {
+					Wi cpwi = wi;
+					String func = consumersV2.get(consumer);
+					try {
+						if(StringUtils.isNoneBlank(func)){
+							cpwi = (Wi)BeanUtils.cloneBean(wi);
+							JsonObject body = cpwi.getBody().deepCopy().getAsJsonObject();
+							CompiledScript compiledScript = scriptMap.get(func);
+							if(compiledScript == null) {
+								String eval = Config.messageSendRuleScript();
+								if(StringUtils.isNotEmpty(eval)) {
+									eval = "function" + StringUtils.substringAfter(eval, "function") + " " + func + "();";
+									compiledScript = ScriptFactory.compile(eval);
+									scriptMap.put(func, compiledScript);
+								}
+							}
+							if(compiledScript != null) {
+								ScriptContext scriptContext = new SimpleScriptContext();
+								Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
+								bindings.put("body", body);
+								Object o = compiledScript.eval(scriptContext);
+								cpwi.setBody(body);
+								if (o != null) {
+									if (o instanceof Boolean) {
+										if (!((Boolean) o).booleanValue()) {
+											logger.info("消息类型{}.{}的消息[{}]不满足发送条件,跳过...", wi.getType(), consumer, wi.getTitle());
+											continue;
+										}
+									}
+								}
+							}
+						}
+					} catch (Exception e) {
+						logger.warn("执行消息发送脚本[{}]方法异常:{}", func, e.getMessage());
+					}
 					Message message = null;
 					switch (Objects.toString(consumer, "")) {
 					case MessageConnector.CONSUME_WS:
-						message = this.wsMessage(effectivePerson, business, wi, instant);
+						message = this.wsMessage(effectivePerson, business, cpwi, instant);
 						break;
 					case MessageConnector.CONSUME_PMS:
-						message = this.pmsMessage(effectivePerson, business, wi, instant);
+						message = this.pmsMessage(effectivePerson, business, cpwi, instant);
 						break;
 					case MessageConnector.CONSUME_PMS_INNER:
-						message = this.pmsInnerMessage(effectivePerson, business, wi, instant);
+						message = this.pmsInnerMessage(effectivePerson, business, cpwi, instant);
 						break;
 					case MessageConnector.CONSUME_DINGDING:
-						message = this.dingdingMessage(effectivePerson, business, wi, instant);
+						message = this.dingdingMessage(effectivePerson, business, cpwi, instant);
 						break;
 					case MessageConnector.CONSUME_ZHENGWUDINGDING:
-						message = this.zhegnwudingdingMessage(effectivePerson, business, wi, instant);
+						message = this.zhegnwudingdingMessage(effectivePerson, business, cpwi, instant);
 						break;
 					case MessageConnector.CONSUME_QIYEWEIXIN:
-						message = this.qiyeweixinMessage(effectivePerson, business, wi, instant);
+						message = this.qiyeweixinMessage(effectivePerson, business, cpwi, instant);
 						break;
 					case MessageConnector.CONSUME_CALENDAR:
-						message = this.calendarMessage(effectivePerson, business, wi, instant);
+						message = this.calendarMessage(effectivePerson, business, cpwi, instant);
 						break;
 					default:
-						message = this.defaultMessage(effectivePerson, business, wi, consumer, instant);
+						message = this.defaultMessage(effectivePerson, business, cpwi, consumer, instant);
 						break;
 					}
 					messages.add(message);

+ 25 - 0
o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthDingdingConfig.java

@@ -0,0 +1,25 @@
+package com.x.organization.assemble.authentication.jaxrs.authentication;
+
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.config.Dingding;
+import com.x.base.core.project.config.Qiyeweixin;
+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;
+
+public class ActionOauthDingdingConfig extends BaseAction {
+
+    private static Logger logger = LoggerFactory.getLogger(ActionOauthDingdingConfig.class);
+
+    ActionResult<Dingding> execute(EffectivePerson effectivePerson) throws Exception {
+        ActionResult<Dingding> result = new ActionResult<>();
+        if (Config.dingding().getScanLoginEnable()) {
+            result.setData(Config.dingding());
+            return result;
+        }
+        return result;
+    }
+
+
+}

+ 142 - 0
o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthDingdingLogin.java

@@ -0,0 +1,142 @@
+package com.x.organization.assemble.authentication.jaxrs.authentication;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.connection.HttpConnection;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Audit;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.organization.assemble.authentication.Business;
+import com.x.organization.core.entity.Person;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Date;
+
+public class ActionOauthDingdingLogin extends BaseAction {
+    private static Logger logger = LoggerFactory.getLogger(ActionOauthDingdingLogin.class);
+
+
+    ActionResult<ActionOauthDingdingLogin.Wo> execute(HttpServletRequest request, HttpServletResponse response,
+                                                      EffectivePerson effectivePerson, String code) throws Exception {
+        try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+            Audit audit = logger.audit(effectivePerson);
+            ActionResult<ActionOauthDingdingLogin.Wo> result = new ActionResult<>();
+            Business business = new Business(emc);
+
+            //请求钉钉用户信息地址
+            String url = "https://oapi.dingtalk.com/sns/getuserinfo_bycode";
+
+            //请求参数 签名
+            String timestamp = new Date().getTime()+"";
+            Mac mac = Mac.getInstance("HmacSHA256");
+            String appSecret = Config.dingding().getScanLoginAppSecret();
+            mac.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256"));
+            byte[] signatureBytes = mac.doFinal(timestamp.getBytes("UTF-8"));
+            String signature = new String(Base64.encodeBase64(signatureBytes));
+            String urlEncodeSignature = urlEncode(signature, "utf-8");
+            url += "?accessKey="+Config.dingding().getScanLoginAppId()+"&timestamp="+timestamp+"&signature="+urlEncodeSignature;
+            String str = HttpConnection.postAsString(url, null, "{\"tmp_auth_code\":\""+code+"\"}");
+            JsonElement jsonElement = getDingJsonData(str);
+            JsonObject userInfo = jsonElement.getAsJsonObject().get("user_info").getAsJsonObject();
+            String unionid = userInfo.get("unionid").getAsString();
+            //通过unionid获取用户userId https://oapi.dingtalk.com/user/getUseridByUnionid?access_token=ACCESS_TOKEN&unionid=xxx
+            String getDingUserIdUrl = "https://oapi.dingtalk.com/user/getUseridByUnionid?access_token="+Config.dingding().corpAccessToken()+"&unionid="+unionid;
+            String dingUserBackString = HttpConnection.getAsString(getDingUserIdUrl, null);
+            JsonElement dingBackJsonElement = getDingJsonData(dingUserBackString);
+            String userid = dingBackJsonElement.getAsJsonObject().get("userid").getAsString();
+            logger.info("credential:{}", userid);
+            if (StringUtils.isEmpty(userid)) {
+                throw new ExceptionOauthEmptyCredential();
+            }
+            Wo wo = new Wo();
+            if (Config.token().isInitialManager(userid)) {
+                wo = this.manager(request, response, business, Wo.class);
+            } else {
+                /* 普通用户登录,也有可能拥有管理员角色 */
+                String personId = business.person().getWithCredential(userid);
+                if (StringUtils.isEmpty(personId)) {
+                    throw new ExceptionPersonNotExistOrInvalidPassword();
+                }
+                Person o = emc.find(personId, Person.class);
+                wo = this.user(request, response, business, o, Wo.class);
+                audit.log(o.getDistinguishedName(), "登录");
+            }
+            result.setData(wo);
+            return result;
+        }
+
+
+
+    }
+
+    private JsonElement getDingJsonData(String dingUserBackString) throws ExceptionOauthDingdingErrorInfo {
+        logger.info("钉钉获取用户 return:{}", dingUserBackString);
+        JsonElement dingBackJsonElement = gson.fromJson(dingUserBackString, JsonElement.class);
+        int errCode2 = dingBackJsonElement.getAsJsonObject().get("errcode").getAsInt();
+        String errMsg2 = dingBackJsonElement.getAsJsonObject().get("errmsg").getAsString();
+        if (errCode2 > 0) {
+            throw new ExceptionOauthDingdingErrorInfo(errMsg2);
+        }
+        return dingBackJsonElement;
+    }
+
+    // encoding参数使用utf-8
+    private String urlEncode(String value, String encoding) {
+        if (value == null) {
+            return "";
+        }
+        try {
+            String encoded = URLEncoder.encode(value, encoding);
+            return encoded.replace("+", "%20").replace("*", "%2A")
+                    .replace("~", "%7E").replace("/", "%2F");
+        } catch (UnsupportedEncodingException e) {
+            throw new IllegalArgumentException("FailedToEncodeUri", e);
+        }
+    }
+
+    public static class Wo extends AbstractWoAuthentication {
+
+        private static final long serialVersionUID = -1473824515272368422L;
+
+        private String url;
+        private String method;
+        private String parameter;
+
+        public String getUrl() {
+            return url;
+        }
+
+        public void setUrl(String url) {
+            this.url = url;
+        }
+
+        public String getMethod() {
+            return method;
+        }
+
+        public void setMethod(String method) {
+            this.method = method;
+        }
+
+        public String getParameter() {
+            return parameter;
+        }
+
+        public void setParameter(String parameter) {
+            this.parameter = parameter;
+        }
+    }
+
+}

+ 18 - 0
o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthList.java

@@ -3,6 +3,8 @@ package com.x.organization.assemble.authentication.jaxrs.authentication;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.x.base.core.project.config.Dingding;
+import com.x.base.core.project.config.Qiyeweixin;
 import org.apache.commons.lang3.BooleanUtils;
 
 import com.x.base.core.project.config.Config;
@@ -38,6 +40,22 @@ class ActionOauthList extends BaseAction {
 				}
 			}
 		}
+		//企业微信扫码登录
+		if (Config.qiyeweixin().getScanLoginEnable()) {
+			Wo wo = new Wo();
+			wo.setName("企业微信");
+			wo.setDisplayName("@O2企业微信");
+			wo.setIcon(Qiyeweixin.qywxLogo);
+			wos.add(wo);
+		}
+		//钉钉扫码登录
+		if (Config.dingding().getScanLoginEnable()) {
+			Wo wo = new Wo();
+			wo.setName("钉钉");
+			wo.setIcon(Dingding.dingdingLogo);
+			wo.setDisplayName("@O2钉钉");
+			wos.add(wo);
+		}
 		result.setData(wos);
 		return result;
 	}

+ 25 - 0
o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthQiyeweixinConfig.java

@@ -0,0 +1,25 @@
+package com.x.organization.assemble.authentication.jaxrs.authentication;
+
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.config.Qiyeweixin;
+
+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;
+
+public class ActionOauthQiyeweixinConfig extends BaseAction {
+
+    private static Logger logger = LoggerFactory.getLogger(ActionOauthQiyeweixinConfig.class);
+
+    ActionResult<Qiyeweixin> execute(EffectivePerson effectivePerson) throws Exception {
+        ActionResult<Qiyeweixin> result = new ActionResult<>();
+        if (Config.qiyeweixin().getScanLoginEnable()) {
+            result.setData(Config.qiyeweixin());
+            return result;
+        }
+        return result;
+    }
+
+
+}

+ 94 - 0
o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ActionOauthQiyeweixinLogin.java

@@ -0,0 +1,94 @@
+package com.x.organization.assemble.authentication.jaxrs.authentication;
+
+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.config.Config;
+import com.x.base.core.project.connection.HttpConnection;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Audit;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.organization.assemble.authentication.Business;
+import com.x.organization.core.entity.Person;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class ActionOauthQiyeweixinLogin extends BaseAction {
+    private static Logger logger = LoggerFactory.getLogger(ActionOauthQiyeweixinLogin.class);
+
+
+    ActionResult<ActionOauthQiyeweixinLogin.Wo> execute(HttpServletRequest request, HttpServletResponse response,
+                                                        EffectivePerson effectivePerson, String code) throws Exception {
+        try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+            Audit audit = logger.audit(effectivePerson);
+            ActionResult<ActionOauthQiyeweixinLogin.Wo> result = new ActionResult<>();
+            Business business = new Business(emc);
+
+            String url = Config.qiyeweixin().getApiAddress() + "/cgi-bin/user/getuserinfo?access_token="
+                    + Config.qiyeweixin().corpAccessToken() + "&code=" + code;
+            String str = HttpConnection.getAsString(url, null);
+            logger.debug("企业微信获取用户 return:{}", str);
+            JsonElement jsonElement = gson.fromJson(str, JsonElement.class);
+            String userId = jsonElement.getAsJsonObject().get("UserId").getAsString();
+
+            logger.info("credential:{}", userId);
+            if (StringUtils.isEmpty(userId)) {
+                throw new ExceptionOauthEmptyCredential();
+            }
+            Wo wo = new Wo();
+            if (Config.token().isInitialManager(userId)) {
+                wo = this.manager(request, response, business, Wo.class);
+            } else {
+                /* 普通用户登录,也有可能拥有管理员角色 */
+                String personId = business.person().getWithCredential(userId);
+                if (StringUtils.isEmpty(personId)) {
+                    throw new ExceptionPersonNotExistOrInvalidPassword();
+                }
+                Person o = emc.find(personId, Person.class);
+                wo = this.user(request, response, business, o, Wo.class);
+                audit.log(o.getDistinguishedName(), "登录");
+            }
+            result.setData(wo);
+            return result;
+        }
+
+    }
+
+    public static class Wo extends AbstractWoAuthentication {
+
+        private static final long serialVersionUID = -1473824515272368422L;
+
+        private String url;
+        private String method;
+        private String parameter;
+
+        public String getUrl() {
+            return url;
+        }
+
+        public void setUrl(String url) {
+            this.url = url;
+        }
+
+        public String getMethod() {
+            return method;
+        }
+
+        public void setMethod(String method) {
+            this.method = method;
+        }
+
+        public String getParameter() {
+            return parameter;
+        }
+
+        public void setParameter(String parameter) {
+            this.parameter = parameter;
+        }
+    }
+
+}

+ 76 - 0
o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/AuthenticationAction.java

@@ -20,6 +20,8 @@ import com.google.gson.JsonElement;
 import com.x.base.core.project.annotation.JaxrsDescribe;
 import com.x.base.core.project.annotation.JaxrsMethodDescribe;
 import com.x.base.core.project.annotation.JaxrsParameterDescribe;
+import com.x.base.core.project.config.Dingding;
+import com.x.base.core.project.config.Qiyeweixin;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.HttpMediaType;
@@ -263,6 +265,40 @@ public class AuthenticationAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 	}
 
+	@JaxrsMethodDescribe(value = "企业微信oauth登录认证配置", action = ActionOauthQiyeweixinConfig.class)
+	@GET
+	@Path("oauth/qywx/config")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void qiyeweixinOauthConfig(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request) {
+		ActionResult<Qiyeweixin> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionOauthQiyeweixinConfig().execute(effectivePerson);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+	@JaxrsMethodDescribe(value = "钉钉oauth登录认证配置", action = ActionOauthDingdingConfig.class)
+	@GET
+	@Path("oauth/dingding/config")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void dingdingOauthConfig(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request) {
+		ActionResult<Dingding> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionOauthDingdingConfig().execute(effectivePerson);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
 	@JaxrsMethodDescribe(value = "oauth登录认证地址", action = ActionOauthGet.class)
 	@GET
 	@Path("oauth/name/{name}")
@@ -302,6 +338,46 @@ public class AuthenticationAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 	}
 
+	@JaxrsMethodDescribe(value = "企业微信oauth登录", action = ActionOauthQiyeweixinLogin.class)
+	@GET
+	@Path("oauth/login/qywx/code/{code}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void oauthLoginQywx(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+						   @Context HttpServletResponse response,
+						   @JaxrsParameterDescribe("code") @PathParam("code") String code) {
+		ActionResult<ActionOauthQiyeweixinLogin.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionOauthQiyeweixinLogin().execute(request, response, effectivePerson, code);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+
+	@JaxrsMethodDescribe(value = "钉钉oauth登录", action = ActionOauthDingdingLogin.class)
+	@GET
+	@Path("oauth/login/dingding/code/{code}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void oauthLoginDingding(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+							   @Context HttpServletResponse response,
+							   @JaxrsParameterDescribe("code") @PathParam("code") String code) {
+		ActionResult<ActionOauthDingdingLogin.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionOauthDingdingLogin().execute(request, response, effectivePerson, code);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+
 	@JaxrsMethodDescribe(value = "oauth账户绑定.", action = ActionOauthBind.class)
 	@GET
 	@Path("oauth/bind/name/{name}/code/{code}/redirecturi/{redirectUri}")

+ 12 - 0
o2server/x_organization_assemble_authentication/src/main/java/com/x/organization/assemble/authentication/jaxrs/authentication/ExceptionOauthDingdingErrorInfo.java

@@ -0,0 +1,12 @@
+package com.x.organization.assemble.authentication.jaxrs.authentication;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ExceptionOauthDingdingErrorInfo extends PromptException {
+
+	private static final long serialVersionUID = 4132300948670472899L;
+
+	ExceptionOauthDingdingErrorInfo(String msg) {
+		super(msg);
+	}
+}

+ 6 - 6
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/group/ActionGet.java

@@ -60,10 +60,10 @@ class ActionGet extends BaseAction {
 			List<Group> os = business.group().pick(wo.getGroupList());
 			wos = Wo.copier.copy(os);
 		}
-		wos = wos.stream()
+		/*wos = wos.stream()
 				.sorted(Comparator.comparing(Wo::getOrderNumber, Comparator.nullsLast(Integer::compareTo))
 						.thenComparing(Comparator.comparing(Wo::getName, Comparator.nullsLast(String::compareTo))))
-				.collect(Collectors.toList());
+				.collect(Collectors.toList());*/
 		wo.setWoGroupList(wos);
 	}
 
@@ -73,11 +73,11 @@ class ActionGet extends BaseAction {
 			List<Person> os = business.person().pick(wo.getPersonList());
 			wos = WoPerson.copier.copy(os);
 		}
-		wos = wos.stream()
+		/*wos = wos.stream()
 				.sorted(Comparator.comparing(WoPerson::getOrderNumber, Comparator.nullsLast(Integer::compareTo))
 						.thenComparing(
 								Comparator.comparing(WoPerson::getName, Comparator.nullsLast(String::compareTo))))
-				.collect(Collectors.toList());
+				.collect(Collectors.toList());*/
 		wo.setWoPersonList(wos);
 	}
 
@@ -87,10 +87,10 @@ class ActionGet extends BaseAction {
 			List<Unit> os = business.unit().pick(wo.getUnitList());
 			wos = WoUnit.copier.copy(os);
 		}
-		wos = wos.stream()
+		/*wos = wos.stream()
 				.sorted(Comparator.comparing(WoUnit::getOrderNumber, Comparator.nullsLast(Integer::compareTo))
 						.thenComparing(Comparator.comparing(WoUnit::getName, Comparator.nullsLast(String::compareTo))))
-				.collect(Collectors.toList());
+				.collect(Collectors.toList());*/
 		wo.setWoUnitList(wos);
 	}
 

+ 1 - 0
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/identity/ActionOrder.java

@@ -83,6 +83,7 @@ class ActionOrder extends BaseAction {
 			Wo wo = new Wo();
 			wo.setValue(true);
 			result.setData(wo);
+			ApplicationCache.notify(Identity.class);
 			ApplicationCache.notify(Unit.class);
 			return result;
 		}

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio