From 67717e5ebc3eec7c0962093eb4cbbe6ae985eabc Mon Sep 17 00:00:00 2001 From: Tcy <776394504@qq.com> Date: Tue, 29 Apr 2025 19:59:21 +0800 Subject: [PATCH] src --- src/farm-core/.idea/workspace.xml | 75 ++ src/farm-core/pom.xml | 135 ++ .../java/com/farm/core/AuthorityService.java | 92 ++ .../src/main/java/com/farm/core/Context.java | 7 + .../main/java/com/farm/core/FarmUtils.java | 96 ++ .../main/java/com/farm/core/LogService.java | 31 + .../java/com/farm/core/ParameterService.java | 55 + .../java/com/farm/core/SequenceService.java | 113 ++ .../com/farm/core/auth/domain/AuthKey.java | 31 + .../com/farm/core/auth/domain/LoginUser.java | 11 + .../com/farm/core/auth/domain/WebMenu.java | 15 + .../exception/LoginUserNoExistException.java | 12 + .../com/farm/core/auth/impl/AuthTestImpl.java | 145 +++ .../core/auth/impl/VersionController.java | 29 + .../com/farm/core/auth/impl/VersionInfo.java | 33 + .../core/auth/impl/mybatis_demo/.gitignore | 38 + .../auth/impl/mybatis_demo/.idea/.gitignore | 8 + .../impl/mybatis_demo/.idea/dataSources.xml | 17 + .../impl/mybatis_demo/.idea/encodings.xml | 7 + .../auth/impl/mybatis_demo/.idea/misc.xml | 14 + .../impl/mybatis_demo/.idea/sqldialects.xml | 6 + .../impl/mybatis_demo/.idea/uiDesigner.xml | 124 ++ .../lib/mysql-connector-java-5.1.48.jar | Bin 0 -> 1006956 bytes .../farm/core/auth/impl/mybatis_demo/pom.xml | 67 + .../main/java/com/kuang/dao/UseMapper.java | 17 + .../com/kuang/mybatisUtils/mybatisUtils.java | 28 + .../src/main/java/com/kuang/pojo/User.java | 46 + .../main/java/com/kuang/test/mybatisDemo.java | 100 ++ .../src/main/resources/UserMapper.xml | 35 + .../src/main/resources/mybatis-config.xml | 30 + .../src/main/webapp/WEB-INF/web.xml | 7 + .../mybatis_demo/src/main/webapp/index.jsp | 5 + .../core/auth/util/AuthenticateInter.java | 54 + .../core/auth/util/AuthenticateProvider.java | 50 + .../java/com/farm/core/auth/util/KeyUtil.java | 22 + .../java/com/farm/core/auth/util/MD5.java | 358 ++++++ .../java/com/farm/core/auth/util/Urls.java | 192 +++ .../java/com/farm/core/config/AppConfig.java | 48 + .../com/farm/core/config/PropertiesUtils.java | 116 ++ .../java/com/farm/core/config/ReadKey.java | 60 + .../java/com/farm/core/page/OperateType.java | 49 + .../java/com/farm/core/page/RequestMode.java | 198 +++ .../java/com/farm/core/page/StateType.java | 22 + .../java/com/farm/core/page/ViewMode.java | 74 ++ .../com/farm/core/para/impl/ParaTestImpl.java | 46 + .../com/farm/core/sql/query/CoreHandle.java | 22 + .../java/com/farm/core/sql/query/DBRule.java | 228 ++++ .../com/farm/core/sql/query/DBRuleList.java | 40 + .../java/com/farm/core/sql/query/DBSort.java | 106 ++ .../com/farm/core/sql/query/DataQuery.java | 849 ++++++++++++ .../com/farm/core/sql/query/DataQuerys.java | 54 + .../core/sql/query/HibernateQueryHandle.java | 281 ++++ .../com/farm/core/sql/query/SQLQuery.java | 104 ++ .../com/farm/core/sql/query/Searcher.java | 60 + .../com/farm/core/sql/result/DataResult.java | 708 ++++++++++ .../com/farm/core/sql/result/DataResults.java | 200 +++ .../farm/core/sql/result/ResultsHandle.java | 18 + .../core/sql/utils/HibernateSQLTools.java | 145 +++ .../java/com/farm/core/time/TimeTool.java | 507 ++++++++ .../farm/util/cache/FarmCacheGenerater.java | 5 + .../com/farm/util/cache/FarmCacheName.java | 33 + .../com/farm/util/cache/FarmCacheNames.java | 44 + .../java/com/farm/util/cache/FarmCaches.java | 431 +++++++ .../com/farm/util/spring/BeanFactory.java | 34 + .../util/spring/HibernateSessionFactory.java | 27 + .../com/farm/util/validate/ValidUtils.java | 8 + .../com/farm/util/web/FarmFormatUnits.java | 110 ++ .../java/com/farm/util/web/FarmHtmlUtils.java | 155 +++ .../java/com/farm/util/web/FarmproHotnum.java | 48 + .../java/com/farm/util/web/WebHotCase.java | 99 ++ .../java/com/farm/util/web/WebVisitBuff.java | 53 + .../src/main/java/com/farm/web/WebUtils.java | 244 ++++ .../java/com/farm/web/action/FarmAction.java | 193 +++ .../com/farm/web/constant/FarmConstant.java | 53 + .../com/farm/web/easyui/EasyUiTreeNode.java | 796 ++++++++++++ .../java/com/farm/web/easyui/EasyUiUtils.java | 227 ++++ .../com/farm/web/local/ConfDirHandle.java | 44 + .../com/farm/web/local/ConfHandleInter.java | 7 + .../com/farm/web/online/OnlineUserOpImpl.java | 212 +++ .../farm/web/online/OnlineUserOpInter.java | 86 ++ .../farm/web/task/ServletInitJobInter.java | 17 + .../main/java/com/farm/web/task/SysInit.java | 51 + .../java/com/farm/web/task/TaskListInter.java | 11 + .../farm/web/task/impl/ServerLicenceInit.java | 64 + .../com/farm/web/task/impl/TaskListImpl.java | 20 + .../main/java/com/farm/web/test/FarmTest.java | 7 + .../java/com/farm/text/MarkLicenceKey.java | 10 + src/wcp-api/pom.xml | 28 + .../java/com/farm/wcp/api/WcpAppInter.java | 73 ++ .../com/farm/wcp/api/client/WcpAppClient.java | 30 + .../api/exception/DocCreatErrorExcepiton.java | 21 + .../java/com/farm/wcp/domain/Results.java | 52 + src/wcp-authority/pom.xml | 64 + .../java/com/farm/authority/AuthUtils.java | 17 + .../farm/authority/FarmAuthorityService.java | 133 ++ .../controller/ActionController.java | 278 ++++ .../controller/ActiontreeController.java | 364 ++++++ .../controller/OrganizationController.java | 567 ++++++++ .../authority/controller/PostController.java | 382 ++++++ .../controller/WebUserController.java | 301 +++++ .../farm/authority/dao/ActionDaoInter.java | 113 ++ .../authority/dao/ActiontreeDaoInter.java | 110 ++ .../authority/dao/OrganizationDaoInter.java | 110 ++ .../com/farm/authority/dao/PostDaoInter.java | 82 ++ .../authority/dao/PostactionDaoInter.java | 82 ++ .../com/farm/authority/dao/UserDaoInter.java | 108 ++ .../farm/authority/dao/UserorgDaoInter.java | 107 ++ .../farm/authority/dao/UserpostDaoInter.java | 115 ++ .../authority/dao/impl/ActionDaoImpl.java | 155 +++ .../authority/dao/impl/ActiontreeDaoImpl.java | 144 +++ .../dao/impl/OrganizationDaoImpl.java | 143 +++ .../farm/authority/dao/impl/PostDaoImpl.java | 133 ++ .../authority/dao/impl/PostactionDaoImpl.java | 134 ++ .../farm/authority/dao/impl/UserDaoImpl.java | 165 +++ .../authority/dao/impl/UserorgDaoImpl.java | 132 ++ .../authority/dao/impl/UserpostDaoImpl.java | 156 +++ .../com/farm/authority/domain/Action.java | 137 ++ .../com/farm/authority/domain/Actiontree.java | 196 +++ .../farm/authority/domain/AuthKeyImpl.java | 47 + .../farm/authority/domain/AuthMenuImpl.java | 55 + .../farm/authority/domain/Organization.java | 128 ++ .../java/com/farm/authority/domain/Post.java | 141 ++ .../com/farm/authority/domain/Postaction.java | 53 + .../java/com/farm/authority/domain/User.java | 159 +++ .../com/farm/authority/domain/Userorg.java | 67 + .../com/farm/authority/domain/Userpost.java | 60 + .../authority/service/ActionServiceInter.java | 148 +++ .../service/OrganizationServiceInter.java | 185 +++ .../authority/service/UserServiceInter.java | 249 ++++ .../service/impl/ActionServiceImpl.java | 396 ++++++ .../service/impl/OrganizationServiceImpl.java | 457 +++++++ .../service/impl/UserServiceImpl.java | 518 ++++++++ src/wcp-doc-so/pom.xml | 97 ++ .../server/plus/FarmTypePopServerInter.java | 24 + .../farm/doc/server/plus/domain/DocAudit.java | 91 ++ .../doc/server/plus/domain/Doctypepop.java | 78 ++ .../plus/impl/FarmTypePopServerImpl.java | 47 + src/wcp-doc/pom.xml | 107 ++ .../controller/ActionFarmDocIndexQuery.java | 62 + .../doc/controller/ActionFarmDocQuery.java | 310 +++++ .../controller/ActionFarmDocfileQuery.java | 156 +++ .../controller/ActionFarmDocgroupQuery.java | 159 +++ .../ActionFarmDocgroupUserQuery.java | 205 +++ .../controller/ActionFarmDocmessageQuery.java | 158 +++ .../controller/ActionFarmDoctypeQuery.java | 200 +++ .../doc/controller/ActionFarmLuceneQuery.java | 136 ++ .../farm/doc/controller/ActionImgQuery.java | 235 ++++ .../FarmReleaseRankingController.java | 68 + .../doc/controller/FarmtopController.java | 242 ++++ .../doc/controller/UsermessageController.java | 195 +++ .../farm/doc/controller/WeburlController.java | 207 +++ .../com/farm/doc/dao/FarmDocDaoInter.java | 69 + .../farm/doc/dao/FarmDocenjoyDaoInter.java | 69 + .../com/farm/doc/dao/FarmDocfileDaoInter.java | 111 ++ .../farm/doc/dao/FarmDocgroupDaoInter.java | 77 ++ .../doc/dao/FarmDocgroupUserDaoInter.java | 69 + .../farm/doc/dao/FarmDocmessageDaoInter.java | 105 ++ .../farm/doc/dao/FarmDocruninfoDaoInter.java | 112 ++ .../doc/dao/FarmDocruninfoDetailDaoInter.java | 77 ++ .../com/farm/doc/dao/FarmDoctextDaoInter.java | 69 + .../com/farm/doc/dao/FarmDoctypeDaoInter.java | 98 ++ .../doc/dao/FarmRfDoctextfileDaoInter.java | 69 + .../farm/doc/dao/FarmRfDoctypeDaoInter.java | 81 ++ .../com/farm/doc/dao/FarmtopDaoInter.java | 82 ++ .../com/farm/doc/dao/UsermessageDaoInter.java | 82 ++ .../java/com/farm/doc/dao/WeburlDaoInter.java | 82 ++ .../java/com/farm/doc/dao/impl/Article.java | 53 + .../com/farm/doc/dao/impl/FarmDocDao.java | 103 ++ .../farm/doc/dao/impl/FarmDocenjoyDao.java | 110 ++ .../com/farm/doc/dao/impl/FarmDocfileDao.java | 132 ++ .../farm/doc/dao/impl/FarmDocgroupDao.java | 114 ++ .../doc/dao/impl/FarmDocgroupUserDao.java | 98 ++ .../farm/doc/dao/impl/FarmDocmessageDao.java | 127 ++ .../farm/doc/dao/impl/FarmDocruninfoDao.java | 131 ++ .../doc/dao/impl/FarmDocruninfoDetailDao.java | 115 ++ .../com/farm/doc/dao/impl/FarmDoctextDao.java | 98 ++ .../com/farm/doc/dao/impl/FarmDoctypeDao.java | 113 ++ .../doc/dao/impl/FarmRfDoctextfileDao.java | 98 ++ .../farm/doc/dao/impl/FarmRfDoctypeDao.java | 139 ++ .../com/farm/doc/dao/impl/FarmtopDaoImpl.java | 120 ++ .../farm/doc/dao/impl/UsermessageDaoImpl.java | 120 ++ .../com/farm/doc/dao/impl/WeburlDaoImpl.java | 120 ++ .../main/java/com/farm/doc/domain/Doc.java | 226 ++++ .../com/farm/doc/domain/FarmDocenjoy.java | 68 + .../java/com/farm/doc/domain/FarmDocfile.java | 256 ++++ .../com/farm/doc/domain/FarmDocgroup.java | 233 ++++ .../com/farm/doc/domain/FarmDocgroupUser.java | 234 ++++ .../com/farm/doc/domain/FarmDocmessage.java | 199 +++ .../com/farm/doc/domain/FarmDocruninfo.java | 124 ++ .../farm/doc/domain/FarmDocruninfoDetail.java | 159 +++ .../java/com/farm/doc/domain/FarmDoctext.java | 194 +++ .../java/com/farm/doc/domain/FarmDoctype.java | 311 +++++ .../farm/doc/domain/FarmRfDoctextfile.java | 70 + .../com/farm/doc/domain/FarmRfDoctype.java | 69 + .../java/com/farm/doc/domain/Farmtop.java | 92 ++ .../java/com/farm/doc/domain/Usermessage.java | 108 ++ .../main/java/com/farm/doc/domain/Weburl.java | 158 +++ .../farm/doc/domain/ex/ArticleRepository.java | 18 + .../java/com/farm/doc/domain/ex/DocBrief.java | 225 ++++ .../com/farm/doc/domain/ex/DocEntire.java | 247 ++++ .../com/farm/doc/domain/ex/GroupBrief.java | 168 +++ .../com/farm/doc/domain/ex/GroupEntire.java | 188 +++ .../com/farm/doc/domain/ex/TypeBrief.java | 77 ++ .../doc/exception/CanNoDeleteException.java | 25 + .../doc/exception/CanNoReadException.java | 26 + .../doc/exception/CanNoWriteException.java | 25 + .../doc/exception/DocNoExistException.java | 25 + .../NoGroupAuthForLicenceException.java | 25 + .../doc/quartz/task/RecountDocHotnumTask.java | 55 + .../farm/doc/server/FarmDocIndexInter.java | 74 ++ .../farm/doc/server/FarmDocManagerInter.java | 168 +++ .../doc/server/FarmDocOperateRightInter.java | 154 +++ .../farm/doc/server/FarmDocRunInfoInter.java | 261 ++++ .../com/farm/doc/server/FarmDocTypeInter.java | 154 +++ .../doc/server/FarmDocgroupManagerInter.java | 503 ++++++++ .../server/FarmDocmessageManagerInter.java | 168 +++ .../doc/server/FarmFileIndexManagerInter.java | 56 + .../farm/doc/server/FarmFileManagerInter.java | 180 +++ .../farm/doc/server/FarmtopServiceInter.java | 62 + .../doc/server/UsermessageServiceInter.java | 118 ++ .../farm/doc/server/WeburlServiceInter.java | 72 ++ .../doc/server/commons/DocMessageCache.java | 35 + .../doc/server/commons/DocumentConfig.java | 38 + .../farm/doc/server/commons/FarmDocFiles.java | 158 +++ .../exception/NotIsHttpZipException.java | 10 + .../farm/doc/server/impl/ArticleService.java | 52 + .../server/impl/FarmDocIndexManagerImpl.java | 334 +++++ .../doc/server/impl/FarmDocManagerImpl.java | 775 +++++++++++ .../server/impl/FarmDocOperateRightImpl.java | 293 +++++ .../doc/server/impl/FarmDocRunInfoImpl.java | 765 +++++++++++ .../server/impl/FarmDocTypeManagerImpl.java | 584 +++++++++ .../server/impl/FarmDocgroupManagerImpl.java | 1135 +++++++++++++++++ .../impl/FarmDocmessageManagerImpl.java | 283 ++++ .../server/impl/FarmFileIndexManagerImpl.java | 96 ++ .../doc/server/impl/FarmFileManagerImpl.java | 267 ++++ .../doc/server/impl/FarmtopServiceImpl.java | 104 ++ .../server/impl/UsermessageServiceImpl.java | 159 +++ .../doc/server/impl/WeburlServiceImpl.java | 146 +++ .../com/farm/doc/util/ArticleController .java | 40 + .../java/com/farm/doc/util/DocTagUtils.java | 21 + .../java/com/farm/doc/util/DocToString.java | 18 + .../java/com/farm/doc/util/HtmlUtils.java | 51 + .../java/com/farm/doc/util/LuceneDocUtil.java | 58 + .../java/com/farm/doc/util/MailSender.java | 237 ++++ .../com/farm/doc/util/MailSenderConf.java | 58 + .../src/test/java/org/test/doc/SendMail.java | 21 + 246 files changed, 33557 insertions(+) create mode 100644 src/farm-core/.idea/workspace.xml create mode 100644 src/farm-core/pom.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/AuthorityService.java create mode 100644 src/farm-core/src/main/java/com/farm/core/Context.java create mode 100644 src/farm-core/src/main/java/com/farm/core/FarmUtils.java create mode 100644 src/farm-core/src/main/java/com/farm/core/LogService.java create mode 100644 src/farm-core/src/main/java/com/farm/core/ParameterService.java create mode 100644 src/farm-core/src/main/java/com/farm/core/SequenceService.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/domain/AuthKey.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/domain/LoginUser.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/domain/WebMenu.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/exception/LoginUserNoExistException.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/AuthTestImpl.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/VersionController.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/VersionInfo.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.gitignore create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/.gitignore create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/dataSources.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/encodings.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/misc.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/sqldialects.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/uiDesigner.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/lib/mysql-connector-java-5.1.48.jar create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/pom.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/dao/UseMapper.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/mybatisUtils/mybatisUtils.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/pojo/User.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/test/mybatisDemo.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/resources/UserMapper.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/resources/mybatis-config.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/webapp/WEB-INF/web.xml create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/webapp/index.jsp create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/util/AuthenticateInter.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/util/AuthenticateProvider.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/util/KeyUtil.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/util/MD5.java create mode 100644 src/farm-core/src/main/java/com/farm/core/auth/util/Urls.java create mode 100644 src/farm-core/src/main/java/com/farm/core/config/AppConfig.java create mode 100644 src/farm-core/src/main/java/com/farm/core/config/PropertiesUtils.java create mode 100644 src/farm-core/src/main/java/com/farm/core/config/ReadKey.java create mode 100644 src/farm-core/src/main/java/com/farm/core/page/OperateType.java create mode 100644 src/farm-core/src/main/java/com/farm/core/page/RequestMode.java create mode 100644 src/farm-core/src/main/java/com/farm/core/page/StateType.java create mode 100644 src/farm-core/src/main/java/com/farm/core/page/ViewMode.java create mode 100644 src/farm-core/src/main/java/com/farm/core/para/impl/ParaTestImpl.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/CoreHandle.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/DBRule.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/DBRuleList.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/DBSort.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/DataQuery.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/DataQuerys.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/HibernateQueryHandle.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/SQLQuery.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/query/Searcher.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/result/DataResult.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/result/DataResults.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/result/ResultsHandle.java create mode 100644 src/farm-core/src/main/java/com/farm/core/sql/utils/HibernateSQLTools.java create mode 100644 src/farm-core/src/main/java/com/farm/core/time/TimeTool.java create mode 100644 src/farm-core/src/main/java/com/farm/util/cache/FarmCacheGenerater.java create mode 100644 src/farm-core/src/main/java/com/farm/util/cache/FarmCacheName.java create mode 100644 src/farm-core/src/main/java/com/farm/util/cache/FarmCacheNames.java create mode 100644 src/farm-core/src/main/java/com/farm/util/cache/FarmCaches.java create mode 100644 src/farm-core/src/main/java/com/farm/util/spring/BeanFactory.java create mode 100644 src/farm-core/src/main/java/com/farm/util/spring/HibernateSessionFactory.java create mode 100644 src/farm-core/src/main/java/com/farm/util/validate/ValidUtils.java create mode 100644 src/farm-core/src/main/java/com/farm/util/web/FarmFormatUnits.java create mode 100644 src/farm-core/src/main/java/com/farm/util/web/FarmHtmlUtils.java create mode 100644 src/farm-core/src/main/java/com/farm/util/web/FarmproHotnum.java create mode 100644 src/farm-core/src/main/java/com/farm/util/web/WebHotCase.java create mode 100644 src/farm-core/src/main/java/com/farm/util/web/WebVisitBuff.java create mode 100644 src/farm-core/src/main/java/com/farm/web/WebUtils.java create mode 100644 src/farm-core/src/main/java/com/farm/web/action/FarmAction.java create mode 100644 src/farm-core/src/main/java/com/farm/web/constant/FarmConstant.java create mode 100644 src/farm-core/src/main/java/com/farm/web/easyui/EasyUiTreeNode.java create mode 100644 src/farm-core/src/main/java/com/farm/web/easyui/EasyUiUtils.java create mode 100644 src/farm-core/src/main/java/com/farm/web/local/ConfDirHandle.java create mode 100644 src/farm-core/src/main/java/com/farm/web/local/ConfHandleInter.java create mode 100644 src/farm-core/src/main/java/com/farm/web/online/OnlineUserOpImpl.java create mode 100644 src/farm-core/src/main/java/com/farm/web/online/OnlineUserOpInter.java create mode 100644 src/farm-core/src/main/java/com/farm/web/task/ServletInitJobInter.java create mode 100644 src/farm-core/src/main/java/com/farm/web/task/SysInit.java create mode 100644 src/farm-core/src/main/java/com/farm/web/task/TaskListInter.java create mode 100644 src/farm-core/src/main/java/com/farm/web/task/impl/ServerLicenceInit.java create mode 100644 src/farm-core/src/main/java/com/farm/web/task/impl/TaskListImpl.java create mode 100644 src/farm-core/src/main/java/com/farm/web/test/FarmTest.java create mode 100644 src/farm-core/src/test/java/com/farm/text/MarkLicenceKey.java create mode 100644 src/wcp-api/pom.xml create mode 100644 src/wcp-api/src/main/java/com/farm/wcp/api/WcpAppInter.java create mode 100644 src/wcp-api/src/main/java/com/farm/wcp/api/client/WcpAppClient.java create mode 100644 src/wcp-api/src/main/java/com/farm/wcp/api/exception/DocCreatErrorExcepiton.java create mode 100644 src/wcp-api/src/main/java/com/farm/wcp/domain/Results.java create mode 100644 src/wcp-authority/pom.xml create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/AuthUtils.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/FarmAuthorityService.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/controller/ActionController.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/controller/ActiontreeController.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/controller/OrganizationController.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/controller/PostController.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/controller/WebUserController.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/ActionDaoInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/ActiontreeDaoInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/OrganizationDaoInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/PostDaoInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/PostactionDaoInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/UserDaoInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/UserorgDaoInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/UserpostDaoInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/impl/ActionDaoImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/impl/ActiontreeDaoImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/impl/OrganizationDaoImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/impl/PostDaoImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/impl/PostactionDaoImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserDaoImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserorgDaoImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserpostDaoImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/Action.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/Actiontree.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/AuthKeyImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/AuthMenuImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/Organization.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/Post.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/Postaction.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/User.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/Userorg.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/domain/Userpost.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/service/ActionServiceInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/service/OrganizationServiceInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/service/UserServiceInter.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/service/impl/ActionServiceImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/service/impl/OrganizationServiceImpl.java create mode 100644 src/wcp-authority/src/main/java/com/farm/authority/service/impl/UserServiceImpl.java create mode 100644 src/wcp-doc-so/pom.xml create mode 100644 src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/FarmTypePopServerInter.java create mode 100644 src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/domain/DocAudit.java create mode 100644 src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/domain/Doctypepop.java create mode 100644 src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/impl/FarmTypePopServerImpl.java create mode 100644 src/wcp-doc/pom.xml create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocIndexQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocfileQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocgroupQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocgroupUserQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocmessageQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDoctypeQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmLuceneQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/ActionImgQuery.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/FarmReleaseRankingController.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/FarmtopController.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/UsermessageController.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/controller/WeburlController.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocenjoyDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocfileDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocgroupDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocgroupUserDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocmessageDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocruninfoDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocruninfoDetailDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDoctextDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDoctypeDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmRfDoctextfileDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmRfDoctypeDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/FarmtopDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/UsermessageDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/WeburlDaoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/Article.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocenjoyDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocfileDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocgroupDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocgroupUserDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocmessageDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocruninfoDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocruninfoDetailDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDoctextDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDoctypeDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmRfDoctextfileDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmRfDoctypeDao.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmtopDaoImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/UsermessageDaoImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/dao/impl/WeburlDaoImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/Doc.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocenjoy.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocfile.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocgroup.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocgroupUser.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocmessage.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocruninfo.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocruninfoDetail.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDoctext.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDoctype.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmRfDoctextfile.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/FarmRfDoctype.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/Farmtop.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/Usermessage.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/Weburl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/ex/ArticleRepository.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/ex/DocBrief.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/ex/DocEntire.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/ex/GroupBrief.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/ex/GroupEntire.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/domain/ex/TypeBrief.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoDeleteException.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoReadException.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoWriteException.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/exception/DocNoExistException.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/exception/NoGroupAuthForLicenceException.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/quartz/task/RecountDocHotnumTask.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocIndexInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocManagerInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocOperateRightInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocRunInfoInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocTypeInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocgroupManagerInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocmessageManagerInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmFileIndexManagerInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmFileManagerInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/FarmtopServiceInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/UsermessageServiceInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/WeburlServiceInter.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/commons/DocMessageCache.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/commons/DocumentConfig.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/commons/FarmDocFiles.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/exception/NotIsHttpZipException.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/ArticleService.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocIndexManagerImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocManagerImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocOperateRightImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocRunInfoImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocTypeManagerImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocgroupManagerImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocmessageManagerImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmFileIndexManagerImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmFileManagerImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmtopServiceImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/UsermessageServiceImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/server/impl/WeburlServiceImpl.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/util/ArticleController .java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/util/DocTagUtils.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/util/DocToString.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/util/HtmlUtils.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/util/LuceneDocUtil.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/util/MailSender.java create mode 100644 src/wcp-doc/src/main/java/com/farm/doc/util/MailSenderConf.java create mode 100644 src/wcp-doc/src/test/java/org/test/doc/SendMail.java diff --git a/src/farm-core/.idea/workspace.xml b/src/farm-core/.idea/workspace.xml new file mode 100644 index 0000000..81c36ee --- /dev/null +++ b/src/farm-core/.idea/workspace.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + { + "associatedIndex": 2 +} + + + + { + "keyToString": { + "Maven.farm-core [clean,install].executor": "Run", + "RunOnceActivity.ShowReadmeOnStart": "true", + "git-widget-placeholder": "master", + "kotlin-language-version-configured": "true", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "nodejs_package_manager_path": "npm", + "project.structure.last.edited": "模块", + "project.structure.proportion": "0.15", + "project.structure.side.proportion": "0.2", + "settings.editor.selected.configurable": "MavenSettings", + "vue.rearranger.settings.migration": "true" + } +} + + + + + + + + + + + 1741954660473 + + + + + + \ No newline at end of file diff --git a/src/farm-core/pom.xml b/src/farm-core/pom.xml new file mode 100644 index 0000000..852c37e --- /dev/null +++ b/src/farm-core/pom.xml @@ -0,0 +1,135 @@ + + 4.0.0 + com.farm + farm-core + jar + ${wcp.version} + 核心包 + + 3.2.0 + 4.1.6.RELEASE + + UTF-8 + UTF-8 + + UTF-8 + + + + junit + junit + 3.8.1 + test + + + net.sf.ehcache + ehcache + 2.10.4 + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + + + org.springframework + spring-orm + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + mysql + mysql-connector-java + 5.1.29 + + + org.hibernate + hibernate-entitymanager + 4.3.8.Final + + + log4j + log4j + 1.2.17 + + + com.sun.commons + beanutils + 1.6.1-20070314 + + + commons-codec + commons-codec + 1.9 + + + commons-lang + commons-lang + 2.6 + + + commons-beanutils + commons-beanutils + 1.9.2 + + + javax.servlet + servlet-api + 2.5 + + + javax.servlet.jsp + jsp-api + 2.2.1-b03 + + + + + + maven-compiler-plugin + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.1 + + + + true + true + + + + + + + \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/AuthorityService.java b/src/farm-core/src/main/java/com/farm/core/AuthorityService.java new file mode 100644 index 0000000..fbb1367 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/AuthorityService.java @@ -0,0 +1,92 @@ +package com.farm.core; + +import java.util.List; +import java.util.Set; + +import com.farm.core.auth.domain.AuthKey; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.auth.exception.LoginUserNoExistException; + +/** + * 权限服务接口 + * + * @author wangdong + * @version 2014-12 + * + */ +public interface AuthorityService { + + /** + * 验证用户是否合法 + * + * @param loginName + * 用户登录名 + * @param password + * 用户密码 + * @return + */ + public boolean isLegality(String loginName, String password) + throws LoginUserNoExistException; + + /** + * 获得用户对象 + * + * @param loginName + * @return + */ + public LoginUser getUserByLoginName(String loginName); + + + /**获得用户岗位(用于工作流等应用中的对应KEY) + * @param userId + * @return + */ + public List getUserPostKeys(String userId); + + /**获得用户组织机构KEY + * @param userId + * @return + */ + public String getUserOrgKey(String userId); + + /** + * 获得用户对象 + * + * @param userId + * @return + */ + public LoginUser getUserById(String userId); + + /** + * 获得用户权限关键字 + * + * @param userId + * @return + */ + public Set getUserAuthKeys(String userId); + + /** + * 获得key对象(用于检查key权限) + * + * @param key + * @return + */ + public AuthKey getAuthKey(String key); + + /** + * 获得用户的菜单 + * + * @param userId + * @return + */ + public List getUserMenu(String userId); + + /** + * 登录成功时会调用此方法 + * + * @param userId + */ + public void loginHandle(String userId); + +} diff --git a/src/farm-core/src/main/java/com/farm/core/Context.java b/src/farm-core/src/main/java/com/farm/core/Context.java new file mode 100644 index 0000000..9ca4b5c --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/Context.java @@ -0,0 +1,7 @@ +package com.farm.core; + +public class Context { + public static String MK; + public static String FK; + public static boolean FLAG; +} diff --git a/src/farm-core/src/main/java/com/farm/core/FarmUtils.java b/src/farm-core/src/main/java/com/farm/core/FarmUtils.java new file mode 100644 index 0000000..e532547 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/FarmUtils.java @@ -0,0 +1,96 @@ +package com.farm.core; + +import com.farm.core.auth.util.AuthenticateInter; +import com.farm.core.auth.util.AuthenticateProvider; +import com.farm.core.config.PropertiesUtils; +import com.farm.core.time.TimeTool; +import com.farm.util.validate.ValidUtils; +import com.farm.util.web.FarmFormatUnits; +import com.farm.util.web.FarmproHotnum; +import com.farm.util.web.WebHotCase; +import com.farm.util.web.WebVisitBuff; + +/** + * 平台工具类入口 + * + * @author wangdong + * + */ +public class FarmUtils { + /**获得验证类工具 + * @return + */ + public static ValidUtils getValidUtils() { + return new ValidUtils(); + } + + /** + * 获得加解密类工具 + * + * @return + */ + public static AuthenticateInter getAuthUtils() { + return AuthenticateProvider.getInstance(); + } + + /** + * 获得Properties文件工具 + * + * @param fileName + * 如jdbc.properties + * @return + */ + public static PropertiesUtils getPropertiesUtils(String fileName) { + return new PropertiesUtils(fileName); + } + + /** + * 获得时间类工具 + * + * @return + */ + public static TimeTool getTimeTools() { + return new TimeTool(); + } + + /** + * 获得格式化工具(友好的时间格式化,文件大小格式化) + * + * @return + */ + public static FarmFormatUnits getFormatUtils() { + return new FarmFormatUnits(); + } + + /** + * 访问热度计算工具 + * + * @return + */ + public static FarmproHotnum getHotUtils() { + return new FarmproHotnum(); + } + + /** + * 计算热词(如搜索关键字的统计) + * + * @return + */ + public static WebHotCase getHotWordUtils() { + return new WebHotCase(); + } + + /** + * 判断用户在一定时间内是否访问的工具,用来计算一个KEY在一定时间内是否已经被标记(如控制相同用户不重复计算文章的访问量) + * + * @param domain + * 统计域,不同域被分隔开控制(相互间不受影响) + * @param maxNum + * 每个域中允许缓存的key数据量(超出后域被刷新) + * @return + */ + public static WebVisitBuff getWebVisitBuff(String domain, int maxNum) { + return WebVisitBuff.getInstance(domain, maxNum); + } + +} diff --git a/src/farm-core/src/main/java/com/farm/core/LogService.java b/src/farm-core/src/main/java/com/farm/core/LogService.java new file mode 100644 index 0000000..ee0d5f4 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/LogService.java @@ -0,0 +1,31 @@ +package com.farm.core; + +/** + * 参数服务接口 + * + * @author wangdong + * @version 2014-12 + * + */ +public interface LogService { + + /** + * 记录日志 + * + * @param message + * 信息 + * @param loginUserId + * 用户id + * @param level + * 日志级别 + * @param methodName + * 程序方法名称 + * @param className + * 程序类名 + * @param ip + * 用户IP + */ + public void log(String info, String loginUserId, String level, + String methodName, String className, String ip); + +} diff --git a/src/farm-core/src/main/java/com/farm/core/ParameterService.java b/src/farm-core/src/main/java/com/farm/core/ParameterService.java new file mode 100644 index 0000000..b55d609 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/ParameterService.java @@ -0,0 +1,55 @@ +package com.farm.core; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * 参数服务接口 + * + * @author wangdong + * @version 2014-12 + * + */ +public interface ParameterService { + + /** + * 获得系统参数值(可以获得系统中各种参数:如系统参数、properties参数、系统常量) + * + * @return + */ + public String getParameter(String key); + + /** + * 获得系统参数值(可以获得系统中各种参数:如用户个性化参数、系统参数、properties参数、系统常量) + * + * @return + */ + public String getParameter(String key, String userId); + + /** + * 获得字典列表 + * + * @param index + * @return + */ + public List> getDictionaryList(String index); + + /** + * 获得字典 + * + * @param key + * @return + */ + public Map getDictionary(String key); + + public int getParameterInt(String string); + + /** + * 获得系统参数值(可以获得系统中各种参数:如系统参数、properties参数、系统常量) + * + * @param string + * @return + */ + public boolean getParameterBoolean(String key); +} diff --git a/src/farm-core/src/main/java/com/farm/core/SequenceService.java b/src/farm-core/src/main/java/com/farm/core/SequenceService.java new file mode 100644 index 0000000..2fb0f45 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/SequenceService.java @@ -0,0 +1,113 @@ +package com.farm.core; + +import java.net.NetworkInterface; +import java.util.Enumeration; + +import com.farm.core.auth.util.MD5; + +/** + * 机器码生成的通用服务 + * + * @author 杨尚川 + */ +public class SequenceService { + /** + * 对一段String生成MD5摘要信息 + * + * @param message + * 要摘要的String + * @return 生成的MD5摘要信息 + */ + protected static String getMD5(String message) { + String md5 = new MD5().getMD5ofStr(message); + return getSplitString(md5); + } + + public static String InitKey() { + return getMD5(getSigarSequence()); + } + + /** + * 将很长的字符串以固定的位数分割开,以便于人类阅读 + * + * @param str + * @return + */ + protected static String getSplitString(String str) { + + return getSplitString(str.substring(0, 16), "-", 4); + } + + /** + * 将很长的字符串以固定的位数分割开,以便于人类阅读 如将 71F5DA7F495E7F706D47F3E63DC6349A + * 以-,每4个一组,则分割为 71F5-DA7F-495E-7F70-6D47-F3E6-3DC6-349A + * + * @param str + * 字符串 + * @param split + * 分隔符 + * @param length + * 长度 + * @return + */ + protected static String getSplitString(String str, String split, int length) { + int len = str.length(); + StringBuilder temp = new StringBuilder(); + for (int i = 0; i < len; i++) { + if (i % length == 0 && i > 0) { + temp.append(split); + } + temp.append(str.charAt(i)); + } + String[] attrs = temp.toString().split(split); + StringBuilder finalMachineCode = new StringBuilder(); + for (String attr : attrs) { + if (attr.length() == length) { + finalMachineCode.append(attr).append(split); + } + } + String result = finalMachineCode.toString().substring(0, finalMachineCode.toString().length() - 1); + return result; + } + + /** + * 利用sigar来生成机器码,当然这个实现不是很好,无法获得CPU ID,希望有兴趣的朋友来改进这个实现 + * + * @param osName + * 操作系统类型 + * @return 机器码 + */ + protected static String getSigarSequence() { + return "asdf"; + } + /** + * 按照"XX-XX-XX-XX-XX-XX"格式,获取本机MAC地址 + * @return + * @throws Exception + */ + public static String getMacAddress() throws Exception{ + Enumeration ni = NetworkInterface.getNetworkInterfaces(); + + while(ni.hasMoreElements()){ + NetworkInterface netI = ni.nextElement(); + + byte[] bytes = netI.getHardwareAddress(); + if(netI.isUp() && netI != null && bytes != null && bytes.length == 6){ + StringBuffer sb = new StringBuffer(); + for(byte b:bytes){ + //与11110000作按位与运算以便读取当前字节高4位 + sb.append(Integer.toHexString((b&240)>>4)); + //与00001111作按位与运算以便读取当前字节低4位 + sb.append(Integer.toHexString(b&15)); + sb.append("-"); + } + sb.deleteCharAt(sb.length()-1); + return sb.toString().toUpperCase(); + } + } + return null; + } + public static void main(String[] args) { + System.out.println(SequenceService.InitKey()); + } +} \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/domain/AuthKey.java b/src/farm-core/src/main/java/com/farm/core/auth/domain/AuthKey.java new file mode 100644 index 0000000..45229bc --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/domain/AuthKey.java @@ -0,0 +1,31 @@ +package com.farm.core.auth.domain; + +public interface AuthKey { + /** + * 是否需要用户登录使用 + * + * @return + */ + public boolean isLogin(); + + /** + * 是否需要检查用户权限 + * + * @return + */ + public boolean isCheck(); + + /** + * 是否可用 + * + * @return + */ + public boolean isUseAble(); + + /** + * 获得名称 + * + * @return + */ + public String getTitle(); +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/domain/LoginUser.java b/src/farm-core/src/main/java/com/farm/core/auth/domain/LoginUser.java new file mode 100644 index 0000000..80511af --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/domain/LoginUser.java @@ -0,0 +1,11 @@ +package com.farm.core.auth.domain; + +public interface LoginUser { + + public String getId(); + + public String getName(); + + public String getLoginname(); + +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/domain/WebMenu.java b/src/farm-core/src/main/java/com/farm/core/auth/domain/WebMenu.java new file mode 100644 index 0000000..78ad95f --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/domain/WebMenu.java @@ -0,0 +1,15 @@ +package com.farm.core.auth.domain; + +public interface WebMenu { + public String getParams(); + + public String getIcon(); + + public String getUrl(); + + public String getName(); + + public String getParentid(); + + public String getId(); +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/exception/LoginUserNoExistException.java b/src/farm-core/src/main/java/com/farm/core/auth/exception/LoginUserNoExistException.java new file mode 100644 index 0000000..0a04325 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/exception/LoginUserNoExistException.java @@ -0,0 +1,12 @@ +package com.farm.core.auth.exception; + +public class LoginUserNoExistException extends Exception { + public LoginUserNoExistException(String message) { + super(message); + } + /** + * + */ + private static final long serialVersionUID = 6482296763929242398L; + +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/AuthTestImpl.java b/src/farm-core/src/main/java/com/farm/core/auth/impl/AuthTestImpl.java new file mode 100644 index 0000000..250fb5e --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/AuthTestImpl.java @@ -0,0 +1,145 @@ +package com.farm.core.auth.impl; // 定义包名,表示该类位于 com.farm.core.auth.impl 包中 + +import java.util.ArrayList; // 导入 ArrayList 类 +import java.util.HashSet; // 导入 HashSet 类 +import java.util.List; // 导入 List 接口 +import java.util.Set; // 导入 Set 接口 + +import org.springframework.stereotype.Service; // 导入 Spring 的 @Service 注解 + +import com.farm.core.AuthorityService; // 导入 AuthorityService 接口 +import com.farm.core.auth.domain.AuthKey; // 导入 AuthKey 类 +import com.farm.core.auth.domain.LoginUser; // 导入 LoginUser 类 +import com.farm.core.auth.domain.WebMenu; // 导入 WebMenu 类 +import com.farm.core.auth.exception.LoginUserNoExistException; // 导入 LoginUserNoExistException 异常类 +package com.example.versionmanagement; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + + +//启动类 +package com.example.versionmanagement; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class VersionManagementApplication { + + public static void main(String[] args) { + SpringApplication.run(VersionManagementApplication.class, args); + } +} +@Service // 标注该类为 Spring 的服务组件 +public class AuthTestImpl implements AuthorityService { // 定义 AuthTestImpl 类,实现 AuthorityService 接口 + + @Override // 重写 AuthorityService 接口中的 loginHandle 方法 + public void loginHandle(String userId) { + System.out.println("登录成功"); // 打印登录成功信息 + } + + @Override // 重写 AuthorityService 接口中的 getUserAuthKeys 方法 + public Set getUserAuthKeys(String userId) { + Set map = new HashSet(); // 创建一个 HashSet 对象 + map.add("AUTHKEY"); // 向集合中添加一个权限键 + return map; // 返回包含权限键的集合 + } + + @Override // 重写 AuthorityService 接口中的 getUserById 方法 + public LoginUser getUserById(String userId) { + // 创建一个匿名内部类实现 LoginUser 接口 + LoginUser user = new LoginUser() { + @Override // 重写 getName 方法 + public String getName() { + return "userName"; // 返回用户名 + } + + @Override // 重写 getLoginname 方法 + public String getLoginname() { + return "loginName"; // 返回登录名 + } + + @Override // 重写 getId 方法 + public String getId() { + return "userId"; // 返回用户ID + } + }; + return user; // 返回创建的 LoginUser 对象 + } + + @Override // 重写 AuthorityService 接口中的 getUserByLoginName 方法 + public LoginUser getUserByLoginName(String loginName) { + // 创建一个匿名内部类实现 LoginUser 接口 + LoginUser user = new LoginUser() { + @Override // 重写 getName 方法 + public String getName() { + return "userName"; // 返回用户名 + } + + @Override // 重写 getLoginname 方法 + public String getLoginname() { + return "loginName"; // 返回登录名 + } + + @Override // 重写 getId 方法 + public String getId() { + return "userId"; // 返回用户ID + } + }; + return user; // 返回创建的 LoginUser 对象 + } + + @Override // 重写 AuthorityService 接口中的 getUserMenu 方法 + public List getUserMenu(String userId) { + List list = new ArrayList(); // 创建一个 ArrayList 对象 + return list; // 返回用户菜单列表 + } + + @Override // 重写 AuthorityService 接口中的 isLegality 方法 + public boolean isLegality(String loginName, String password) + throws LoginUserNoExistException { + return true; // 返回 true,表示用户名和密码合法 + } + + @Override // 重写 AuthorityService 接口中的 getAuthKey 方法 + public AuthKey getAuthKey(String key) { + // 创建一个匿名内部类实现 AuthKey 接口 + return new AuthKey() { + @Override // 重写 isLogin 方法 + public boolean isLogin() { + return false; // 返回 false,表示未登录 + } + + @Override // 重写 isCheck 方法 + public boolean isCheck() { + return false; // 返回 false,表示未检查 + } + + @Override // 重写 isUseAble 方法 + public boolean isUseAble() { + return true; // 返回 true,表示可用 + } + + @Override // 重写 getTitle 方法 + public String getTitle() { + return "权限名称(测试)"; // 返回权限标题 + } + }; + } + + @Override // 重写 AuthorityService 接口中的 getUserPostKeys 方法 + public List getUserPostKeys(String userId) { + List list = new ArrayList(); // 创建一个 ArrayList 对象 + list.add("POSTID"); // 向列表中添加一个岗位ID + return list; // 返回用户岗位键列表 + } + + @Override // 重写 AuthorityService 接口中的 getUserOrgKey 方法 + public String getUserOrgKey(String userId) { + return "ORGID"; // 返回用户组织键 + } + +} // AuthTestImpl 类结束 + + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/VersionController.java b/src/farm-core/src/main/java/com/farm/core/auth/impl/VersionController.java new file mode 100644 index 0000000..a792d04 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/VersionController.java @@ -0,0 +1,29 @@ +package com.example.versionmanagement; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 版本控制器类,用于处理与版本信息相关的HTTP请求。 + */ +@RestController +public class VersionController { + + /** + * 自动注入版本信息对象,该对象包含了版本相关的数据。 + */ + @Autowired + private VersionInfo versionInfo; + + /** + * 处理GET请求,返回版本信息。 + * 当访问"/version"端点时,此方法将被调用。 + * + * @return VersionInfo 返回包含版本信息的对象。 + */ + @GetMapping("/version") + public VersionInfo getVersionInfo() { + return versionInfo; + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/VersionInfo.java b/src/farm-core/src/main/java/com/farm/core/auth/impl/VersionInfo.java new file mode 100644 index 0000000..8334782 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/VersionInfo.java @@ -0,0 +1,33 @@ +//创建一个类来存储版本信息 +@Configuration +@ConfigurationProperties(prefix = "app.version") +public class VersionInfo { + private String name; + private String version; + private String description; + + // getters and setters + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.gitignore b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/.gitignore b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/dataSources.xml b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/dataSources.xml new file mode 100644 index 0000000..08036ef --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/dataSources.xml @@ -0,0 +1,17 @@ + + + + + mysql_aurora_aws + true + software.aws.rds.jdbc.mysql.Driver + jdbc:mysql:aws://localhost:3306 + + + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/encodings.xml b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/misc.xml b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/misc.xml new file mode 100644 index 0000000..132404b --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/sqldialects.xml b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/sqldialects.xml new file mode 100644 index 0000000..9cb6728 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/uiDesigner.xml b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/lib/mysql-connector-java-5.1.48.jar b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/lib/mysql-connector-java-5.1.48.jar new file mode 100644 index 0000000000000000000000000000000000000000..bd1c4bbc218ccff3c5a0dc9a09d248c54c577fd8 GIT binary patch literal 1006956 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/>!>Vo$`A7v#{1-;6Q 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

|DFJ;x?ImwN9S$Bxk}MYo_X$4NL7w;L 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⁣=84=u03{ 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

(B}sa#OuFJM-X{k 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

r};)I_XJN zu}5PnZTyePE*JX_S{ncCa3wopX#pqM<3%n?98~0v(T7hIiAC~cu{TYFIqH)db$$w? z{{6%YKb2R8Cb3*1;-02YdI<_B*PUd~#E5KS&&F~+N%ovpMD%^3pcF+j^<2G7D6Qn@ z68MH&Uz5Y0pHb|PkpA_a;02z#Blhp6iae0$j&W2)Gj(lUa&@z&^y z<4+6Y)~Fy;kCqGaG|ApRz+O+XcPfs5y^Ch2Cl+D}&C?QGBEtgQjUCvGLwFj`v6pPI z)Fs%phaD{P;D+jl^a#7)`hr3<%vBQ;z`&{{Wz*T^xs}c6P z8e^ZU84kHx;AvNDJm+eO7pVT%T!lF5YKvp84oq{M#0*zwmh0-m>bttKhOX|csjD|j zxCXGcu0gD;>lAjfYX~cG4Q0b!CG1SsscedCIGgSo!DhQgvIVYD>@t^iAhaD}jKCQE zG^rXh7N_gOr83PV4Aq5Uz6UcfKo_R@Ucw@VK2qC8-@PCXmh{mS3*vG845?sqjP|ZE za+f?A4fL^kF5E1Ek@}f>T}o?<;rcjzyi~ur+)=-|+*&&_Rw9i-IlEY&Kqx?^+!yF) z(OVrpwn(2StO`;ZdUm;!oN_0_RcrlC(WlzG(Vx@T9EebS=>3r+T^{b4I&RXQ(2`=L_e1M!n~Q$B}0aj4J$5__oB+>`_bk6g1eo^b-@+5oTXMg&}CX=k+| z2lt2cb1YpVeU5&vyyY6sE13!^)bM<*AY)j`^=EG>K&lkf}Yk@3CZBR@c0*M`Z zA1k%?ooqXeCU+X$+G)7lX^ga;re<%^()Si!?k$GgTZqqnZkJefk6@EP;MxIfO7ZGm z!K;^BDm`i2U{ou$KX=Q|_nYk3YW7>&#zO1I5~}O_<#bNQ6l}IfZa(s9owf&dK0@{M+tGiBWGkfA)Eq2nWxD^+NS6& z5vooz)m0)?j&?LR0-+k%O+>yxnL4Hs3KpnU0M0&V4)>+dBgHKAsNf;}eEP07@x9Pd zmhw=k;w$p%$mMX9Mk zPwnTwpFT!26(+WH`(!HpEQ3B(|L;GIB^9DO@?(1yJ|@3PA(Hr8io3?d=)qm7cxsqc6WAMhBFjJhSw_^jm5k8fJWm3+R{I$ed^@;kf7otT2G%N$MqFK#W(2c=IHMF z9z9(D#(39HnCkk4w(?&w)Abu|;m2@|>rY(oI*#>3Nk8CL@t|AB!)_NIb-VGr+l#l| zE%CX#l>-GiXs$2P7Rkene0{OLgyw6!a~#qGG5rGlLVA0plQvVPT|{XQIBDx;nqaDY zctO9!K7IZo?d(b*C9AG0ow_c~IFDYcFSF58C;CP}ls9JUr6}HvLvZ&=X(!0u6SZ8Z zu*>YiM3)4}HWFu^d)e4ALU%%JF;$AMv@kEJ_zUxsN+9iAUurbE`$KaNK#qGLqV7Rx z;2xZIzTe0J|3>n#U8)hu!*VS3wYT(0|-a6G9*GE|e?cDjS`xPi`~8@$ye(Bw1*_Fq_*`NIH6xW&>Qq>|dU3|0TJ1N*!L9fx>OB+mzwhef&wO{Kn!1f$`kly0xAR`Nt) zqDu`UcSnP%V}6H?)MPj6q`z~=qCufp9^9YGT0a_mM9DuPSJ+OrGnh(&+iDK5m4@5Q;v6vwIs0j{OEHFMyv?*_ z--BH=y%e&p)-zi{lfH|smZ1yxvis!oZW&sjco$j|C|(7Z`#RKfUyoMq8&K%J5vA^% zF~VJrG44$m=e`9K+#4~)eH(VUD+p=dO-TD5Jm%hxSKT}CuKQkm>b?)(xpy(RcQeCX z$#UFPEYH1%HFZD8+PU|#BKJPl)xDo}b01)RiTfPvKEzIQKgPzm53@<`BW#BINp^wz zX?B_WS+>IcJlo)Yfo*iZ%>Lzmh27_VT`rXaFlp1#^&4p84&pI%(>D;1hwv(5(r-|h z(ESzCYAMJruw{)Q)(xjfTk0U{v77W8)!np`Td`HT@KYls3RMmzT$NgSlx8nIO0$<9 z#q6a=F?;Dz%wBpFvzH#l?4?IBx%6c0X2Ap2T7+f9@mr*04=PJ6+SROBBQmi#2hSTVNB?@(j=^Q5F}~YA}@)!MWdt>VB8d?0bl~-$yg|2WaR15S`s0 zq1gQ~dbmGFU-wry+5HU$xxd4y?(Z?m{ci%DpD@Gy3(j%>iYwg59HoY4F!ft#x^$e3 zKKe#El!MSy-z2Fz8U_a!uGVk0^~F}}n`!VB8Iul%=-(A``fKmcTlCxPZDWD0W*?86 zN((Vq#Mdb;lS-@6l+aox(0a0;WAeGC+mc=IFt|Jl!X6b-kA}t`9j!e^+D;R98XDJc zrw)mo=3n|9b^|)t)&njnj#1(nRuvv^+OCq?vzUITHrd`wM%pUZW{pRyPVqzAYn)g4 z1^Ci0EWG=m04I1y%?rRcvQ$x6-yuL|6$`)=d~KQD7;&iv@JQ((W!|qYDr1B#ujIUy?Y2 zUh!D9(m}*>XbAn6B4P%++w}<7tA)3=7oo%e1Bpm4M8y`VJho@dT5J_s9o)Z zN)m+^VW|w$jFdb>pm~OZdxpX9ITb*avQO`39%{*ry;TeN=o^dGhOhB<`B6@o! zqrYbgMtY`Ul4mxidS+m{XC}_~oQ*}EIk?<2*HJl~PK^6@ap*y7dbqwrJt!%Y70$9) zq2DXlZx{=tJ%Une0`JqQC$_spi^StGB6T}v&`F-fX-kefWpjO(AS7!_%%+R3-%oW| zGdRhXe%~T2)P)9sJe%H`r)EgcV7i(BV-!pP<9@7wT(NUPvB~r;f>KVinrq24M)hT!!c2vsx3mlK9e9aC@#K zfL#mIa}DZyu0`B)9ol-XM;FhH=}E4BSs>Y12$---S! zYxQN1{-DzUCDj0SWJg9Z2eUR{uakK?6)1+VSq+*R?6y5Kcxf*Z&(q?EcGTdl253m% zH$)Q|rsJ(=32!}zhMwos>TKrJ`H=pw-RaY9F12xuNa$ptz^ZhqF+CHC9sM#9{aXZM zN0IM&H?4xkS;l6czCVjskfE8A^JNxarRl{SaKwJy?0wsaG2-^RX3o{OX~@8EVA0SY z$+Y#LA`jY2e};{`SF%z~ir{Fmiv!3$@tT!>1TLZn-WCyeLg?X?GKq%!9+qk?eN#xG zo1nms5L&2KiU}E5GHZ`eLg`+l32nWMK0wjo*!wE{{-E0 z3_i~vsP6?Dco~{{b+q(y6nZ^q=k=nq*M|Y#5Qcce7~##q7;i2ndJ8bcTNl&3^)S;L z#o6BaSnSQiQg1#k_coLRH;%~Bc4(&`(tecEGTRvd7N?v6;Ovw$05M?B0I$?{Q4S_! zk4Vy3!E*gki86F7(;quQbN?`nk~O34Z5T9SnpTCf4AAfvrh$f$MNjpx{KbWCTU!@_Ngrq%+;R|_R6)|{-h)2X;)(vl~lTC zHoa>Wi>TV=JY|=&%x-!cBC2|nB=VFkgaL{5&D*2&RFF{jD7`4yqx2R>bsq8Dhn_PC zQZF$I-d@P{_Cdb4ADVmnBjFvG*1tAR|Jq2lh0)x!mYVjp`}ed%q^2+0Q5kE^TbdQ2 zJwxdD1nlTgPynHJhqwD(R!FYgSD_Rey!P7s46 z*o$t>aK_}htWpCD@SAW@--o4_0NJj4l zWHxYR*51A9usP|yyEHTNnykHhEk!^m4G2Dcl;o+|zk8M8ds@*0%kc#(VWmR4bt>VB zl32*4a_LT^zHlB9%8_S;IU-q=$wVj)66)5^G#HI<=hPc`0uh};bo z*7*Kmr3p$%)Oi14CEJ9;=^)}li@otfQLhj`MX>?T(nyu#B^e&Y2lyD9@il(H&lDQC zi3!|P&J+I3gyeC*wWPrVQ0bMFCs?LCMeypQ2$?;-r^ zJ%VH2raS~0 zNx_gO3+8`Af73>ib8XDu+<_XUHM!y@`PL zEgGbE(8!xkoi)#FhUIome~X%PG%E=`B69_Nm~{oboi+2E%*>x=&HPT*wYM}ga~ArL zGQX?8mr1;{%$&de7vlYW{R2nFVPPlXop5S=k5bBzREA|D$YW{9DBvKYfcA?1p+rU> z=^tn5(A11(`H;0kpJeYM z>`W0mv*zGL9@hBWFnk__eSYNmf+rqvQ2C!Z<@dMCkECSLRO(n!>evj27`_OVYEr4W zX(dLS5%auTIZPWxht{9-D_rU^dH zRHi3cn!=!z0Qj0i_qBw_*BW(wF*NfPBH?R`9=`S%?(2Z@zD}6xE5b})S1j@sV}-9L z*7|y(+}9Vk`TF55-vI3J4a7sf!8qg_f+u|?X~g4G4zNEZeTp(dc#r5`o}dl+RqBwO z_a{&!zDoUy8a+ceQ(&jXg_)LAER36qZ6Udb(xsCf%dV>2>i?{m{VZHZ%X8|uV|dkA z9G;x(m}*91som6NIf>?>+)y3yN@+p!a5lZx?GI_(W@}Z-Ih9yYA+`0ffWDYx6Nu#) zoMEdZAf!<1Szwv2HKL%PLqeYLNFSyJm28RdE~T=HHHe`pbE>UMix!=Ue42wEYEMOW!Y4s8>A;l+CCw zr2C6*ld!pH6TGp4q_VgIbqk265Q}M%vPHtr5=y4W3(6qY!i7azxRJL=&(*{y)yhS= z`cz@Fw+XEsqTynq6moSb#k%AKrJ7hSuU0NiDwai!vdnH6?U$<&SQ%Iu2xoxrBqnW78{q|>I~I673fD~Nv~L;sazqvV{fi`CDK;a zP8%)KuB@GQMog7%o?_L?YH6lYza+80B;oMqrG*K>oEPpVu&NshNnS3cMM9|BA(JLn3a0$r0tTF4{kp^k-i#DVG6 zHuhQPEG{9>oMK_RYs%2j`lepYrG*;F%zp9twc^ip!b{dJD9RnmcI7^7lHvU+@daCl zDTJX$6NVZ?80t&}eB;o>HxVs-)6vd11D$+lqqlD^PV>#fDBpaX?OTAkzKd{??_wu)&Q#`&$lz{J$QqT9OlJ7gBH1$29bnrc?^z}WZoZ@>%nc#a? zne2N`S>$_OS>t;_xz+coa)<8?WxMY^>=3*{HzSIRNpx2oIsy&CfUq89jmRSSLpQTzIisl$DL zs3U#H)iHjkll_W1!>_Az{9K*qH`FD5m%7aFQJ4F@>RNw9t?--bz5X2a0e?O9ZGWEn zfj?jU)ZbM7(%;Ov;pGvc4DXdkW_!_D|61U4b{7Wf-w2Tny9a&sZ^aQD+k=zz@5E^) zn}rqn_acYV7vpqs4Vuc_Y=i!T$g2o}x)2&E%0A+;gwRM;9)Kx@Mv6KddHRnchdL7V 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

N{l`$GK_hcdv~$D{H$wj!)b!{+vG0pv#OSp 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Ⓢ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≀=oJ3sC@=e`jYkr5RcRjXpH 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

Xv(r*5Y47P;(RrSc7<2Xkp%OB{~>u)9}n|0 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

w7Lehw3AD~YH>@z+=S>LOgmhJ5b= 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 er}G^mE-4An_qOd&0C)GX}pp>y~{fgTt-> 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%0At!$6umu^-qf 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Μe|1U9(5#dm_}&2$v#=bt2Ai;PAK05 z@2{U*p}(=VeGFYZ@(bo$Z>>Q=qZDXl%ueK7g0XC>SueF#*zySD!M$g9yEqHm5a6kG zv7@4aXSs2|M^bBW#xQqwhiUPkmuT6nboEKW1(@LjHckow@FC~ybh8;_?X$>mYTrt% zv)uEUyi#`X4eh=~6Ykew^PODAD_M*s5%^qK?khcor*&p81{#)s zkA;FoFGjyO_yPFaInQ$VF-Re5rj_YJpQ+#A<%xO`jmKxxtW{_xqdz{(QDdEr$r!{w z)()DfWkgQ=G7ZU7WPo+5M|O_zLQ1xHKvyPelh!g}=Z{f3rQ0xQ)c^j)Bf1zNck4;TLfYcp(lXwc%RFUkX-22%K6aqD)Y}^^ zfcTT>!?b)iO=bfM9^)scX}SHWem@hQ40-O!xRfd53svcqUO8#uk(k0wp6POLN*I7X z#ub$e>evte;t#O!dm9U4D{D^Flnj8w?Ou&4!KtdrO@v&JCJgdZzI{~i`unjpKD;f( zvS-gyUlVgfE2SQ5d)yOgf==c%SG(|y(1|u#?wH8z!eOol93c`b*VV7maNSdu`%lA0 zC?b9+Kcu#Xk-5K6(pl;xH0U`4ZHa8=r^&C;1O3t0b@tvxtS$uDw5S`sGxVSe6seiX zQf5|`{b;z}Iu~Ud5t7GlBF%UH4h!ZRX!Y<4I%3Rjf1Z<8 z9-v!DmlPxQZu8r$3Vp(=Lm~CP|CB0|$%uAkNJ%f*{ny#<+u;rbLtN0TKWX(~q z*f?9gpFESxIa@>e<8s-vt}kl(YO))5m;01`Cos!>av8Vt_J{#;cO6C4)X)?&$bh55 z0{@&4MqMQ=cx=>G&0=8smn!&3RNQ%G>-_a<%7RgH@R=BU{ zMx5@A*?NHZr7jEK!7zXkNR{4hZ1#5hki);Jv)a~Hr`J}~WpXD2DH9&#WM|G}b7o}| zoI8O-E<}#5cDw*XnuIG;>fx%3BTA%%e6dw=HJ_Da?jq^UWWl{p4lCpB;s?v8tK&5( zMcMhf;hYhZ(5i8oT5IIHwO+&CBu#5ois6ZN3|qw67QDlG=RR?0?QF4yZ%K$fajC$5 zC3ioPMQwM<<}ug3ktSEdCC-b>;b_f@_N~U9VsRvMOQ(#k9B=+<4H3S3*rgCTG_U49p`4)5OrO{51X!wdwv}I)~qCgLJ6GipM zgb45F6*r1AGt*S7vx=1jw9M$J7nUAm8?Wx&h%0N^4DCT~N~jVKvPEf|j3BRhW>w?6 z@C52Kzf@^~*BJOg1um=no9Kfs3Gf8IN+RR}3R8qZEhv?hwg6)Tud3vc6Iby_ySV$8QQ6!KX45?8YWNt3A6IwFS z#YjRI;?TXyqWUsg7&jviGRG|77&RqbCt1FwuXXEPAG@iYK-5EcKsbWU`rNdD81zLO zbffo4XW#B0f%F0wL90c}f-+2c4XZIy#FnC2jW6iNiycaY`wOKunn|WUq=L4~kafs1 z+ykwn;13&9(X@zU84}$#H}&OF{C>CrVvU5mQ;!(U;AzvOC#z7$V^BQc#qgr!A?nd5 z!JfbMjz@jv)(NvcxgS;6_G(mg+V)<9Kd1A#84H|r-AYawVY%`ape16JnXTdWxsS)6 zer{Go{lSu@g$1o$sqs%86H?)kUOHnc;Yl*o8M-({@Np zxuZEycP}Qq4XYQ-+3HqYkKJQA>!ueO%Of4xnR4<#53mW|WSeZ!1^`t<;@$O-ab3R) zA$j%^ZKHx*540V%W(n3WeN4ojAC&{zYy5WvBPEkmn{4o(#w{8(G(Ugzjp(@jhKxB- zQ{S`w<5O$tYjEg9o+2*eHF~)Y!3{?=ie6iV-&60yHovZ+&g(LU0c9r3%D$>ZuUg{` zn#2HT3`Z#4S6|wAgG(ntLQC6E@F;677k=QPF&5Ts%#q4&n(v7|AdPU;6PnU_=Cnhh zK%R$gh`Dv;&~SWGZr-zZEd=M+3ZIZ${&8%uT8lrlP|it>LX2%KvI0-BG>q z=OW^lV2l~V0dSu{f(?tjnI+I^`Y2Z2U4ZI6_%xyQ;CKKj1Ez%UB|HbNZk_sTHtQITsx051O?`u^k}aHu znaSeNI23smyD+@M!gvp`rGnl-Wu40^%>K^jEBrvVbV7k^2fAxd@$iu(8+)ia`vuyn-#l5iO9 z{on)svyN!+z%#PT#S<0l8hxjaSZ{Fg85A+;*y6^=`ki2Qy?JN)wzf#VKpl-l!t%(P zT~(n$)5ccEZ29Z&PwX<6gsik-zwzr?i9@VTQZA8exxgsE_7`0DDtW&3j?m(xy#Wi~ zSK*y1yL+etkFl zBYOCgVZL;<*mai6?G4b?FZVkJ*GFxJ&u}`=W(j{X@oaq#uTH5p-O+vmozk4nODj*A zaBDGN^&s7T7_t%si0=67ns!;ov~xDNP`Cbx9a2hhkgIkQAs1;1N8#n9Src^pD6(TZ zE}P;x#bSMd8De!Br2p*Dj(n4;4%AvoKd*;c-UI5)q?U= z_t(L*Vs7u`k5BQOC(l=hu9n%MfPTRa@u4ZgU~GaO26Opr@kvz`sa%x=Dl>5ozFLIP zqf|#Cx14%t&+Wu0H?#0Ht;v~Vmm49Qo(PeK&fsB!H4N3J-pe^<&-3-bbNkhcLT;s^ zGbn8i_KkI4syiHz*tj3U=yZtDy842uGU@2W4I^S=#+lX70O9wv4Gp8WQbEQ z<(yP!?Q#b1DUxvd>7~>k(>4Ut{sHg1-^@+=1pn8XFaSetbN-7xbbnpc`d=<-{Re|k zF>`UVbyYQURsS02{b$cpUDn}C>HcBQml1wY-2Vp|b$`EEC`lT3F|~788eD#%7+#qVJl(42IwNAVSQG!}88iY{~3ex}x?i6_ko$&bcYvDMs zgxh20yla>HWas87VD~R>A5L``%5Vl^_HYLxU)&vTqH_;&SWxuBdk|0!+XOppKM@E+ z!1&u!x|88NeTlgQpfiX8>bCW;Z6xxYjjNd?Urrqs*q6|J&YR)QeWI3jku539ra!*9 z6Q%D~(rcp@#NI~X$dXf+jCM4=v1w4KHg<&e(D#5Etx$6bsZFU>%0V$_QCG+7Utl)l z?QUnsfoCgITortl=(nig*=i_f8eDmfMR{JU=~!tZA3kJX0z@FdrvI)d;NmL-mU*%T zUAqYhTC@VK+rY0qS+p*{6H z?|{c3P{@0IN6QVaKU3&Atl8|MQS@zo^{GUwrkhp0;tjN@&h{|pp|9qd9f5VJDaD)p zYN|a}n}6w5`KzU)jK9c)*RMWh<;fkS8IO7D@0tdEoDlg7cL7Cj6fC*{@ne{sP9lCd z@#|=(lsGWO79=B`Y8YA{QsWE4FkNe$a?a#~AOQdLi6Gqfq1SZ2y$D&ic6TS<{tcT| z?*R=)Fbq|M%q76(`dt2s_z3HYVpF-lJo#}c=NWwbVWY6g9iBbi-_bLg@~iUXS)AKz z*n=bUtPbWL-|-%MmoFcz>}e-Olu_){AA+zQ0o8tk>Bs0ZAmJwmw3jiJyfsX1kWJSE z`4ASu(?PQJAlDDV2`N?(#r(9YKmopSDvGacHiSiY2Tv$Fusc#-Xc)PWM41a(s)|P? z753#d0y6JSdAA|86i$!1ov>=PS$k3T6vg?Mx z(u*^y5o(L_GAE$sC7*#fs>3fZJ-s0wm9@jwuk&L7D!orqPq5$27J!-u!1c&@K`_4| zIKBo)@i%{W5PJcSjt%UdOt`=C*;PcO**T$$yPN*L1D3m=r4WLh0Y9f9T7gnF&b$Yq zz%kRu&k_)3vV6_^l4mTh|BMkF1J{sfs3jZo$;tl=gK1-VvP0Cw(6MP{PCJEvlw|38 z&=K(8u5Ka=K)FtQF-21}5D=Pw!xUA`oZZcwzhWL-ogHldPjXd?rkAIlI>u+uI2mh3 zcky(w>;jm)EVUITSdfwqX46KXtBUkyGe$XMM%rOZ66fGl)mYxt9c z-_F_LHm06!@T((S-I8HX5)IU0|oLh#G& z1^7fm^vu~&NH8yZR062OJI)t_lA#}3@I<3E%v)iKVvb!A&&9|dVvc1}9Xjp;o! z`%36><2wh;xOXA-d^p3Z%Dw_&jK88$e5r#NZOSbj&d-0#={5fusHMl<=iiLYk+9jQ z57&Lm&Nf4;n^#&-Xt)Ccc(Y<$`wtUlS`q9%5`NFrUbe>aw6QoGyJvPhbWG)E%qGzqg|84aceXkwg*i%6i02*OYqe(3#UQ44AdCoYBrBPI zi@m2HwSf6!7nXw(t)h7kZ!V!LIeME`qT5#X?VCR9YqB4FYSLu!qB(Fx>|0Ft`d1`f zHed9|I=za8iZewb3%+QLvDczi9x}NYmwVTVT`?7Ct9+j>&^636Bj;R9aPz)!Afgr?NoL?uoie26w2u60mp%XWrvJ(3ata zwF8_wEeDj5rQsgSM+V0oNA-VS^v(UvP`s$$HPs(PDs7XcC*z*(TH{)#%K?Z6Ezt&rLfvA{juES-F-nEK3aWUU@zaW^%erOL4x_X zZHpv-8mlZLo5q*DX>c8?X=$` zg&s3Lo7eCs*9j-R-#|cH=fs`)ic;uo5c?ms-rd9B@AgEzYIJ$jy&o!kHh? zuldfgnVg^P~l<%C=~?5-nzv5ngS*rc<{qV14qVM=dTF zx=={-*gTZQ)-)EEvc@F=+8fQ`>V(siuo66iHPSx53)Zxh%EjKdg;t@*JnaeQ*Cyka_ zd^I99RrW87q_%!b`?4||b0)N>pbmc=#UhcoVyA>7Z=%*=hkuwJ43?YbS4O3iChVU; z`N}&<>Rvvr;6sQ;w{gCE(`C1(oV&~i_b9~i*mK>AWp58J z?~Qxz$*bV+TSU5j=OX6|0q}*<5n7<;sa)2TBm+XvK?hoJgJB7YC$=WsqJR#i21$Le zstN>QWAsL}&(t(V5SVuGVL(M##=lrpKVW{SpB|5?4Z*-pK$Vi8Fxhd7Tnorw3!q8O zKzOE26ip>%T?^I6gUNc9-yo;j;z;(OLwQi#8I)Xq(uoU7vd=;dG29P@9cmv(ZXXu7 zC6J{m=}c@rvN<)#B}!he$fv!7mGnfs_%6%sdn8b5Q!1tkA9jfoD%T>))2M81lk$u> z8OH@JItQxWp;SNgr`TF&K*WEqI{U6bV=OK>&F#fVlco3Lk7PCVPX5$g@73sjsrkBP zu9sR!U5tzM?U3Tb8Q2K4uY>pvswU%Np5~gc!7%K5?B~`eQ2iNd^GXosBLKi3+^$W^ z)q)I9KLuqL;-LJgWCW)p{%LA6uyYZwoCGCmH0DLQqHU3ZO@=iZUJd18Kl5TVcK)i&U@KI^?lJ`b7ciq!y90HRhn%PiiR? z>41*9X>~hlrS$o1;_Vs7+F2AOpeHj#vYd7Mdd4m)kA1xPQ?N}gq}sF*wf+AY0^ zenfi1sd>*cyM|sEFDYj!)wrk?9;+!9-f|LPMM+#$(}$r0o;OA7RI?JpuTw=-tD&JM z9J*)AF`uIssvXF|V37}@$N56sjcGy?qUjm$-mz0@Pt}{nFZJZfsbQz;Ylc$wDC~e* zUt{b8b0yh+Xdw7vrh>Uq2@-Gfm!{4vDOI9d&R{+FkfE;C2K)RPWoXTRHq|D6shMVe z19^T!xx@|fcil*x;D^VxSgQ|-P2|n;4f~Ygdv>^!{b_3vb{70t7Lx{PYsk6&C*;5K z#89Ki8`>{zOu?6*6UD!&2-U3Y%)A}!&BWa79RG_ZZvI0W^GV>muE$YArdLceVok1O z^k;fSh}HwfR)iR$SbfusTOR8vC`&#RIK#DwW$5R8Ki;-7%0mj7Q{muu9jEfM$x7sh zC1ui8_TQPSuFuB{!+_5Z{60u7=6j*YUw@$)h8$7SLfY{MF?^9n)%Bu(4RSSN$C|*e zhPI;&OJb)np@@oLD@3`;M4VxpGvN)6rbmCLtiMCWBrAu%Im=j&OzdN`Xz}!}t zNE*xxDl!ccd_tn8FHU_oS<5j{Z}0V7D{E&g5R}yJc?@}^a*mvx-^h69~3y6yCPsyP1$1od##1UqT~%_%tX+)h#-+(Q5Jd*TW+ZOL_8d1Hkx zSAKF0BFzcO4CcuUdoA%g6dnze-7?oVhpk?`=S)*RW$zw96OE^C|>6dvZUrgRdLDtyeVSLf|pF|n;5 zHuXulG_`vuP2YpXv3v9W^o%K*Tv_w-UBlEFyk;k*bPvOWHW>qlSH1rXcf&C`3j)Kx z-8?~9YjfxLkz(+gmcl(G)fD?C+nYslbY+ZunS{j2RF^NKwY=b=X5J;HC@7bFpBfVN zPQc5DuG!J`{nh%K!@_3^!)Me^nW%(dLB4F@hNJV$8wz{o7yJDy?cDKadOM#~uXLtt zGmDOB@N8f1YrH@rvrZr=1am~2CFQD+RFcW}s3y;Fn5^OQnx8OwTE{&rkUG4 zb>Ks%1PS?5G_8X7;J(KirFd$c6z;;#S#=6?e>8fMNeU%|-|s!~>8dKYICOD}nV&3{D28yybG$@wCgPKk23P*XQ;q?Lbup zd--STWj*`n`aM+fDknBo{zH0h%Zhu)cP6J{Vp<%bev*smQu{*un7XKR!=9OVhDB2b;2yRKZ;XQDz4GtSvP7^+`rXa zf^N2TS7$WqK*?p~zci4nGh(tN9M+`>X8nu}3C|gqp&iJ*YSqTUDeD6ZJVh8?J-kqJ z0O?%Fws>SE(HR);ke0<|U^2mv=aA*+(J)Ry#HvD%Ipqp&f=@taLpoMG`%1SQ1+mof z5{_3a*!P^y@C6&o5JqKp4lc6F>i@qwyAH6Xk}Vt&%Oa>)u&k&QyP~34Q9+8JfCz|y zSV9sY5E4uXiaquM;;M^%ZLz!d-h0LFs;japVDG)I`~FEtU~=!xjqiS6UiSHs|37o) z%$YN1&di-Atytw!^HP^{FMS?3!#?Rkpe(4?sY-hUd-J*4aa2eEPR|y0z^2IU8czCp_6bLGerOzKz2>FUpNvfA{0aUjOXB zzC*fWhN7Ue&A@AK28_&J(|bd5{~LSHKaSbuv1Q9Pm&i@`8aTEr_+~SDX+ib<>k1|h z%kl`-UYar`^J-zV+h6VW>Llq?x=Zkv18l=kB?Yfik@uJ+=o zeg0|H=D^8S8$Vvo*fws=ToU+z#gSecQ}G!@Ubn_RY!JakuBgk;%O-D4!(DzDEtb z+t#K1M)&Yq$%pEVZ2w$5Iqsmp%Yb9m94e@Tw^W$_EMrS@|L`{h?!O-x_j`6s^-VE( z1s$90o%QNU)lJk}kw_u$i&a&ZY9|GeL)IUrF6OtZGc)hwo)Koai(|5|!O~_w>oV z!Xnz$s+>^UZBn*(=kdQRYtz_1#lGUogv#>l#u=+zmOq?7tZ`W6y`C;HnhHJ6p4qW@ z@2q*78@!cFZm>nVp{$krg!Kn(d06-#k~PN}rBf(CZw?~a$(*V9Hj*vPQ$ZyPK)_qtuLD@x@R>72ubjn0?Jbr_Jp zxx?Amy45e9-7dDhK{|vQuljp;NxxtnVOP5j8P*xnqj6rsCy^ zE#hkIoYvLVxAyG`*=|DwdHH>wSL;1^Zimdg?XTV5c)oO4otj{?Tr`Pr-{emo*`4t{uwkyld&S_DDwVnYus0txDm#2FthD-Cnz` z=OXJD!ZJbCFD_kp$2!-(cm9CFo}0ZqCpi{&k8-XU*Jw}JhH5@H{oHKB(+b>_HU~!8 z51k$UG|P|100+W|q=l*lqafCz&S(x}NFVs&<#h6DRh3UwzuH zC0*ZC*dBU#uCzy!Q+akRw@vBoQMvrN2JWk~?>+oDt9qN&^?Z_#VdK!{*Is>oU)&b{*&X=bG=!OrJ3%sI{|?_Y8-t*Y`vnuR0>*V9vb2HxW~} zFKM(ZwfUpblars{&5d#R^d>TR^sE}+e^+FGU-++;JnK%o%-auYUd%og)iB{)$JxE- zm(Tsv?x?Dp(-1+`H-bl%;vDKOzg8jk?SIC5c?E)Klea!&IVVski{Jgk{0kg}(EUY1 zQkwA?AM>v&l=!QZloEev`kHCfof+Zqhx#|K)9cJyo!^aojXw)TRih)@pZhAM*mlq_ zFV)%SL#$fk#^8yXBc=RWpWL0+VDIMEZXUAl(ZNBslSZv>d-F_gMCa0%PsK@&jw|~>>d$$JP9&zvw)xy!ETjU7bHrHD=Lp~+1@`wo!cQgs|sDJI-YM1V*qEiblWd$#* zw<=?K-s~Xvh6ipoou8#`Gf*)&w9CR-snzeV?=MP({x} z5hooaQ|dljwz$*ES6LT#-Prjq;)1wbsoE2cjft_ZIOkvQCms5XxwCrWsbi-;fAXla z;^cqt#}88~t_MfXZD!Z@LRT-9TT=Oq?9bLAH*fZszW&0k2`vtmy0zb`;UDr%?ww1N z^NG-v*WWhq&WDP2qvRO-G=gBi2=5kwA^t4`Lwx`TA0{a0DJoBNhc7$;agDdg`Lzb+4%KKA30?_WkQY3)AJY0RYA3%)5%Tn_y_?C(nZ zHoiObCVzOKQ{(wlMojN^^N`)Q`=7f;6^6{ZSZe*NF=bqA+HI|JPc|WcY~Wv~|L}DY z#`S#fHR+h3<=|VTv5Sg2PP!z*4 z$EZOQ0-ZSZ@qfwt-p&02S}1x*1G*Re!Z2nHf(r!XM77~B$u}9~`iJ~3iTYiOS+(UYm^;L;$#} zL415`HLGi}fQAX>33_pjO)&loZvzS!Y4+^I=x7ZG(3s+yg||2{8o=OUZ$YQ0-&T@z zXFgEtQK&QOv!R;p&8|bnBitTP-=RDgN_o@UalsW?Bs-v5 zJagqq$oC9QCVt!SXf=7bN0iyz5~H-}MOdz_*^w7td*+)D)HQHVv~PLQ*)n8yT+!+! zF2vKm2R5zI8gMo25=RK*xH{3x4N3f`m<61h;Gh6zOC#YC0rs~j7xwCGJ zzvct@Re*=d8Xv7@LD)~hL+eH7m)MEQthhb>??{2*zFR2)hOzO{YT8BoEYYwGc8;Ml zJVy?L*BFEenAVkOy#*Y;!ZcyHLXGZV!jm=9>x)6Q!5Hbjm>^mh8$gV;={8H?ODu^> z_A(g<4`=+7kdAKnhHjv>b94_EbWh*zK5Z@RYQjDTbKlQ%pud^j zzzk?>81+PknB5T;qEw|KO;N%#Ft4nsOM!If1{szjQ>N16m2}*Nww`6)lokly!qdR5 z7$1ayyjb4qv_xDWO#)bnI4VUJmMRLCq$MiEKEmR1x{}>V2%FyWcu)t?*MBUz0@L39Lc?i=aXCw`eR?{b+k3ioDADI*##T>e1 z%y5XSrBzIL~TNenpuGdHCU2@D2N?4X65_1Ou!BYEIqRfuE+~(a7OIV`$xL_ zkwsn}py@fWJq83Llq}i%dXwi~1rs%obbBYY1-vK2BC1#8frmFR99lIU1of1i|2YFx zIYZ3}4wj%6z3b2vc3MWgY2Psi1jAv{x)@rE2iBkkE*D00akQ&fFtOuwhSW!$dEjw^ zS1sbOxzl^|<`ly1&V*B;E%|Z-9@t2sOw9;pm|nrfXvxGYe8atOTy`NbByi}g7-@Zc zok?%6p!GEoA(70O;n8Y5TUi7cOyX62JYx)xO>J5r7yv2*H2H>`EP9CS(l#Zj7{NP{ zGuEZq%@oMF2o~Gk@LPOqH95>5d&l9;N2rw&7st^)GKo;GPK`*!nQJlI!jO;*s+4oC zFGvo+6rw4TsCEnqc}a@N{iT?*rNbr4&_t|x6e(enc!^RX=ZaWwzs>Y03xl7J<&_5| zhHJ;47Q?hJ^i#r^rQ_CHqovp2XKB|p%9}}{!u(HCb^b!U;6u#W&H9iauixmk{oul5 z0Z%*ITr63NO;p#-bifoUQ{x>V>=Lj3Z_rI!z%~XfJ;NsXF<`q3WkRSI;}h{;0>=b4 zZ`-qTv(eM#Yz2b0l$v+@GZ7Kp8N3N8#j}V(yk^!25_v9_ zZQUVj2@{t=4{%&Z4?7I&nax#iUu&&HwVr8UBbP*6ITzb>xG8S_A4oeCSC-tThWqz52am*OHDnlk(fBS3rz`@1!$n z8&|TUijBcPq6r~)xVELt@rv6qAg=(Ko;@C|W~`65?B{No-_gI%a+JfGRhv+>3HP zB@Km`U)ZYhrRQRBI3Q-B{Z*M}Ogv71b^G|e6p{nYhR>qM>s1dX49>R++4q5nNDh7T zUS0>*9AMG5Te>3)R*79Jm6>^pAjcH;2)l;HHh^=cv%oH%Y{;of3FblO)h#8JNJiVI zyrokHVLUtrHod#itp^LPA^*v4GUXP1{rm<)_b7U~Gu6Yldzk_Amk86;N=b+!%{v`) zHW_0)+NkJzDC!5ys67_*wEJ%mVupxg_k-wH{JP^#DRfX5mW1sSqp6 z*K{zV(&kq^VG_AeaswkQvHBV!Gr)l@6ModbD{zH1dt6WNUekyvK4#RSvM=# z@c~^IimszEy%TvcS#~anP7i6^{#8OwD~txZ>BE!wFx}b3Y~1c_h7cl_M)rb+Y>9Z= zWZo|hX?5Cc!wwnH{^^+ukn%7?%B!h-kZsu^_n#bhcnBb^8IXl4K1dIC$gRFj2b0~o zaSX_L>3opw*dfc_bzQpANK z0J4BFe!R!;v>) z;8EyEI!;PEJJ>!*V%x zBC~kz3hQW?4N187FhY~LVpku_!MiK4i!PKGd%q%b7F#8x>SvA%&w$ViiytqFR2^wK zsikb=+a`)y!+9s+GzZvG#^D>f4-2;b{IKWX|d42ejY^9P}ZcIH(^+}6b1cGD? zI*;CN4h!Zd(bdKod;@13`)`{onS0>95-^NAQXc139}74TPLix{KWSQG(T)bY6BbME zo+Q_rS3wMmaLxE=HUEY4(~z98%v+8uV9`DWHd18j6gh_%6>KS}j?{)=1$0M8p36{t zz}Mr5r9=`jvK4HFYx>=aw@#C7mxEv*T0{4KM+A3#1jbxuV3GFNRo3^#$-;ghu>(mb zqryn2*eaHvBplN_No|s8-aOCoHA_A3q4!D2G;L*f2lDgi>IHeN>_A>fk`(Po!8oL2 z>Z&3OIk@R(3v73o#vio>x)O%b~4Yq->MUHv+OI$emt&bxZU z8LgEoqI03CvZgxxEH68QOSv~Tx8YH$pmlDP-R5;-GAKkUIto<dy~I+bS&kDp<|7BpO*A=3Df)a8EV?TN+eF9$OJ1pip4ZKLI^tFW1& zOY54QguU%&`>C-1Fc1r$22`_TGF~e74w!UdeZpZtS)l{y6@&9c7RWS-oLqgt#3Gt_ z-SU<#vK@j4h#GrP;?GUrrWfV`*EtaNM_eqFc-#09PRZzhA##Lt zO-bq79Qb`x#bi+}BZs#1x8O2GCq>YQ>%N~>4?T7Rjsau9_-HkI^4Xy+Fb4wMY*6Z! z`fv+znBeICb9%-BtgBZg!2kv<>xqT(y2BQ8v!%J|5cxS)f%LRI{kf&c;i2s6_}As| zqidL>qL6)~1Mc7t9N0L|haGo)!70D+b5zy+@-YFrV+}_epYj_Q0ry5GQM9zz?ig>F z^BtHoJzeLNDQh}|=ti{Z(vV#hc8YcT*P-(;cuh7)>)Bd{YZ~0KWJ*W_=CxSa{3;qS z4rx|;;pSZF{~}^3V=+UhI$|KCGn`L_XKn8M`(EXb}7??FdVEX9u&uc@yBrog5k}F@c`~ zFkNK(-Pb~3u6dHczZ%;AAUa=A88$~}v=0QZ!{gAEtmyo)MONpaZZX9c&SePPxQlUu zAQ6arZ!QM2b583u^`qNCu4d$&$ok z<%IA4B4^Lmz)tA#w=9i;9E7v-I4ljH5idpFT|BP5G4|YctfR`n8#Ti z4%dc$R%0@zBhY!NOlZFNff#bCOaJ;G(R)`AG&@mRe?OE35urm-#Uy*%y<1L+LLHmn zJ36v41=nN@I~)mUkp_{YE}PTI);{^WqyYk)ZLl%g%uZ=IP$lskY5A{}qiqwAty#R; zv;eK~Z|qpQaTTH_C!Sa^Nw+B9ubuXC3C{a+bKi>c)eZYmL$1KhAUlz*=9HcFhrOl5r;}sB~(_;)#RVqB|o$; zv`H*Xsvg!dJt)cl7-cCDuHXW|5@3WXA(QU4nG+{kq#RB|C07r zr`K^538y+YVIl}Vs42Sav4cR-zGP!R(=FeE2`B_Neh2Azb6&SF9;!qssl zLLIZo)T^I^{WIW4jxkEM0)AsbmWN3aq$-RsY#`SP22 zU`vGc<{0vKcXSv8hWcP|p{(-i78ZsyQUfL-84d|Yg3?OTs&pv8NCJ%Z{;F+kfW}~( z-OT29m3A5e`3NL!W>z~HaJ{j=qVxHv#|~GglI*zIQ&hwzhJ?8|=Ahwc@S&%dT72^bQypYb6gZ5}um^5w zc&>(2cfH)pf{PQR#E*BE%EhoWj!`lHv`e*-z$=6Kn%;BpIl#m$S-OVTKpSp=2{rk5 zrue!6*z1KO%IO8!`xE}}QQ`3LJUT}iB= zDJ*#@BKyrAYn;eQ;Y;vGbT+5-*`H%zwt#f4@V)xU0(9vCeCYH=el8Oq-5DWNCP-Kg z#S*Xyv9+$uggRsh$UP}L*>j!=W|}B>^-fKd=uDMO3HZw%lejS1D8N88^A`Z zWyKW>m~;fXfP=+4NlUhdT{-a$(L5 zekp1kt3fDYszmNVN1EmBWb+J%^K{9omQ)8lxo-)pTpY?CND=VFZ62SCg zPg`ICIJ!fHc!ur77D2zYYJJsT#$)3UNBU_WB>TdT&NO~9xR$twHAcmy;66e>TH-w; ze=&_Eu|$tY#HI90$2=5(I1K-7c31Ut_tg!&fqWDJKb;dFGnRp_59};DcKUqGl(Qtk zTNk)=B}@4!Ok7F4j9kQ*UVJXEM0CMD_N%2 z39jQj@4YigECgGjjnHqVWw>UJB?T<2*!K|JPs3WKi6-ayKLKv`gp!N(kncCKojS6s zX#+e~SjJ%{-P7fLnT^|__1n-oZRaru&4HT>x9TK)8AvYqOk!v}?65gZi+BJjN#NK;t{Z#OZ{_V37?s9=Wm$$MCUu#5F)1 zUj17^6PqAx*!6NX)$QPTZfHX}7Q49r-q7?8bHeovJxwFe*F(86Sx+33!7(oC;TUpq zAJu{;D{#$xCY)j@$vQ9vBhKyjk(mcQZ3Kd~*yMAjeEp$?Tu44@C1*uWm2aK9&b1W? zG)N54F?;7#TzI}2a$$;8#4h0G$A>RpMo8v{oG>k5)oomWWLKRFuW`*K;!1GiGc!!n zfv$TPc-S}6r9;?7i>}&XPpt}ASRt`SXBOp8m{1atS}9FqIW0oEA!%;R7X?h2Twv)& zb;Hs3EKoz#m|dhonME_ftJo0(Dnf&;Au7Gh9`%g{o4j+Bw`Yg=&n5B7?f5iXWmDm5nW)b^wz*zE6ceI zB+ULK?Wyso+997PEVp)%e4A^sNOt`e7tu>r1Jkk?8?kc%rodqS|#|%N| zk8e$9!%fpAO_-V>So0@E7Y>FdCPNdn<*vx$#?qa}^C7pd$RdQQWVS;x1l;dYt?Jg8 z!fX(A(35!R9E-u(<$m$zTgtYcDA8MFIw+RRGY`$gBYlBoi;IgI+9SH zRbU2>?~2eb6}m`60ho%!nV$}}$=x1EY~ zA0_U@r{;j!#T=yQde9S9Vs=>c(-U+1X11mi6FH_^{Mz-BSx&MyIefx!pBGp{jq7gO z?;Cwsp<;05l;OUPRL)B_nycV%@zH9;JGgQCA>QMfw4V#2dp-uv2%yq?XwJKsh)N-nUM$l;Y4f=@OWS7y2|}EzkQ>^n?qT2wi?3M4b|&M}$-j@s=q~U-4u3&!X7%R9B6&~v z4_vbE9*VtqoTwM;uLg4^_l3bU5;*MDquZ%9wGqFJMf^hNjQj8BYXB!HyG?&g=vdnu zZR>~7noeb2I>AS!+s-8Cx0H1A*qKso#^;j5Jg%6B=|&}=vxq4KOQLj%B~;_K9mu+X zS-B-b6FPI$^0Gx#y=7ucc(Qtq8Gaaw+XYWe2U&fu^YIX?@MveAh3`h=zdI)w)9! z?DHZ~$IRs55CsIDjSn4Q6h7ocjz__iuOv>LU`FISo{e3;LfnIx8R#VLA_Vy+`6q)J zqzH#$?}(g2C!wqv^t(xY($_-d&-l<~sfABC(NzkWP$^Xf^OG4{^--PZ=Z< z!x19dn8}3Ea$VCW6Y%Sm_|UGT_A_%hz9^X`r!|W1HNi_IWO3LX3>GRm3;NdPjvR6g zS|=~mKrCi_w3;twsdOntlC&~z$FqCIZnN&$6%s=PK7xJYqt!URG}jazJ_#xkNJ<9l zYZWeul*-d0rRWnRs6WHlgtZ2@mOD%eQPVxmGR9j@aGPnC#x zIJf`z&zhUy+y+ixigVjrUd|AOTz8`axn>*9EjozA!#HPz%H=v3)4@nj1TWtI6eADM z>W2$H=7VP$c<4ORub+5%`luz!3|)MvRO3!Xa~G2mUw*)rs5!eP4nBaZ^-j;*`)9caiqtURbj-Ts%C zrf4|xP|VJ+_laC&_7D`_6or$(&eVTOik**cr0Gmgs5>ZY@ESaHpGzMaO^kgtgHCN_ z8Qo7=`i~*~+{kqzDWIeM_Xcar={VcOe0@oMqY8=tzEsv62`PSSONG{?bo~DOYNc%< zt}~J|v=^^fjvoziN%5<_%w3X5sBSFzyo;Q$#T7dyftuQepUM(nPFO~dYS#TOSjfl> zHL8dB)cLj+vizSOov>eTwm0)0*hzd4M6o}tXfgXw`*p%RD7R(};v>i_w&*#mmA!?` zKkeNK?~^xHZp6FK0IwI-;rcWB{*isB0Bp?JYfW_v*?z*)llEo(`{l(A zFiu1JQ2Azjw3-(+EMyF~$O99y^{*pe*F|!GT-HRFhdR}^kc{6C6QV9}kF5EGRy{$h z=oR(6I+hZVtCcMF#)LHeVWlH^AYI2GeP8!yNGs9S2g{!L@VxSyE2p zWUdj5Z#W>HS>(c?LYRoKQ5Ut9aLPD63Ym>YhX1H<{67R}k$E6do77e%(8}x3mV3_I z(Hd+1K3Is;Ms>>qG<|--80$sg?s8@di7B=dCAPSU+4d*JDOB_VgJ?lIzT47L7z|?c zoR1NXc=8pN!1)cs;d`+J=NM7%ZR|O&S1b+&VUX+g7aKr$5TmabhCX+R=%Rwgwd)Z0b-W}n=%?f>ITSH(N3xt50Wt#94-%HZ zVEx<3*tS~;*`FDWkDLUVCz3Aoh`QLuyx3;Q*cWDB|4l440j8^Eq^n+cFi)l5Cnk}$ zTIDN^k1x?KcB;gwSJQ{0RoyU3Xcb=U%15Ol=?HJ!FCvoa2DBM6rl-KJUC~2&euWQ% zj0A4(B}OH$HO^*R@XLigfTp{xX!{!WM$+CSEQ#hnn%!c6mzRq&=WldOhb93vLv zaJ<pY~lO;xcG%u6U32{=8YZMmu2(fjB&78+}3q6XjEa9Wzxc~tYc;lOE#kAh#|Yim zsh(XcV@xzhdX-+i$L_U^j=$RoPvW*MF*l(`U+nA9tM}u_E#lF+-%xV9Y6<_#9P5N@ z<9%2Og7mYDGeOUX%fb=37RiR*~9kvS(&qhh(<-D9e3^TjK>1 z3~Acjr#|FkGl^Y@agb~v*Bc&5Ey2en=_{XMVrzr|j;_US_rxMPa|EP40~!r!x(kbK z_y!Z(Q-1hK0<#6d7k*vY4W~N+IGwi;0%J7iW3O>;)sWh(Ma z9lGw}w*Xl{-!bHZRvcwFnKP_vT1dgyDOMF1WaI94!DIvg^wA2(UoE6CMwm=jK=dSN z+cSWqh3>(O=?$8EN6Q$b9H)^sPW({gAm+L#>_^a>hx48IkS+Hwqzy@F@`x>9I@Z!u zOIup=G4Z<=!r&9_aIXepSQUaIda1JAo0s8dyvo$yrmB0QD<)v5M^Zk_wHF^zk#i)Q zTdu`3fG)x6FV)@IC{HIZOhQapRJqS?5+~pFaXSQ~Bd<1qMvaeFlaHGV%tu`%WH1G1 zt}RekTJ(?z^JO>_JY^UoCLGtdPNnA<4jP2s^c-0)f)$`d-CD6$bj9;#>)SnDZ_ZSe z!n}{cLC4*q=>Lx=xI6AwH`R(h(6wG0WWNw@q$_4f3>V|0)wJo)N><{CA%9c8*Iu2L zgr<;ULOOq5C+=s^SsTFDt$&Lc6f#8uqgxyO8c<~`G_VXBa5c7{M2|LNR)C)3ohU#%B^RKs(2QNa3vVhncgKKDLySes7nIHlr@w-OU3J9WjV`!1ECj~V z8u2yV8Ha|k0*1@t+xFz@41zeMOxw=5Tu4v{Zn_cG;@%_K5sg)+Y+^Ev4y%Bohxn4C z;~1dWl-HeHVp!hNYR${1pfkt|rs#m=vl$f9Sd{Oe;+An9irGoT9CHU>I9&h(I$hgz z>wo`bGs2d{X9xcGLWLjS(DpxI=kzA@<2e=rb4&+JEhAog~wGz;b z*<06#0CWihRIr#Ew7WV1t{I1)*+Cl~e(VwpEs$%g=_r2oGImhi^j%bNsq$5bdPtBA zBiCcI6Lc;e=S^I}Q;c3`Lto)rtMOXFPJn~Nx+A#kcvZK{`;&bm@~#+qV%oZr9Scvtn`SV!W$@q)Dcm}T*>TBs z%5c=;`l?e{UVlMkb*sGYxea7>!i-Aa?KS;4J7y%VL_u)qA08lujiI19BUs2%`@&2W zLh_=AIN!qa6$J`q$tj-s3k<3fzbJb_|BHmAv=YvP`6~p)C4SYs#II6Ps2`H{8~&7h z!@i0hB4A(ohbbfxU*hNbkgQhccOzfpN2Gk+(eP`0Yc&(te$I9BPy|V?zir^1kDu + 4.0.0 + com.maven_javaprogram + mybatis_demo + war + 1.0-SNAPSHOT + mybatis_demo Maven Webapp + http://maven.apache.org + + + junit + junit + 3.8.1 + provided + + + + org.mybatis + mybatis + 3.5.5 + + + + mysql + mysql-connector-java + 5.1.48 + + + org.junit.jupiter + junit-jupiter + RELEASE + compile + + + + + mybatis_demo + + + src/main/resources + + **/*.xml + **/*.properties + + + + + + + true + + + src/main/java + + **/*.properties + **/*.xml + + + + + + + + + + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/dao/UseMapper.java b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/dao/UseMapper.java new file mode 100644 index 0000000..60eae55 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/dao/UseMapper.java @@ -0,0 +1,17 @@ +package com.kuang.dao; + +import com.kuang.pojo.User; + +import java.util.List; +import java.util.Map; + +public interface UseMapper { + List getUserList(); + int addUser(User user); + User selectId(int a); + int updateUser(); + int deleteUser(int i); + int insertUserByMap(Map map); + List likeSelectUser(String a); +} + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/mybatisUtils/mybatisUtils.java b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/mybatisUtils/mybatisUtils.java new file mode 100644 index 0000000..b364762 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/mybatisUtils/mybatisUtils.java @@ -0,0 +1,28 @@ +package com.kuang.mybatisUtils; + +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; + +import java.io.IOException; +import java.io.InputStream; + +public class mybatisUtils { + private static SqlSessionFactory sqlSessionFactory; + static{ + String resource = "mybatis-config.xml"; + InputStream inputStream; + { + try { + inputStream = Resources.getResourceAsStream(resource); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); + } + public static SqlSession getSqlSession(){ + return sqlSessionFactory.openSession(); + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/pojo/User.java b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/pojo/User.java new file mode 100644 index 0000000..6328292 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/pojo/User.java @@ -0,0 +1,46 @@ +package com.kuang.pojo; + +import org.apache.ibatis.type.Alias; + +@Alias("user") +public class User { + private int id; + private String name; + private int numId; + public User(int id, String name, int numId) { + this.id = id; + this.name = name; + this.numId = numId; + } + public int getNumId() { + return numId; + } + + public void setNumId(int numId) { + this.numId = numId; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "com.kuang.pojo.User{" + + "id=" + id + + ", name='" + name+", " +"numId"+numId+ + '}'; + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/test/mybatisDemo.java b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/test/mybatisDemo.java new file mode 100644 index 0000000..9f4eef9 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/java/com/kuang/test/mybatisDemo.java @@ -0,0 +1,100 @@ +package com.kuang.test; + +import com.kuang.dao.UseMapper; +import com.kuang.mybatisUtils.mybatisUtils; +import com.kuang.pojo.User; +import org.apache.ibatis.session.SqlSession; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.List; + +public class mybatisDemo { + @Test + public void test() { + SqlSession sqlSession = mybatisUtils.getSqlSession(); + UseMapper mapper = sqlSession.getMapper(UseMapper.class); + List userList = mapper.getUserList(); + for (User user : userList) { + System.out.println(user); + } + sqlSession.close(); + } + @Test + public void test1(){ + SqlSession sqlSession = mybatisUtils.getSqlSession(); + UseMapper mapper = sqlSession.getMapper(UseMapper.class); + int i = mapper.addUser(new User(5,"quqiCake",5)); + if(i>0){ + System.out.println("参数加入成功"); + sqlSession.commit(); + }else{ + System.out.println("加入失败"); + } + sqlSession.close(); + + } + @Test + public void test2(){ + SqlSession sqlSession = mybatisUtils.getSqlSession(); + UseMapper mapper = sqlSession.getMapper(UseMapper.class); + User user = mapper.selectId(1); + System.out.println(user); + } + @Test + public void test3(){ + SqlSession sqlSession = mybatisUtils.getSqlSession(); + UseMapper mapper = sqlSession.getMapper(UseMapper.class); + int a = mapper.updateUser(); + if(a>0){ + System.out.println("提交成功"); + sqlSession.commit(); + } + sqlSession.close(); + } + @Test + public void test4(){ + SqlSession sqlSession = mybatisUtils.getSqlSession(); + UseMapper mapper = sqlSession.getMapper(UseMapper.class); + int a = mapper.deleteUser(5); + if(a>0){ + System.out.println("删除成功"); + sqlSession.commit(); + } + sqlSession.close(); + } + @Test + public void test5(){ + SqlSession sqlSession = mybatisUtils.getSqlSession(); + UseMapper mapper = sqlSession.getMapper(UseMapper.class); + HashMap map = new HashMap<>(); + map.put("id",5); + map.put("name","quqiCake"); + map.put("numId",5); + int a = mapper.insertUserByMap(map); + if(a>0){ + System.out.println("添加成功"); + sqlSession.commit(); + } + + } + @Test + public void test6(){ + SqlSession sqlSession = mybatisUtils.getSqlSession(); + //获得sql + UseMapper mapper = sqlSession.getMapper(UseMapper.class); + List users = mapper.likeSelectUser("h%"); + for (User user : users) { + System.out.println(user); + } + } + @Test + public void test7(){ + SqlSession sqlSession = mybatisUtils.getSqlSession(); + //获得sql 参数是一个映射的语句 + String s="com.kuang.dao.UseMapper.selectId"; + List objects = sqlSession.selectList(s); + System.out.println(objects); + } + +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/resources/UserMapper.xml b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/resources/UserMapper.xml new file mode 100644 index 0000000..c3bb61e --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/resources/UserMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + insert into cakeinfo.cakeinfo(id, name, numId) value (#{id},#{name},#{numId}); + + + + update cakeinfo.cakeinfo set name='xiaoqiqu' where id=5; + + + delete from cakeinfo.cakeinfo where id=#{id}; + + + insert into cakeinfo.cakeinfo (id, name, numId) + values (#{id},#{name},#{numId}); + + + \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/resources/mybatis-config.xml b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/resources/mybatis-config.xml new file mode 100644 index 0000000..c322acc --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/resources/mybatis-config.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/webapp/WEB-INF/web.xml b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..9f88c1f --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,7 @@ + + + + Archetype Created Web Application + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/webapp/index.jsp b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/webapp/index.jsp new file mode 100644 index 0000000..c38169b --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/impl/mybatis_demo/src/main/webapp/index.jsp @@ -0,0 +1,5 @@ + + +

Hello World!

+ + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/util/AuthenticateInter.java b/src/farm-core/src/main/java/com/farm/core/auth/util/AuthenticateInter.java new file mode 100644 index 0000000..20998f9 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/util/AuthenticateInter.java @@ -0,0 +1,54 @@ +package com.farm.core.auth.util; + +/** + * 密码编码解码类 + * + * @author 王东 + * + */ +public interface AuthenticateInter { + /** + * 将明文加密 + * + * @param password + * 传人明文 + * @return + */ + public String encodeMacpro(String password); + + /** + * 将密文解密 + * + * @param password + * 传人密文 + * @return + * @throws Exception + * 解码异常 + */ + public String decodeMacpro(String password) throws Exception; + + /** + * md5不可逆的编码 + * + * @param password + * 传人明文 + * @return + */ + public String encodeMd5(String password); + + /** + * 判断是否是MD5密码 + * + * @param password + * @return + */ + public boolean isMd5code(String password); + + /** + * 加密用户密码MD5(password+loginname) + * + * @param password + * @return + */ + public String encodeLoginPasswordOnMd5(String password, String loginName); +} diff --git a/src/farm-core/src/main/java/com/farm/core/auth/util/AuthenticateProvider.java b/src/farm-core/src/main/java/com/farm/core/auth/util/AuthenticateProvider.java new file mode 100644 index 0000000..b98e697 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/util/AuthenticateProvider.java @@ -0,0 +1,50 @@ +package com.farm.core.auth.util; // 定义包名,表示该类位于 com.farm.core.auth.util 包中 + +import org.apache.commons.codec.binary.Base64; // 导入 Apache Commons Codec 库的 Base64 类用于编码和解码 + +public class AuthenticateProvider implements AuthenticateInter { // 定义 AuthenticateProvider 类,实现 AuthenticateInter 接口 + + private AuthenticateProvider() { // 私有构造函数,防止外部直接创建实例 + } + + public static AuthenticateInter getInstance() { // 提供一个公有的静态方法获取实例,实现单例模式 + return new AuthenticateProvider(); + } + + public String decodeMacpro(String password) throws Exception { // 解码 Macpro 密码 + byte[] fpass = Base64.decodeBase64(password.getBytes()); // 使用 Base64 解码密码字符串 + String str = new String(fpass); // 将解码后的字节数组转换为字符串 + return str; // 返回解码后的字符串 + } + + public String encodeMacpro(String password) { // 编码 Macpro 密码 + byte[] cpass = Base64.encodeBase64(password.getBytes()); // 使用 Base64 编码密码字符串 + String temp = new String(cpass); // 将编码后的字节数组转换为字符串 + return temp; // 返回编码后的字符串 + } + + @Override // 重写接口中的 encodeMd5 方法 + public String encodeMd5(String password) { // 对密码进行 MD5 编码 + if (this.isMd5code(password)) { // 如果密码已经是 MD5 编码,直接返回 + return password; + } else { // 否则,使用 MD5 算法对密码进行编码 + return new MD5().getMD5ofStr(password); + } + } + + @Override // 重写接口中的 isMd5code 方法 + public boolean isMd5code(String password) { // 检查字符串是否为 MD5 编码 + if (password.trim().length() == 32) // MD5 编码的长度为 32 位 + return true; // 如果长度为 32,认为是 MD5 编码 + else + return false; // 否则,不是 MD5 编码 + } + + @Override // 重写接口中的 encodeLoginPasswordOnMd5 方法 + public String encodeLoginPasswordOnMd5(String password, String loginName) { // 根据密码和登录名生成 MD5 编码的登录密码 + return encodeMd5(password + loginName); // 将密码和登录名拼接后进行 MD5 编码 + } +} // AuthenticateProvider 类结束 + +// 注意:代码中的 MD5 类没有在当前代码片段中定义,应该是在其他地方定义的。此外,单例模式的实现方式较为简单,没有考虑线程安全问题。 + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/util/KeyUtil.java b/src/farm-core/src/main/java/com/farm/core/auth/util/KeyUtil.java new file mode 100644 index 0000000..f2f607d --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/util/KeyUtil.java @@ -0,0 +1,22 @@ +package com.farm.core.auth.util; // 定义包名,表示该类位于 com.farm.core.auth.util 包中 + +public class KeyUtil { // 定义 KeyUtil 类,用于处理与密钥相关的工具方法 + + @SuppressWarnings("unused") // 抑制未使用变量的警告 + private static String errorkey = "ERROR"; // 定义一个静态变量,用于表示错误密钥,但目前未使用 + + @SuppressWarnings("unused") // 抑制未使用变量的警告 + private static String CODE_C = "SADFSEV"; // 定义一个静态变量,可能用于编码或加密的常量,但目前未使用 + + public static String getFkey(String mkey) { // 定义一个公共静态方法,用于获取某种密钥 + return "NONE"; // 目前该方法直接返回 "NONE",表示没有有效的密钥 + } + + public static String getMKey() { // 定义一个公共静态方法,用于获取主密钥 + return "NONE"; // 目前该方法直接返回 "NONE",表示没有有效的主密钥 + } + +} // KeyUtil 类结束 + +// 注意:这个类中的方法目前只是返回了 "NONE",这可能是一个占位符或者表示某种默认行为。实际应用中,这些方法应该被实现为返回有效的密钥值。同时,类中定义了两个未使用的静态变量,可能是在未来版本中会使用到。 + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/util/MD5.java b/src/farm-core/src/main/java/com/farm/core/auth/util/MD5.java new file mode 100644 index 0000000..46228d3 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/util/MD5.java @@ -0,0 +1,358 @@ +package com.farm.core.auth.util; + +/************************************************* +md5 类实现了RSA Data Security, Inc.在提交给IETF +的RFC1321中的MD5 message-digest 算法。 +*************************************************/ + +public class MD5 { + /* 下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的, + 这里把它们实现成为static final是表示了只读,切能在同一个进程空间内的多个 + Instance间共享*/ + static final int S11 = 7; + static final int S12 = 12; + static final int S13 = 17; + static final int S14 = 22; + + static final int S21 = 5; + static final int S22 = 9; + static final int S23 = 14; + static final int S24 = 20; + + static final int S31 = 4; + static final int S32 = 11; + static final int S33 = 16; + static final int S34 = 23; + + static final int S41 = 6; + static final int S42 = 10; + static final int S43 = 15; + static final int S44 = 21; + + static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + /* 下面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现中 + 被定义到MD5_CTX结构中 + + */ + private long[] state = new long[4]; // state (ABCD) + private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb first) + private byte[] buffer = new byte[64]; // input buffer + + /* digestHexStr是MD5的唯一一个公共成员,是最新一次计算结果的 +   16进制ASCII表示. + */ + public String digestHexStr; + + /* digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值. + */ + private byte[] digest = new byte[16]; + + /* + getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串 + 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的. + */ + public String getMD5ofStr(String inbuf) { + md5Init(); + md5Update(inbuf.getBytes(), inbuf.length()); + md5Final(); + digestHexStr = ""; + for (int i = 0; i < 16; i++) { + digestHexStr += byteHEX(digest[i]); + } + return digestHexStr; + + } + // 这是MD5这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数 + public MD5() { + md5Init(); + + return; + } + + + + /* md5Init是一个初始化函数,初始化核心变量,装入标准的幻数 */ + private void md5Init() { + count[0] = 0L; + count[1] = 0L; + ///* Load magic initialization constants. + + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; + + return; + } + /* F, G, H ,I 是4个基本的MD5函数,在原始的MD5的C实现中,由于它们是 + 简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们 +   实现成了private方法,名字保持了原来C中的。 */ + + private long F(long x, long y, long z) { + return (x & y) | ((~x) & z); + + } + private long G(long x, long y, long z) { + return (x & z) | (y & (~z)); + + } + private long H(long x, long y, long z) { + return x ^ y ^ z; + } + + private long I(long x, long y, long z) { + return y ^ (x | (~z)); + } + + /* + FF,GG,HH和II将调用F,G,H,I进行近一步变换 + FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + Rotation is separate from addition to prevent recomputation. + */ + + private long FF(long a, long b, long c, long d, long x, long s, + long ac) { + a += F (b, c, d) + x + ac; + a = ((int) a << s) | ((int) a >>> (32 - s)); + a += b; + return a; + } + + private long GG(long a, long b, long c, long d, long x, long s, + long ac) { + a += G (b, c, d) + x + ac; + a = ((int) a << s) | ((int) a >>> (32 - s)); + a += b; + return a; + } + private long HH(long a, long b, long c, long d, long x, long s, + long ac) { + a += H (b, c, d) + x + ac; + a = ((int) a << s) | ((int) a >>> (32 - s)); + a += b; + return a; + } + private long II(long a, long b, long c, long d, long x, long s, + long ac) { + a += I (b, c, d) + x + ac; + a = ((int) a << s) | ((int) a >>> (32 - s)); + a += b; + return a; + } + /* + md5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个 + 函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private的 + */ + private void md5Update(byte[] inbuf, int inputLen) { + + int i, index, partLen; + byte[] block = new byte[64]; + index = (int)(count[0] >>> 3) & 0x3F; + // /* Update number of bits */ + if ((count[0] += (inputLen << 3)) < (inputLen << 3)) + count[1]++; + count[1] += (inputLen >>> 29); + + partLen = 64 - index; + + // Transform as many times as possible. + if (inputLen >= partLen) { + md5Memcpy(buffer, inbuf, index, 0, partLen); + md5Transform(buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) { + + md5Memcpy(block, inbuf, 0, i, 64); + md5Transform (block); + } + index = 0; + + } else + + i = 0; + + ///* Buffer remaining input */ + md5Memcpy(buffer, inbuf, index, i, inputLen - i); + + } + + /* + md5Final整理和填写输出结果 + */ + private void md5Final () { + byte[] bits = new byte[8]; + int index, padLen; + + ///* Save number of bits */ + Encode (bits, count, 8); + + ///* Pad out to 56 mod 64. + index = (int)(count[0] >>> 3) & 0x3f; + padLen = (index < 56) ? (56 - index) : (120 - index); + md5Update (PADDING, padLen); + + ///* Append length (before padding) */ + md5Update(bits, 8); + + ///* Store state in digest */ + Encode (digest, state, 16); + + } + + /* md5Memcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的 +      字节拷贝到output的outpos位置开始 + */ + + private void md5Memcpy (byte[] output, byte[] input, + int outpos, int inpos, int len) + { + int i; + + for (i = 0; i < len; i++) + output[outpos + i] = input[inpos + i]; + } + + /* + md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节 + */ + private void md5Transform (byte block[]) { + long a = state[0], b = state[1], c = state[2], d = state[3]; + long[] x = new long[16]; + + Decode (x, block, 64); + + /* Round 1 */ + a = FF (a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */ + d = FF (d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */ + c = FF (c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */ + b = FF (b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */ + a = FF (a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */ + d = FF (d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */ + c = FF (c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */ + b = FF (b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */ + a = FF (a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */ + d = FF (d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */ + c = FF (c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */ + b = FF (b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */ + a = FF (a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */ + d = FF (d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */ + c = FF (c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */ + b = FF (b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */ + + /* Round 2 */ + a = GG (a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */ + d = GG (d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */ + c = GG (c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */ + b = GG (b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */ + a = GG (a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */ + d = GG (d, a, b, c, x[10], S22, 0x2441453L); /* 22 */ + c = GG (c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */ + b = GG (b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */ + a = GG (a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */ + d = GG (d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */ + c = GG (c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */ + b = GG (b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */ + a = GG (a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */ + d = GG (d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */ + c = GG (c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */ + b = GG (b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */ + + /* Round 3 */ + a = HH (a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */ + d = HH (d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */ + c = HH (c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */ + b = HH (b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */ + a = HH (a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */ + d = HH (d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */ + c = HH (c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */ + b = HH (b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */ + a = HH (a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */ + d = HH (d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */ + c = HH (c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */ + b = HH (b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */ + a = HH (a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */ + d = HH (d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */ + c = HH (c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */ + b = HH (b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */ + + /* Round 4 */ + a = II (a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */ + d = II (d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */ + c = II (c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */ + b = II (b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */ + a = II (a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */ + d = II (d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */ + c = II (c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */ + b = II (b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */ + a = II (a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */ + d = II (d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */ + c = II (c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */ + b = II (b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */ + a = II (a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */ + d = II (d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */ + c = II (c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */ + b = II (b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + } + + /*Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的, + 只拆低32bit,以适应原始C实现的用途 + */ + private void Encode (byte[] output, long[] input, int len) { + int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (byte)(input[i] & 0xffL); + output[j + 1] = (byte)((input[i] >>> 8) & 0xffL); + output[j + 2] = (byte)((input[i] >>> 16) & 0xffL); + output[j + 3] = (byte)((input[i] >>> 24) & 0xffL); + } + } + + /*Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的, + 只合成低32bit,高32bit清零,以适应原始C实现的用途 + */ + private void Decode (long[] output, byte[] input, int len) { + int i, j; + + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = b2iu(input[j]) | + (b2iu(input[j + 1]) << 8) | + (b2iu(input[j + 2]) << 16) | + (b2iu(input[j + 3]) << 24); + + return; + } + + /* + b2iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算 + */ + public static long b2iu(byte b) { + return b < 0 ? b & 0x7F + 128 : b; + } + + /*byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示, +  因为java中的byte的toString无法实现这一点,我们又没有C语言中的 + sprintf(outbuf,"%02X",ib) + */ + public static String byteHEX(byte ib) { + char[] Digit = { '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F' }; + char [] ob = new char[2]; + ob[0] = Digit[(ib >>> 4) & 0X0F]; + ob[1] = Digit[ib & 0X0F]; + String s = new String(ob); + return s; + } + +} + diff --git a/src/farm-core/src/main/java/com/farm/core/auth/util/Urls.java b/src/farm-core/src/main/java/com/farm/core/auth/util/Urls.java new file mode 100644 index 0000000..a5eab38 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/auth/util/Urls.java @@ -0,0 +1,192 @@ +package com.farm.core.auth.util; // 定义包名,表示该类位于 com.farm.core.auth.util 包中 + +import java.util.Map; // 导入 Map 接口 +import java.util.Map.Entry; // 导入 Map.Entry 接口,用于遍历 Map 中的键值对 +import java.util.Set; // 导入 Set 接口 + +import javax.servlet.http.HttpServletRequest; // 导入 HttpServletRequest 接口,用于处理 HTTP 请求 + +/** + * 权限验证帮助类 + * + * @author WangDong + * @date Mar 14, 2010 + * + */ +public class Urls { + + /** + * 验证权限是否符合系统验证 + * + * @param actionMap 全部监控权限 + * @param useraction 用户拥有权限 + * @param url 当前URL + * @return 是否符合验证 + */ + @SuppressWarnings("unused") // 抑制未使用变量的警告 + private boolean checkpopedom(Map actionMap, Map> useraction, + String url) { + // 查看是否是受控权限 + if (actionMap == null) { + return false; // 如果全部监控权限为空,则返回false + } + if (actionMap.get(url) != null) { + // 是受检权限,看用户是否拥有该权限 + if (useraction == null) { + return false; // 如果用户拥有权限为空,则返回false + } + if (useraction.get(url) != null) { + return true; // 如果用户拥有该URL的权限,则返回true + } else { + return false; // 如果用户没有该URL的权限,则返回false + } + } else { + // 不是受检权限 + return true; // 如果当前URL不在监控权限中,则默认有权限,返回true + } + } + + // struts2的请求处理方法 + + /** + * 将url解析为系统可识别的url transact Url to Url(Admin/Xxxx.do) + * + * @param requestUrl 原始url + * @param basePath 应用基础路径 + * @return 解析后的url,如果返回null则表示url错误 + */ + public static String formatUrl(String requestUrl, String basePath) { + // 去掉basepath + requestUrl = requestUrl.replace(basePath, ""); + // 截去url参数 + int num = requestUrl.indexOf("?"); + if (num > 0) { + requestUrl = requestUrl.substring(0, num); + } + // 截去url前缀 + // int num2 = requestUrl.replace("\\", "/").lastIndexOf("/"); + // requestUrl = requestUrl.substring(num2); + return requestUrl; // 返回处理后的URL + } + + /** + * 判断是否是actionURL + * + * @param _Url URL字符串 + * @param _postfix 后缀 + * @return 是否是actionURL + */ + public static boolean isActionByUrl(String _Url, String _postfix) { + if (_Url.indexOf(".") < 0) { + return false; // 如果URL中没有点,则不是actionURL + } + _Url = _Url.trim(); + String postfix = _Url.substring(_Url.lastIndexOf(".") + 1); + if (postfix.toUpperCase().equals(_postfix.toUpperCase())) { + return true; // 如果后缀匹配,则是actionURL + } + return false; // 否则不是actionURL + } + + /** + * 获得URLIndex,将格式化后的URL转换为URLIndex形式 + * + * @param formatUrl 格式化后的URL + * @return URLIndex + */ + public static String getActionKey(String formatUrl) { + String name = formatUrl.substring(0, formatUrl.lastIndexOf(".")); + // if (name.lastIndexOf("/") >= 0) { + // name = name.substring(name.lastIndexOf("/") + 1); + // } + // if (name.lastIndexOf("\\") >= 0) { + // name = name.substring(name.lastIndexOf("\\") + 1); + // } + return name; // 返回URLIndex + } + + /** + * 获得URL的子键,即URL中的最后一部分 + * + * @param actionkey URLIndex + * @return URL的子键 + */ + public static String getActionSubKey(String actionkey) { + // 将actionkey中的反斜杠替换为正斜杠,以统一路径分隔符 + int num2 = actionkey.replace("\\", "/").lastIndexOf("/"); + // 如果找到了正斜杠,说明存在路径 + if (num2 >= 0) { + // 截取最后一个正斜杠之后的部分,即URL的子键 + actionkey = actionkey.substring(num2); + } + // 返回处理后的URL子键,如果未找到正斜杠,则返回原actionkey + return actionkey; + } + + + /** + * 获得当前连接的IP地址 + * + * @param request 请求对象 + * @return IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + // 尝试从HTTP头部x-forwarded-for获取IP地址,这个头部通常由代理服务器设置 + String ip = request.getHeader("x-forwarded-for"); + // 如果IP地址为空、长度为0或者为"unknown",则尝试从Proxy-Client-IP头部获取IP地址 + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + // 如果IP地址仍然为空、长度为0或者为"unknown",则尝试从WL-Proxy-Client-IP头部获取IP地址 + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + // 如果IP地址仍然为空、长度为0或者为"unknown",则从远程地址(即直接连接到服务器的客户端IP)获取IP地址 + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + // 返回获取到的IP地址 + return ip; + } + + + /** + * 获得所有request的参数并拼接成GET参数字符串 + * + * @param request 请求对象 + * @return GET参数字符串 + */ + public static String getUrlParameters(HttpServletRequest request) { + // 抑制unchecked警告,因为getParameterMap()返回的是Map,而Entry是unchecked类型 + @SuppressWarnings("unchecked") + Set> entrySet = request.getParameterMap().entrySet(); + // 创建StringBuffer用于拼接URL参数 + StringBuffer urlp = new StringBuffer(); + // 遍历所有请求参数的键值对 + for (Entry node : entrySet) { + // 检查参数值是否存在且至少有一个元素 + if (node.getValue() != null && node.getValue().length > 0) { + // 如果已经拼接了参数,则在添加新参数前添加'&'分隔符 + if (urlp.length() > 0) { + urlp.append("&"); + } + // 拼接参数名和第一个参数值,格式为"key=value" + urlp.append(node.getKey() + "=" + node.getValue()[0]); + } + } + // 返回拼接后的GET参数字符串 + return urlp.toString(); + } + + + /** + * 验证用户是否拥有权限 + * + * @param URL_index actionIndex,URl关键字不包括后缀和前缀 + * @param userUrl 用户权限集合《URL_index,URL_Id》 + * @return 是否有权限 + */ + public boolean isHavePop(String URL_index, Map userUrl) { + return false; // 当前方法未实现,直接返回false + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/config/AppConfig.java b/src/farm-core/src/main/java/com/farm/core/config/AppConfig.java new file mode 100644 index 0000000..3be02c2 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/config/AppConfig.java @@ -0,0 +1,48 @@ +package com.farm.core.config; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.apache.log4j.Logger; + +/** + * 应用参数工具类,获得config中定义的参数 + * + * @author wangdong + * + */ +public class AppConfig { + private static final String BUNDLE_NAME = "config"; //$NON-NLS-1$ + private static final Logger log = Logger.getLogger(AppConfig.class); + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + private AppConfig() { + // 私有构造函数,防止外部创建AppConfig实例 + } + + /** + * 从properties文件中获得配置值 + * + * @param key 配置文件的key + * @return 配置值 + */ + public static String getString(String key) { + // 如果key是"PRO",则直接返回"PRO"(可能是特殊处理或默认值) + if (key.equals("PRO")) { + return "PRO"; + } + try { + // 从资源束中获取key对应的字符串值 + String messager = RESOURCE_BUNDLE.getString(key); + return messager; + } catch (MissingResourceException e) { + // 如果在资源束中找不到key,构建错误消息 + String messager = "不能在配置文件" + BUNDLE_NAME + "中发现参数:" + '!' + key + '!'; + // 记录错误日志 + log.error(messager); + // 抛出运行时异常,通知调用者配置值未找到 + throw new RuntimeException(messager); + } + } +// AppConfig类结束 + diff --git a/src/farm-core/src/main/java/com/farm/core/config/PropertiesUtils.java b/src/farm-core/src/main/java/com/farm/core/config/PropertiesUtils.java new file mode 100644 index 0000000..84b69d0 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/config/PropertiesUtils.java @@ -0,0 +1,116 @@ +package com.farm.core.config; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Properties; + +import org.apache.log4j.Logger; + + +public class PropertiesUtils { + private String PROPERTY_FILE; // 属性文件路径 + private static final Logger log = Logger.getLogger(PropertiesUtils.class); // 日志记录器 + + /** + * 构造函数,用于初始化PropertiesUtils实例并设置属性文件路径。 + * @param fileName 属性文件名,例如jdbc.properties + */ + public PropertiesUtils(String fileName) { + // 获取类路径下的资源路径,并拼接文件名以设置完整的属性文件路径 + PROPERTY_FILE = PropertiesUtils.class.getResource("/").getPath() + .toString() + + fileName; + } + // 类的其他部分... +} + + + /** + * 根据Key 读取Value + */ + public String getData(String key) { + // 创建Properties对象,用于加载和读取属性文件中的键值对 + Properties props = new Properties(); + try { + // 创建InputStream对象,用于读取属性文件 + // 使用BufferedInputStream包装FileInputStream以提供缓冲功能,提高读取效率 + InputStream in = new BufferedInputStream(new FileInputStream( + PROPERTY_FILE)); + // 加载属性文件中的键值对到Properties对象中 + props.load(in); + // 关闭输入流 + in.close(); + // 根据键获取对应的值 + String value = props.getProperty(key); + // 返回获取到的值 + return value; + } catch (Exception e) { + // 如果在读取过程中发生异常,记录错误日志 + log.error(e.getMessage()); + // 返回null,表示没有获取到对应的值 + return null; + } + } + + +/** + * 修改或添加键值对 如果key存在,修改 反之,添加。 + */ +public void setData(String key, String value) { + // 创建Properties对象,用于存储和修改属性键值对 + Properties prop = new Properties(); + // 定义OutputStream变量,用于写入属性文件 + OutputStream fos = null; + // 定义InputStream变量,用于读取属性文件 + InputStream fis = null; + try { + // 创建File对象,指向属性文件 + File file = new File(PROPERTY_FILE); + // 如果属性文件不存在,则创建一个新的文件 + if (!file.exists()) + file.createNewFile(); + // 初始化FileInputStream,用于读取属性文件 + fis = new FileInputStream(file); + // 加载属性文件中的键值对到Properties对象中 + prop.load(fis); + } catch (IOException e) { + // 如果读取属性文件时发生IOException,打印错误信息 + System.err.println("Visit " + PROPERTY_FILE + " for updating " + + value + " value error"); + } finally { + try { + // 关闭FileInputStream,释放资源 + fis.close();// 一定要在修改值之前关闭fis + } catch (IOException e) { + // 关闭FileInputStream时可能发生的IOException,此处忽略 + } + } + try { + // 初始化FileOutputStream,用于写入修改后的属性文件 + fos = new FileOutputStream(PROPERTY_FILE); + // 设置Properties对象的键值对 + prop.setProperty(key, value); + // 将修改后的键值对存储到属性文件中,并添加注释 + prop.store(fos, "Update '" + key + "' value"); + // 重复存储操作,可能是为了测试或记录额外信息,但通常不需要 + prop.store(fos, "just for test"); + } catch (IOException e) { + // 如果写入属性文件时发生IOException,打印错误信息 + System.err.println("Visit " + PROPERTY_FILE + " for updating " + + value + " value error"); + } finally { + try { + // 关闭FileOutputStream,释放资源 + fos.close(); + } catch (IOException e) { + // 关闭FileOutputStream时可能发生的IOException,此处忽略 + } + } +} +// 类结束 + diff --git a/src/farm-core/src/main/java/com/farm/core/config/ReadKey.java b/src/farm-core/src/main/java/com/farm/core/config/ReadKey.java new file mode 100644 index 0000000..859c17b --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/config/ReadKey.java @@ -0,0 +1,60 @@ +package com.farm.core.config; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; + +import com.farm.core.Context; +import com.farm.core.auth.util.KeyUtil; + +/** + * 读取licence + * + * @author macplus + * + */ +public class ReadKey { + private static boolean isOk = false; // 静态标志变量,用于指示是否已成功读取licence文件 + + public static void read(String path) { + try { + // 检查是否已经读取过licence文件,如果没有,则进行读取操作 + if (isOk == false) { + // 读取licence文件内容,并设置到Context的FK字段 + Context.FK = readTxtFile(path + File.separator + "licence"); + // 比较licence文件内容与通过KeyUtil获取的Fkey是否相等,结果设置到Context的FLAG字段 + Context.FLAG = KeyUtil.getFkey(KeyUtil.getMKey()).equals(Context.FK); + // 设置isOk为true,表示已成功读取licence文件 + isOk = true; + } + } catch (Exception e) { + // 如果在读取过程中发生异常,将Context的FK字段设置为"NONE1" + Context.FK = "NONE1"; + } + } + + public static String readTxtFile(String filePath) { + try { + // 创建File对象,指向指定的文件路径 + File file = new File(filePath); + // 检查文件是否存在且是一个文件 + if (file.isFile() && file.exists()) { + // 创建InputStreamReader对象,指定文件输入流和编码格式为utf-8 + InputStreamReader read = new InputStreamReader(new FileInputStream(file), "utf-8"); + // 创建BufferedReader对象,用于读取文件内容 + BufferedReader bufferedReader = new BufferedReader(read); + String lineTxt = null; + // 读取文件的第一行内容 + while ((lineTxt = bufferedReader.readLine()) != null) { + return lineTxt; // 返回读取到的第一行内容 + } + read.close(); // 关闭读取流 + } + } catch (Exception e) { + // 异常处理,此处为空,实际应用中应添加适当的异常处理逻辑 + } + return "none"; // 如果文件不存在或读取过程中发生异常,返回"none" + } +} + diff --git a/src/farm-core/src/main/java/com/farm/core/page/OperateType.java b/src/farm-core/src/main/java/com/farm/core/page/OperateType.java new file mode 100644 index 0000000..2093f6e --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/page/OperateType.java @@ -0,0 +1,49 @@ +package com.farm.core.page; + +/** + * 页面类型 + * + * @author wangdong + * + */ +public enum OperateType { + /** + * 展示 + */ + SHOW(0), /** + * 新增 + */ + ADD(1), /** + * 修改 + */ + UPDATE(2), + /** + * 删除 + */ + DEL(4), + /** + * 其他 + */ + OTHER(3); + public int value; + + private OperateType(int var) { + value = var; + } + + /**根据数值获得页面类型枚举对象 + * @param type + * @return + */ + public static OperateType getEnum(int type) { + // 方法开始,定义一个静态方法getEnum,它接受一个整型参数type + if (type == 0) + return OperateType.SHOW; // 检查type是否为0,如果是,则返回OperateType.SHOW,表示显示操作 + if (type == 1) + return OperateType.ADD; // 检查type是否为1,如果是,则返回OperateType.ADD,表示添加操作 + if (type == 2) + return OperateType.UPDATE; // 检查type是否为2,如果是,则返回OperateType.UPDATE,表示更新操作 + return null; // 如果type不是0、1或2,表示传入的type不匹配任何预定义的操作类型,返回null + } // 方法结束,返回一个OperateType枚举类型或者null + +} diff --git a/src/farm-core/src/main/java/com/farm/core/page/RequestMode.java b/src/farm-core/src/main/java/com/farm/core/page/RequestMode.java new file mode 100644 index 0000000..6e33111 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/page/RequestMode.java @@ -0,0 +1,198 @@ +package com.farm.core.page; // 定义包名,表示该类属于com.farm.core.page包 + +import java.util.HashMap; // 导入HashMap类 +import java.util.Map; // 导入Map接口 + +import javax.servlet.http.HttpSession; // 导入HttpSession接口 + +import org.apache.log4j.Logger; // 导入Logger类 + +import com.farm.core.auth.domain.LoginUser; // 导入LoginUser类 + +/** + * 封装一次页面请求的状态 + * + * @author wangdong + * + */ +public class RequestMode implements java.io.Serializable { // 定义RequestMode类,实现Serializable接口 + /** + * + */ + private static final long serialVersionUID = 1L; // 定义序列化版本UID + static final Logger log = Logger.getLogger(RequestMode.class); // 获取Logger实例 + private Map data; // 定义数据存储Map + /** + * 页面类型 + */ + private int operateType; // 定义操作类型变量 + /** + * 消息 + */ + private String message = ""; // 定义消息字符串,默认为空 + /** + * 记录集id集合 + */ + private String ids; // 定义记录集ID集合字符串 + /** + * 当前实体id + */ + private String currentKeyid; // 定义当前实体ID字符串 + + // ------------------------------------------------------------------------------ + + /** + * 当前主键 + * + * @return + */ + public String getCurrentKeyid() { // 获取当前主键的方法 + return currentKeyid; // 返回当前主键 + } + + /** + * 设置参数 + * + * @return + */ + public void putParameters(String key, String val) { // 设置参数的方法 + if (this.data == null) { // 如果data为null + this.data = new HashMap(); // 初始化data + } + this.data.put(key, val); // 向data中添加键值对 + } + + /** + * 获得参数 + * + * @param key + * @return + */ + public String getParameters(String key) { // 获取参数的方法 + return this.data.get(key); // 返回指定键的值 + } + + /** + * 获得当前业务id + * + * @param currentKeyid + */ + public void setCurrentKeyid(String currentKeyid) { // 设置当前业务ID的方法 + this.currentKeyid = currentKeyid; // 设置当前业务ID + } + + public RequestMode() { // 默认构造函数 + } + + public RequestMode(OperateType operate) { // 带操作类型的构造函数 + operateType = operate.value; // 设置操作类型 + } + + public RequestMode(OperateType operate, String message) { // 带操作类型和消息的构造函数 + operateType = operate.value; // 设置操作类型 + this.message = message; // 设置消息 + } + + /** + * 设置一个PageSet 而且PageSet可以为空 + * + * @param pageSet 页面状态对象 + * @param pageType 页面类型 + * @param commitType 提交状态 + * @param e 异常 + * @return pageSet 页面状态对象 + */ + public static RequestMode initPageSet(RequestMode pageSet, + OperateType operateType, Exception e) { // 初始化页面状态的方法 + if (pageSet == null) { // 如果页面状态对象为null + pageSet = new RequestMode(OperateType.OTHER); // 创建一个新的页面状态对象 + } + if (e != null) { // 如果异常不为null + pageSet.setMessage(e.getMessage()); // 设置消息为异常信息 + log.error(pageSet.getMessage()); // 记录错误日志 + } + if (operateType != null) { // 如果操作类型不为null + pageSet.setOperateType(operateType.value); // 设置操作类型 + } + return pageSet; // 返回页面状态对象 + } + + /** + * 设置状态 + * + * @param pageType 页面类型对象 + * @param commitType 提交状态对象 + */ + public void SetVar(OperateType operateType) { // 设置状态的方法 + if (operateType != null) // 如果操作类型不为null + this.operateType = operateType.value; // 设置操作类型 + } + + /** + * 设置状态 + * + * @param pageType 页面类型对象 + * @param commitType 提交状态对象 + * @param message 消息内容 + */ + public void SetVar(OperateType operateType, + String message) { // 设置状态和消息的方法 + if (operateType != null) // 如果操作类型不为null + this.operateType = operateType.value; // 设置操作类型 + if (message != null) // 如果消息不为null + this.message = message; // 设置消息 + } + + /** + * 获得消息 + * + * @return + */ + public String getMessage() { // 获取消息的方法 + return message; // 返回消息 + } + + /** + * 设置消息内容 + * + * @param message + */ + public void setMessage(String message) { // 设置消息内容的方法 + this.message = message; // 设置消息 + } + + public int getOperateType() { // 获取操作类型的方法 + return operateType; // 返回操作类型 + } + + public void setOperateType(int operateType) { // 设置操作类型的方法 + this.operateType = operateType; // 设置操作类型 + } + + /** + * 获得id集合 + * + * @return + */ + public String getIds() { // 获取ID集合的方法 + return ids; // 返回ID集合 + } + + /** + * 设置id集合 + * + * @param ids + */ + public void setIds(String ids) { // 设置ID集合的方法 + this.ids = ids; // 设置ID集合 + } + + public Map getData() { // 获取数据的方法 + return data; // 返回数据 + } + + public void setData(Map data) { // 设置数据的方法 + this.data = data; // 设置数据 + } + +} diff --git a/src/farm-core/src/main/java/com/farm/core/page/StateType.java b/src/farm-core/src/main/java/com/farm/core/page/StateType.java new file mode 100644 index 0000000..97d0002 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/page/StateType.java @@ -0,0 +1,22 @@ +package com.farm.core.page; + +/** + * 提交状态,用来标志操作是否成功,多用于页面对后台操作的判断 + * + * @author wangdong + * + */ +public enum StateType { + /** + * 成功 + */ + SUCCESS(0), /** + * 失败 + */ + ERROR(1); + public int value; + + private StateType(int var) { + value = var; + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/page/ViewMode.java b/src/farm-core/src/main/java/com/farm/core/page/ViewMode.java new file mode 100644 index 0000000..5907f0c --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/page/ViewMode.java @@ -0,0 +1,74 @@ +package com.farm.core.page; // 定义包名,表示该类属于com.farm.core.page包 + +import java.util.HashMap; // 导入HashMap类 +import java.util.List; // 导入List接口 +import java.util.Map; // 导入Map接口 + +import org.apache.log4j.Logger; // 导入Logger类 +import org.springframework.web.servlet.ModelAndView; // 导入ModelAndView类 + +/** + * ajax请求时的json模型 + * + * @author wangdong + * + */ +public class ViewMode { + private final static Logger log = Logger.getLogger(ViewMode.class); // 获取Logger实例 + private Map attrs = new HashMap(); // 存储属性键值对的Map + + // 获取ViewMode的实例,并初始化状态和操作类型 + public static ViewMode getInstance() { + ViewMode obj = new ViewMode(); + obj.attrs.put("STATE", StateType.SUCCESS.value); // 设置默认状态为成功 + obj.attrs.put("OPERATE", OperateType.OTHER.value); // 设置默认操作类型为其他 + return obj; + } + + /** + * 装入json返回值 + * + * @param key 键 + * @param value 值 + * @return 当前ViewMode实例 + */ + public ViewMode putAttr(String key, String value) { + attrs.put(key, value); // 添加字符串类型的键值对 + return this; + } + + // 重载putAttr方法,支持Object类型的值 + public ViewMode putAttr(String key, Object value) { + attrs.put(key, value); // 添加Object类型的键值对 + return this; + } + + // 添加多个键值对到attrs中 + public ViewMode putAttrs(Map map) { + attrs.putAll(map); // 合并Map到attrs中 + return this; + } + + /** + * 装入错误 + * + * @param message 错误消息 + * @return 当前ViewMode实例 + */ + public ViewMode setError(String message) { + attrs.put("MESSAGE", message); // 设置错误消息 + attrs.put("STATE", StateType.ERROR.value); // 设置状态为错误 + log.error(message); // 记录错误日志 + return this; + } + + // 设置操作类型 + public ViewMode setOperate(OperateType type) { + attrs.put("OPERATE", type.value); // 设置操作类型 + return this; + } + +/** + * 返回map格式json + * + * @return at \ No newline at end of file diff --git a/src/farm-core/src/main/java/com/farm/core/para/impl/ParaTestImpl.java b/src/farm-core/src/main/java/com/farm/core/para/impl/ParaTestImpl.java new file mode 100644 index 0000000..69fa363 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/para/impl/ParaTestImpl.java @@ -0,0 +1,46 @@ +package com.farm.core.para.impl; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.farm.core.ParameterService; + +public class ParaTestImpl implements ParameterService { + + @Override + public Map getDictionary(String key) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List> getDictionaryList(String index) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getParameter(String key) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getParameter(String key, String userId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getParameterInt(String key) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public boolean getParameterBoolean(String key) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/CoreHandle.java b/src/farm-core/src/main/java/com/farm/core/sql/query/CoreHandle.java new file mode 100644 index 0000000..0e88483 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/CoreHandle.java @@ -0,0 +1,22 @@ +package com.farm.core.sql.query; + +import com.farm.core.Context; +import com.farm.core.auth.util.KeyUtil; + +public class CoreHandle { + // 定义核心处理类 + + /** + * 运行LCE逻辑。 + * 此方法用于执行某些核心的LCE(可能是某种逻辑、计算或初始化)操作。 + * 它首先从KeyUtil工具类获取主键(MKey),然后将其设置到Context的MK属性中。 + * 目前,无论操作结果如何,该方法总是返回true。 + * + * @return 总是返回true,表示操作成功。 + */ + public static boolean runLce() { + Context.MK = KeyUtil.getMKey(); // 获取并设置主键 + return true; // 返回操作成功标志 + } +} + diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/DBRule.java b/src/farm-core/src/main/java/com/farm/core/sql/query/DBRule.java new file mode 100644 index 0000000..7bd6e8d --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/DBRule.java @@ -0,0 +1,228 @@ +package com.farm.core.sql.query; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 查询条件的封装类,配合DataQuery使用 + * + * @author 王东 + * @date 2012-12-30 + */ +public class DBRule { + private String key;// where key + private Object value;// where value + private String comparaSign;// like,}��% = > < >= <= + private List rules = new ArrayList(); + + /** + * 将一个条件对象添加到条件序列中 + * + * @param ruleList + * @param key + * @param value + * @param comString + * @return + */ + public static List addRule(List ruleList, String key, + String value, String comString) { + DBRule cRule = new DBRule(key, value, comString); + ruleList.add(cRule); + return ruleList; + } + + /** + * 将一个条件对象添加到条件序列中 + * + * @param key + * @param value + * @param comString + * @return + */ + public DBRule addRule(String key, String value, String comString) { + DBRule cRule = new DBRule(key, value, comString); + rules.add(cRule); + return this; + } + + /** + * 获得条件序列 + * + * @return + */ + public List getDBRules() { + return rules; + } + + /** + * 将条件序列转义为条件字符串 + * + * @param ruleList + * 条件序列 + * @return + */ + public static String makeWhereStr(List ruleList) { + StringBuffer str = new StringBuffer(); + for (DBRule node : ruleList) { + str.append(node.getThisLimit()); + } + return str.toString(); + } + + /** + * 构造一个查询条件 + * + * @param key + * 字段名 + * @param value + * 字段值 + * @param comString + * 匹配类型 like(-like坐标自由匹配) IS NOT = > < >= <= + */ + public DBRule(String key, Object value, String comString) { + // 对键进行SQL注入防护 + DataQuerys.wipeVirus(key); + // 对值进行SQL注入防护,先将Object类型的值转换为字符串 + DataQuerys.wipeVirus(value.toString()); + // 对比较符进行SQL注入防护 + DataQuerys.wipeVirus(comString); + + // 去除键的首尾空格并转换为大写 + this.key = key.trim().toUpperCase(); + // 设置规则值 + this.value = value; + // 去除比较符的首尾空格并转换为大写 + this.comparaSign = comString.trim().toUpperCase(); + + // 将当前DBRule对象添加到规则列表中 + this.rules.add(this); + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value.toString(); + } + + public void setValue(String value) { + this.value = value; + } + + public String getComparaSign() { + return comparaSign; + } + + public void setComparaSign(String comparaSign) { + this.comparaSign = comparaSign; + } + + public String getThisLimit() { + // 初始化StringBuffer用于构建限制条件 + StringBuffer where_ = new StringBuffer(); + // 将比较符转换为大写 + comparaSign = comparaSign.toUpperCase(); + // 检查键、值和比较符是否非空 + if (key != null && value != null && comparaSign != null) { + // 添加AND关键字和键 + where_.append(" AND "); + where_.append(key); + // 根据比较符是否包含"LIKE"来决定添加LIKE还是其他比较符 + if (comparaSign.indexOf("LIKE") >= 0) { + where_.append(" "); + where_.append("LIKE"); + } else { + where_.append(" "); + where_.append(comparaSign); + } + // 添加处理后的值 + where_.append(expendVal()); + where_.append(" "); + } + // 返回构建好的限制条件字符串 + return where_.toString(); + } + + private String expendVal() { + // 创建一个新的StringBuffer对象用于构建扩展后的值字符串 + StringBuffer valStr = new StringBuffer(); + + // 检查比较符是否为"LIKE",如果是,则进行模糊匹配处理 + if (comparaSign.equals("LIKE")) { + // 为LIKE查询添加前百分号和单引号 + valStr.append(" '%"); + // 添加值本身 + valStr.append(value.toString()); + // 为LIKE查询添加后百分号和单引号 + valStr.append("%'"); + } else if (comparaSign.equals("-LIKE")) { + // 为-LIKE查询添加前百分号和单引号(不添加后百分号) + valStr.append(" '%"); + // 添加值本身 + valStr.append(value.toString()); + // 为-LIKE查询添加单引号 + valStr.append("'"); + } else if (comparaSign.equals("LIKE-")) { + // 为LIKE-查询添加单引号和后百分号(不添加前百分号) + valStr.append(" '"); + // 添加值本身 + valStr.append(value.toString()); + // 为LIKE-查询添加后百分号和单引号 + valStr.append("%'"); + } else if (comparaSign.equals("IS NOT")) { + // 为IS NOT查询添加空格 + valStr.append(" "); + // 添加值本身 + valStr.append(value.toString()); + // 为IS NOT查询添加空格 + valStr.append(" "); + } else if (comparaSign.equals("IS")) { + // 为IS查询添加空格 + valStr.append(" "); + // 添加值本身 + valStr.append(value.toString()); + // 为IS查询添加空格 + valStr.append(" "); + } else if (comparaSign.equals("IN")) { + // 为IN查询添加左括号 + valStr.append("("); + // 添加值本身,通常是一个逗号分隔的列表 + valStr.append(value.toString()); + // 为IN查询添加右括号 + valStr.append(")"); + } else { + // 对于其他类型的比较符,根据值的类型进行处理 + if (value instanceof String) { + // 如果值是字符串,添加单引号以区分SQL关键字 + valStr.append(" '"); + // 添加值本身 + valStr.append(value.toString()); + // 添加单引号 + valStr.append("'"); + } else if (value instanceof BigDecimal) { + // 如果值是BigDecimal,直接添加值(数字不需要单引号) + valStr.append(" "); + // 添加值本身 + valStr.append(value.toString()); + // 不需要额外的符号 + valStr.append(""); + } else { + // 对于其他类型的值,直接添加值 + valStr.append(" "); + // 添加值本身 + valStr.append(value.toString()); + // 不需要额外的符号 + valStr.append(""); + } + } + + // 将构建好的StringBuffer对象转换为字符串并返回 + return valStr.toString(); + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/DBRuleList.java b/src/farm-core/src/main/java/com/farm/core/sql/query/DBRuleList.java new file mode 100644 index 0000000..8772780 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/DBRuleList.java @@ -0,0 +1,40 @@ +package com.farm.core.sql.query; + +import java.util.ArrayList; +import java.util.List; + +/** + * 查询条件的封装类 + * + * @author 王东 + * @date 2015-01-28 + */ +public class DBRuleList { + // 使用@SuppressWarnings注解来抑制未使用变量的警告 + @SuppressWarnings("unused") + // 定义一个序列化版本ID,用于对象的序列化和反序列化 + private static final long serialVersionUID = 1L; + // 初始化一个列表来存储DBRule对象 + private List list = new ArrayList(); + + // 默认构造函数,用于创建DBRuleList实例 + public DBRuleList() { + } + + // 获取DBRuleList的实例,返回一个新的DBRuleList对象 + public static DBRuleList getInstance() { + return new DBRuleList(); + } + + // 向列表中添加一个DBRule对象,并返回当前DBRuleList实例以支持链式调用 + public DBRuleList add(DBRule rule) { + list.add(rule); + return this; + } + + // 将内部的DBRule列表转换为List并返回,以便外部使用 + public List toList() { + return list; + } +} + diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/DBSort.java b/src/farm-core/src/main/java/com/farm/core/sql/query/DBSort.java new file mode 100644 index 0000000..1a72a2d --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/DBSort.java @@ -0,0 +1,106 @@ +package com.farm.core.sql.query; + +/** + * 排序方式的封装类,配合DataQuery使用 + * + * @author 王东 + * @date 2012-12-30 + */ +public class DBSort { + private String sortTitleText; // 排序字段,用于存储数据库中需要排序的列的名称 + private String sortTypeText; // 排序类型,用于存储排序的方式,可以是"ASC"(升序)或"DESC"(降序) + private String isValidate; // 验证标志,用于指示是否对排序字段和排序类型进行数据验证 + + @SuppressWarnings("unused") + private DBSort() { + // 私有构造函数,防止外部直接创建DBSort实例,可能用于内部逻辑或继承时使用 + } + + /** + * 构造一个排序方式 + * + * @param title 排序字段,必须是非空的字符串,表示数据库中要排序的列名 + * @param type 排序类型,必须是非空的字符串,且为"ASC"或"DESC",表示升序或降序 + */ + public DBSort(String title, String type) { + DataQuerys.wipeVirus(type); // 对排序类型进行防SQL注入处理 + DataQuerys.wipeVirus(title); // 对排序字段进行防SQL注入处理 + sortTitleText = title; // 设置排序字段 + sortTypeText = type; // 设置排序类型 + } + + /** + * 构造一个排序方式,并指定是否进行数据验证 + * + * @param title 排序字段,必须是非空的字符串,表示数据库中要排序的列名 + * @param type 排序类型,必须是非空的字符串,且为"ASC"或"DESC",表示升序或降序 + * @param isValidate 验证标志,布尔值,表示是否对传入的参数进行数据验证 + */ + public DBSort(String title, String type, boolean isValidate) { + if (isValidate) { + DataQuerys.wipeVirus(type); // 如果需要进行验证,对排序类型进行防SQL注入处理 + DataQuerys.wipeVirus(title); // 如果需要进行验证,对排序字段进行防SQL注入处理 + } + sortTitleText = title; // 设置排序字段 + sortTypeText = type; // 设置排序类型 + } + + /** + * 设置排序字段 + * + * @param sortTitleText 排序字段,必须是非空的字符串,表示数据库中要排序的列名 + */ + public void setSortTitleText(String sortTitleText) { + this.sortTitleText = sortTitleText; // 更新排序字段 + } + + /** + * 获取排序字段,确保返回的排序字段不包含下划线,因为数据库中的字段不能带下划线 + * + * @return 排序字段,如果为空或为"NULL"(不区分大小写),则返回null,否则返回替换下划线为点后的字符串 + */ + public String getSortTitleText() { + if (sortTitleText == null + || sortTitleText.trim().toUpperCase().equals("NULL")) { + return null; // 如果排序字段为空或为"NULL",则返回null + } + return sortTitleText.replace("_", "."); // 替换排序字段中的下划线为点 + } + + /** + * 获取排序类型 + * + * @return 排序类型,字符串,表示升序或降序 + */ + public String getSortTypeText() { + return sortTypeText; // 返回排序类型 + } + + /** + * 设置排序类型 + * + * @param sortTypeText 排序类型,必须是非空的字符串,且为"ASC"或"DESC",表示升序或降序 + */ + public void setSortTypeText(String sortTypeText) { + this.sortTypeText = sortTypeText; // 更新排序类型 + } + + /** + * 获取验证标志 + * + * @return 验证标志,字符串,表示是否进行了数据验证 + */ + public String getIsValidate() { + return isValidate; // 返回验证标志 + } + + /** + * 设置验证标志 + * + * @param isValidate 验证标志,字符串,用于指示是否进行了数据验证 + */ + public void setIsValidate(String isValidate) { + this.isValidate = isValidate; // 更新验证标志 + } +} + diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/DataQuery.java b/src/farm-core/src/main/java/com/farm/core/sql/query/DataQuery.java new file mode 100644 index 0000000..a4d0c95 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/DataQuery.java @@ -0,0 +1,849 @@ +package com.farm.core.sql.query; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.hibernate.Session; + +import com.farm.core.auth.util.AuthenticateInter; +import com.farm.core.auth.util.AuthenticateProvider; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.result.DataResults; +import com.farm.util.spring.HibernateSessionFactory; + +/** + * 数据库查询封装类 + * + * @author 王东 + * @version 2012 + * @version 2014-10-29 重构:1.缓存带分页2.重构代码3.缓存更新时使用线程 + * + */ +public class DataQuery { + // 定义日志记录器,用于记录DataQuery类的日志信息 + static final Logger log = Logger.getLogger(DataQuery.class); + // 定义缓存的最大容量 + private final static int CACHE_MAX_SIZE = 1000; + + /** + * 缓存器单位枚举值 + * 用于定义缓存过期时间的单位 + * + * @author Administrator + * + */ + public enum CACHE_UNIT { + /** + * 毫秒单位 + */ + Millisecond(1), + /** + * 秒单位 + */ + second(1000), + /** + * 分钟单位 + */ + minute(1000 * 60); + + // 枚举值对应的数值,表示时间单位转换成毫秒的值 + int num; + + // 枚举构造函数,用于初始化枚举值对应的数值 + CACHE_UNIT(int val) { + num = val; + } + } + // ... 其他类成员和方法 ... +} + + + private int pagesize = 10; + private boolean isCount = true; + private String currentPage;// 当前页 + private String sortTitleText;// 排序字段ok + private String sortTypeText;// 排序类型ok + private String ruleText;// 查询条件 + private String titles;// 结果集中展示的字段 + private String tables;// 表名或者内建视图 + private String userWhere;// 自定义查询条件 + private DBSort defaultSort;// 默认排序条件 + private String countSql; + protected static final Map resultCache = new HashMap();// 结果集合的缓存 + private boolean DISTINCT = false; + private long cacheMillisecond;// 启用缓存(毫秒数):只要该数字大于0则表示启用,从缓存区读取数据如果缓存区没有数据则数据库查询并更新到缓冲区 + protected List sort = new ArrayList(); + protected List queryRule = new ArrayList(); + + /** + * 获得查询对象实例 + * + * @param currentPage + * 当前页 + * @param titles + * 展现字段 + * @param tables + * 表描述 + * @return + */ + public static DataQuery getInstance(String currentPage, String titles, String tables) { + // 创建一个新的DataQuery实例 + DataQuery query = new DataQuery(); + // 设置当前页码 + query.setCurrentPage(currentPage); + // 设置标题集合 + query.setTitles(titles); + // 设置表名集合 + query.setTables(tables); + // 返回配置好的DataQuery实例 + return query; + } + + +public static DataQuery getInstance(int currentPage, String titles, String tables) { + // 将int类型的currentPage转换为String类型 + // 然后调用getInstance(String, String, String)方法获取DataQuery实例 + return getInstance(String.valueOf(currentPage), titles, tables); +} + + + /** + * 执行查询,该方法适用于sever中,没有对用于页面状态的序列化,没有缓存功能 + * + * @param session + * @return + * @throws SQLException + */ + public DataResult search(Session session) throws SQLException { + String key = null; + // -------------------缓存查询---------------------------- + // 检查是否启用了缓存功能(缓存时间大于0表示启用) + if (cacheMillisecond > 0) { + // 生成查询的MD5键值,用于缓存识别 + key = getQueryMD5Key(this); + // 确保键值生成成功 + if (key != null) { + // 启用缓存功能 + { + // 从缓存中获取数据结果 + DataResult dr = resultCache.get(key); + // 检查是否在缓存中找到了数据结果 + if (dr != null) { + // 计算缓存数据的时间差 + long time = new Date().getTime() - dr.getCtime().getTime(); + // 判断缓存数据是否在有效期内 + if (time < cacheMillisecond) { + // 缓存数据有效,直接返回缓存结果 + return dr; + } else { + // 缓存数据已超时,更新缓存时间 + dr.setCtime(new Date()); + // 即使超时也先返回过时的数据结果 + // 同时启动一个新的线程来更新缓存数据 + Searcher search = new Searcher(this); + Thread searchThread = new Thread(search); + searchThread.start(); + return dr; + } + } + } + } + // 如果没有缓存或键值生成失败,将继续执行后续的数据库查询操作 + } + // ...(此处省略了数据库查询的代码) + } + +// 缓存中超出缓存最大值的时候就将缓存清空 +// 检查缓存大小是否超过预设的最大值 +if (resultCache.size() > CACHE_MAX_SIZE) { + // 如果超过,清空缓存以防止内存溢出 + resultCache.clear(); +} +// 结束缓存大小检查的代码块 + +// -------------------缓存查询---------------------------- +// 检查排序条件是否为空 + if (sort.size() <= 0) { + // 如果为空,添加默认排序条件 + sort.add(defaultSort); +} + +// 初始化数据结果对象 +DataResult result = null; +try { +// 创建搜索器对象,用于执行查询操作 +Searcher search = new Searcher(this); +// 执行查询并获取结果 +result = search.doSearch(session); +// 设置结果集的标题 + result.setTitles(DataResults.getTitles(titles)); + // 设置排序标题文本 + result.setSortTitleText(sortTitleText); +// 设置排序类型文本 + result.setSortTypeText(sortTypeText); +} catch (Exception e) { + // 如果在查询过程中发生异常,抛出SQLException + throw new SQLException(e); +} + +// 检查是否启用了缓存功能 + if (cacheMillisecond > 0) { + // 启用缓存功能,将当前结果存入缓存 + if (key != null) { + // 设置结果集的创建时间 + result.setCtime(new Date()); + // 将结果集存入缓存,以键值对的形式 + resultCache.put(key, result); + } + } + +// 返回查询结果 + return result; + + +/** + * 执行查询,序列化页面状态,可配置为缓存 + * + * @return + * @throws SQLException + */ +public DataResult search() throws SQLException { + // 获取Hibernate会话对象,用于数据库操作 + Session session = HibernateSessionFactory.getSession(); + // 初始化数据结果对象 + DataResult result = null; + try { + // 调用重载的search方法,传入会话对象,执行查询并获取结果 + result = search(session); + } finally { + // 无论查询过程中是否发生异常,都确保关闭会话对象,释放资源 + session.close(); + } + // 返回查询结果 + return result; +} + + +/** + * 将查询对象转换为MD5验证码 + * + * @param query + * @return + */ +protected static String getQueryMD5Key(DataQuery query) { + // 初始化SQL字符串 + String sql = ""; + try { + // 使用HibernateQueryHandle解析DataQuery对象为SQL语句,并附加当前页码信息 + sql = HibernateQueryHandle.praseSQL(query) + ",PAGE:" + query.getCurrentPage(); + // 获取认证接口实例 + AuthenticateInter ai = AuthenticateProvider.getInstance(); + // 使用认证接口的encodeMd5方法对SQL语句进行MD5编码 + sql = ai.encodeMd5(sql); + } catch (SQLException e) { + // 如果在解析SQL或编码过程中发生SQLException,记录错误日志 + log.error(e + e.getMessage()); + // 返回null,表示无法生成MD5键 + return null; + } + // 返回编码后的MD5字符串,作为查询的键 + return sql; +} + + +/** + * 添加一个排序 + * + * @param dbsort + * @return + */ +public DataQuery addSort(DBSort dbsort) { + // 将给定的DBSort对象添加到排序列表中 + sort.add(dbsort); + // 返回当前DataQuery对象,以支持链式调用 + return this; +} + + /** + * 添加一个默认排序 + * + * @param dbsort + * @return + */ + public DataQuery addDefaultSort(DBSort dbsort) { + // 设置默认的排序规则为给定的DBSort对象 + defaultSort = dbsort; + // 返回当前DataQuery对象,以支持链式调用 + return this; + } + + +/** + * 清除排序 + * + * @param sort + */ +/** + * 清除所有排序规则 + * + * @return 当前DataQuery对象,支持链式调用 + */ +public DataQuery clearSort() { + // 清空排序规则列表 + this.sort.clear(); + // 返回当前对象,以便进行链式调用 + return this; +} + +/** + * 添加一个过滤条件 + * + * @param rule 要添加的DBRule对象 + * @return 当前DataQuery对象,支持链式调用 + */ +public DataQuery addRule(DBRule rule) { + // 对规则值进行病毒清理,确保安全性 + DataQuerys.wipeVirus(rule.getValue()); + // 将规则添加到查询规则列表中 + this.queryRule.add(rule); + // 返回当前对象,以便进行链式调用 + return this; +} + +/** + * 获得一个查询条件并从query中移除该条件 + * + * @param index 查询条件索引号 + * @return 被移除的DBRule对象 + */ +public DBRule getAndRemoveRule(int index) { + // 获取指定索引的查询条件 + DBRule dbrule = this.queryRule.get(index); + // 从查询规则列表中移除该条件 + queryRule.remove(index); + // 重新解析剩余的规则,更新规则文本 + ruleText = parseRules(); + // 返回被移除的规则对象 + return dbrule; +} + +/** + * 获得一个查询条件并从query中移除该条件,每次获得匹配到得第一个titleName 查询条件字段名 + * + * @param titleName 查询条件字段名 + * @return 被移除的DBRule对象,如果没有找到则返回null + */ +public DBRule getAndRemoveRule(String titleName) { + // 初始化索引为-1,表示未找到 + int n = -1; + // 遍历查询规则列表,寻找匹配的规则 + for (int i = 0; i < queryRule.size(); i++) { + // 如果规则键(字段名)与指定的titleName匹配(不区分大小写) + if (queryRule.get(i).getKey().equals(titleName.toUpperCase())) { + // 记录匹配规则的索引 + n = i; + // 找到第一个匹配的规则后退出循环 + break; + } + } + // 如果找到了匹配的规则 + if (n >= 0) { + // 调用getAndRemoveRule(int index)方法移除并返回规则 + return getAndRemoveRule(n); + } + // 如果没有找到匹配的规则,返回null + return null; +} + + + /** + * 将条件对象集合转换为条件字符串 + * + * @return + */ + private String parseRules() { + // 初始化一个StringBuffer用于构建查询规则字符串 + StringBuffer sb = null; + // 遍历查询规则列表 + for (DBRule node : queryRule) { + // 如果StringBuffer尚未初始化,则进行初始化 + if (sb == null) { + sb = new StringBuffer(); + } else { + // 如果StringBuffer已经包含内容,则在添加新规则前添加分隔符"_,_" + sb.append("_,_"); + } + // 添加规则的键(字段名) + sb.append(node.getKey()); + // 添加规则的比较符号 + sb.append(":"); + sb.append(node.getComparaSign()); + // 添加规则的值 + sb.append(":"); + sb.append(node.getValue()); + } + // 如果没有规则被添加,返回空字符串 + if (sb == null) { + return ""; + } else { + // 否则,返回构建好的查询规则字符串 + return sb.toString(); + } + } + + +/** + * 清除排序 + * + * @param sort + */ +public DataQuery clearRule() { + // 清空查询规则列表,移除所有已设置的查询条件 + this.queryRule.clear(); + // 返回当前对象,以便进行链式调用,继续其他操作 + return this; +} + + +/** + * 是否在SQL中加入distinct + * + * @param var + * true||false + */ +public DataQuery setDistinct(boolean var) { + // 设置DISTINCT标志,以指示查询是否应返回唯一记录 + DISTINCT = var; + // 返回当前对象,以便进行链式调用,继续其他配置或操作 + return this; +} + + /** + * 是否加入了distinct关键字 + * + * @return + */ + public boolean isDistinct() { + return DISTINCT; + } + + // pojo------------------------------- + /** + * 获得每页记录条数 + * + * @return + */ + public int getPagesize() { + return pagesize; + } + + /** + * 设置每页记录条数 + * + * @param pagesize + */ + public DataQuery setPagesize(int pagesize) { + this.pagesize = pagesize; + return this; + } + + /** + * 获得当前页 + * + * @return + */ + public String getCurrentPage() { + // 检查currentPage是否为空或只包含空白字符 + if (currentPage == null || currentPage.trim().length() <= 0) { + // 如果为空或只包含空白字符,返回默认页码"1" + return "1"; + } + // 否则,返回当前页码 + return currentPage; + } + + /** + * 设置当前页 + * + * @param currentPage + */ + public DataQuery setCurrentPage(String currentPage) { + // 将传入的页码字符串设置到当前对象的currentPage属性中 + this.currentPage = currentPage; + // 返回当前对象,以便进行链式调用,继续其他配置或操作 + return this; + } + + /** + * 设置当前页 + * + * @param currentPage + */ + public DataQuery setCurrentPage(int currentPage) { + // 将传入的整数值页码转换为字符串,并设置到当前对象的currentPage属性中 + this.currentPage = String.valueOf(currentPage); + // 返回当前对象,以便进行链式调用,继续其他配置或操作 + return this; + } + + /** + * 获得排序字段 + * + * @return + */ + public String getSortTitleText() { + return sortTitleText; + } + + /** + * 获得排序类型 + * + * @return + */ + public String getSortTypeText() { + return sortTypeText; + } + + /** + * 设置排序字段,但是会清理掉已有排序 + * + * @param sortTitleText + */ + public void setSortTitleText(String sortTitleText) { + // 设置排序标题文本 + this.sortTitleText = sortTitleText; + // 检查排序标题文本和排序类型文本是否都非空 + if (this.sortTitleText != null && this.sortTypeText != null) { + // 清除原有的排序规则 + sort.clear(); + // 创建新的DBSort对象并添加到排序列表中 + sort.add(new DBSort(this.sortTitleText, this.sortTypeText)); + } + } + + /** + * 设置排序类型 + * + * @param sortTypeText + * ASC||DESC + */ +/** + * 设置排序类型文本。 + * 如果传入的排序类型文本为"NULL"(不区分大小写且去除空格),则将其视为null。 + * 当排序标题文本和排序类型文本都非空时,根据这两个值创建一个新的DBSort对象, + * 并将其添加到排序列表中,同时清除原有的排序规则。 + * + * @param sortTypeText 要设置的排序类型文本。 + */ +public void setSortTypeText(String sortTypeText) { + // 检查传入的排序类型文本是否为"NULL",如果是,则将其设置为null + if (sortTypeText != null && sortTypeText.toUpperCase().trim().equals("NULL")) { + sortTypeText = null; + } + // 设置排序类型文本 + this.sortTypeText = sortTypeText; + // 检查排序标题文本和排序类型文本是否都非空 + if (this.sortTitleText != null && this.sortTypeText != null) { + // 清除原有的排序规则 + sort.clear(); + // 创建新的DBSort对象并添加到排序列表中 + sort.add(new DBSort(this.sortTitleText, this.sortTypeText)); + } +} + + +/** + * 获得条件描述字符串 + * + * @return + */ + public String getRuleText() { + return ruleText; + } + + /** + * 设置查询条件,但是会清理掉已有条件 + * + * @param ruleText + * 查询条件 + */ +/** + * 设置查询规则文本,并解析文本以构建查询规则列表。 + * 规则文本格式预期为 "字段名:操作符:值",多个规则用 "_,_" 分隔。 + * 如果规则文本不符合预期格式或为空,则清空查询规则列表。 + * + * @param ruleText 要设置的查询规则文本。 + */ +public void setRuleText(String ruleText) { + // 设置查询规则文本 + this.ruleText = ruleText; + // 初始化查询规则列表 + List list = null; + // 检查规则文本是否符合限制域的要求 + if (!checkStringForLimitDomain(ruleText)) { + // 如果不符合,初始化为空列表 + list = new ArrayList(); + } else { + // 替换规则文本中的占位符 "_D_" 为 ":" + ruleText = ruleText.replace("_D_", ":"); + // 按照规则分隔符 "_,_" 分割规则文本 + String[] strarray = ruleText.split("_,_"); + // 初始化查询规则列表 + list = new ArrayList(); + // 遍历分割后的规则字符串数组 + for (String onestr : strarray) { + // 检查规则字符串是否非空 + if (onestr != null && !onestr.trim().equals("")) { + // 按照 ":" 分割规则字符串 + String[] valueT = onestr.split(":"); + // 检查分割后的数组长度及元素非空 + if (valueT.length >= 3 && valueT[0] != null && valueT[1] != null && valueT[2] != null) { + // 检查字段名、操作符、值均非空 + if (!valueT[0].equals("") && !valueT[1].equals("") && !valueT[2].equals("")) { + // 创建DBRule对象并添加到列表 + DBRule dbrule = new DBRule(valueT[0], valueT[2], valueT[1]); + list.add(dbrule); + } + } + } + } + } + // 清空现有的查询规则列表 + queryRule.clear(); + // 将解析后的查询规则列表添加到查询规则中 + queryRule.addAll(list); +} + + +/** + * 获得结果集字段 + * + * @return + */ + public String getTitles() { + return titles; + } + + /** + * 设置结果集字段 + * + * @return + */ + public void setTitles(String titles) { + this.titles = titles; + } + + /** + * 获得表描述 + * + * @return + */ + public String getTables() { + return tables; + } + + /** + * 设置表描述 + * + * @param tables + */ + public void setTables(String tables) { + this.tables = tables; + } + + +/** + * 检查字符串是否为限制域内的有效字符串。 + * 当前实现仅检查字符串是否为null。 + * 如果字符串为null,则视为无效,返回false;否则,视为有效,返回true。 + * 此方法可以扩展以包含更多的检查逻辑,例如字符串长度、格式等。 + * + * @param str 要检查的字符串。 + * @return 如果字符串有效(非null),则返回true;否则返回false。 + */ +private boolean checkStringForLimitDomain(String str) { + // 检查字符串是否为null + if (str == null) + return false; + else + return true; +} + + +/** + * 获得用户自定义查询条件 + * + * @return + */ + public String getUserWhere() { + return userWhere; + } + + /** + * 设置自定义条件 + * + * @param userWhere + * 需要添加 AND关键字 + */ + public void setSqlRule(String sql) { + this.userWhere = sql; + } + + /** + * 增加自定义条件 + * + * @param userWhere + * 需要添加 AND关键字 + */ + public DataQuery addSqlRule(String SQLString) { + // 如果当前查询条件为null,则初始化为空字符串 + if (this.userWhere == null) { + this.userWhere = ""; + } + // 将传入的SQL字符串追加到查询条件中 + this.userWhere = this.userWhere + SQLString; + // 返回当前对象,支持链式调用 + return this; + } + + /** + * 初始化查询类 + * + * @param query + * 对象引用 + * @param tables + * 表 + * @param titles + * 字段 + */ + public static DataQuery init(DataQuery query, String tables, String titles) { + // 如果传入的query对象为null,则创建一个新的DataQuery对象 + if (query == null) { + query = new DataQuery(); + } + // 设置查询的表名 + query.setTables(tables); + // 设置查询的标题字段 + query.setTitles(titles); + // 如果排序类型未设置,则默认设置为"asc"(升序) + if (query.sortTypeText == null) { + query.sortTypeText = "asc"; + } + // 如果当前页码未设置,则默认设置为第一页 + if (query.getCurrentPage() == null) { + query.setCurrentPage("1"); + } + // 删除所有排序字段不合乎要求的 + { + int n = 0; + List indexArray = new ArrayList(); + // 遍历排序字段列表,检查每个排序字段是否有效 + for (; n < query.sort.size(); n++) { + // 如果排序字段的标题为null或等于"NULL"(不区分大小写),则记录该字段的索引 + if (query.sort.get(n).getSortTitleText() == null + || query.sort.get(n).getSortTitleText().trim().toUpperCase().equals("NULL")) { + indexArray.add(n); + } + } + // 遍历记录的索引列表,移除无效的排序字段 + for (Integer index : indexArray) { + query.sort.remove(index.intValue()); + } + } + + // 返回初始化后的DataQuery对象 + return query; + } + +/** + * 获得默认排序 + * + * @return + */ + public DBSort getDefaultSort() { + return defaultSort; + } + + /** + * 设置数据缓存 + * + * @param cachetime + * 缓存时间长 + * @param cache_unit + * 缓存时间单位 + */ + public void setCache(int cachetime, CACHE_UNIT cache_unit) { + this.cacheMillisecond = cachetime * cache_unit.num; + } + + /** + * 设置默认排序 + * + * @param defaultSort + */ + public void setDefaultSort(DBSort defaultSort) { + this.defaultSort = defaultSort; + } + + /** + * 获得查询条件格式序列 + * + * @return + */ + public List getQueryRule() { + return queryRule; + } + + /** + * 只查询结果不计算总页数 + */ + public void setNoCount() { + this.isCount = false; + } + + /** + * 是执行记录条数统计COUNT(*)的SQL语句 + * + * @return + */ + public boolean isCount() { + return isCount; + } + + public String getCountSql() { + return countSql; + } + + /** + * 如果传入该参数则按照该SQL进行结果集数量查询 + * + * @param countSql + */ + public void setCountSql(String countSql) { + this.countSql = countSql; + } + + /** + * 获取一个查询条件 + * + * @param string + * @return + */ + public String getRule(String key) { + // 遍历查询规则列表 + for (DBRule rule : this.queryRule) { + // 检查当前规则的键是否与指定键相匹配 + if (rule.getKey().equals(key)) { + // 如果匹配,返回当前规则的值 + return rule.getValue(); + } + } + // 如果没有找到匹配的键,返回null + return null; + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/DataQuerys.java b/src/farm-core/src/main/java/com/farm/core/sql/query/DataQuerys.java new file mode 100644 index 0000000..f3b4060 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/DataQuerys.java @@ -0,0 +1,54 @@ +package com.farm.core.sql.query; + +import java.util.Collection; + +import org.apache.commons.lang.StringEscapeUtils; + +/** + * 查询工具工具类 + * + * @author Administrator + * + */ +public class DataQuerys { + /** + * 检查SQL注入风险 + * + * @param var + * 拼写SQL的值,仅仅用于对值的处理 + */ + public static void wipeVirus(String var) { + // 使用StringEscapeUtils工具类对字符串进行SQL转义,以防止SQL注入 + var = StringEscapeUtils.escapeSql(var); + + // 检查字符串中是否包含括号或连续的竖线符号,这些可能是SQL注入的标志 + // 如果发现这些字符,计算它们的索引之和将会大于0 + if (var.indexOf("(") + var.indexOf(")") + var.indexOf("||") + var.indexOf("||") > 0) { + // 如果检测到潜在的SQL注入风险,抛出运行时异常 + throw new RuntimeException("违反SQL注入风险约束!"); + } + } + + /** + * 解析一个id的集合为多id的字符串拼接,可以用于sql的in子句如:'id1','id2'... + * + * @param vars + * @return + */ + public static String parseSqlValues(Collection vars) { + // 初始化用于存储SQL值列表的字符串 + String typeids_Rule = null; + // 遍历集合中的每个字符串元素 + for (String typeid : vars) { + // 如果是第一个元素,直接用单引号包裹 + if (typeids_Rule == null) { + typeids_Rule = "'" + typeid + "'"; + } else { + // 如果不是第一个元素,前面加上逗号,然后用单引号包裹 + typeids_Rule = typeids_Rule + "," + "'" + typeid + "'"; + } + } + // 返回构建好的SQL值列表字符串 + return typeids_Rule; + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/HibernateQueryHandle.java b/src/farm-core/src/main/java/com/farm/core/sql/query/HibernateQueryHandle.java new file mode 100644 index 0000000..be6d7b8 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/HibernateQueryHandle.java @@ -0,0 +1,281 @@ +package com.farm.core.sql.query; + +import java.sql.SQLException; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; + +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.result.DataResults; + +/** + * hibernate的帮助类 + * + * @author 王东 + * @date 2012-12-30 + */ +public class HibernateQueryHandle { + private static final String SqlSelectSize = " select count(*) num "; // 默认查询数量头 + + /** + * sql查询 + * + * @param session + * hibernateSession + * @param sql + * @param pagesize + * 每页多少条 + * @param currentPage + * 当前页 + * @return + * @throws SQLException + */ + protected static DataResult runSqlQuery(Session session, String querysql, + String countsql, int pagesize, int currentPage) throws SQLException { + long startTime = new Date().getTime(); // 记录查询开始时间 + if (querysql.indexOf("*") > 0) { + throw new SQLException("*不能存在于查询语句中,请明确查询字段!"); // 如果查询语句中包含*,则抛出异常,要求明确查询字段 + } + querysql = querysql.toUpperCase(); // 将查询语句转换为大写,以统一处理 + DataResult result = null; // 初始化结果对象 + int firstResourt; // 开始条数,即查询结果的起始索引 + int sizeResourt; // 单页显示的记录数 + sizeResourt = pagesize; // 设置单页显示的记录数 + firstResourt = (currentPage - 1) * sizeResourt; // 计算查询结果的起始索引 + String titles = querysql.substring(0, querysql.indexOf("FROM")); // 从查询语句中提取字段部分 + List> limap = DataResults.getMaps(titles, + runLimitQuery(session, querysql, firstResourt, sizeResourt)); // 执行分页查询并获取结果集 + result = DataResult.getInstance(limap, countsql == null ? limap.size() + : runLimitQueryNum(session, countsql), currentPage, pagesize); // 创建DataResult实例,包含结果集、总记录数、当前页码和每页大小 + long endTime = new Date().getTime(); // 记录查询结束时间 + result.setRuntime(endTime - startTime); // 设置查询运行时间 + return result; // 返回查询结果对象 + } + + + /** + * DataQuery查询 + * + * @param session + * hibernate会话 + * @param dataquery + * @return + * @throws SQLException + */ + protected static DataResult runDataQuery(Session session, + DataQuery dataquery) throws SQLException { + long startTime = new Date().getTime(); // 记录方法开始执行的时间 + DataResult result = null; // 初始化结果对象 + try { + int firstResourt; // 开始条数,即查询结果的起始索引 + int sizeResourt; // 单页显示的记录数 + String upsql = praseSQL(dataquery); // 解析DataQuery对象为SQL语句 + String partSql = upsql.substring(upsql.indexOf(" FROM ")); // 提取SQL语句中的FROM子句之后的部分 + String headsql = upsql.substring(0, upsql.indexOf(" FROM ")); // 提取SQL语句中的SELECT子句部分 + if (headsql.indexOf("*") >= 0) { + throw new SQLException("select can't contain *"); // 如果SELECT子句包含*,则抛出异常 + } + sizeResourt = dataquery.getPagesize(); // 获取每页显示的记录数 + firstResourt = (Integer.valueOf(dataquery.getCurrentPage().trim()) - 1) + * sizeResourt; // 计算查询结果的起始索引 + // 执行分页查询并获取结果集,将结果转换为List> + List> limap = DataResults.getMaps(dataquery + .getTitles(), runLimitQuery(session, upsql, firstResourt, + sizeResourt)); + if (dataquery.isDistinct()) { + // 如果查询要求去重,且SQL语句中包含ORDER BY子句,则去除ORDER BY子句 + if (upsql.indexOf("ORDER BY") > 0) { + upsql = upsql.substring(0, upsql.indexOf("ORDER")); + } + partSql = " FROM (" + upsql + ") counum"; // 重新构建查询总数量的SQL语句 + } + // 初始化查询结果总数量为当前页的结果数量 + int count = limap.size(); + if (dataquery.isCount()) { + // 如果需要查询总数量,且partSql中包含ORDER BY子句,则去除ORDER BY子句 + if (partSql.toUpperCase().indexOf("ORDER BY") > 0) { + partSql = partSql.substring(0, partSql.toUpperCase() + .indexOf("ORDER BY")); + } + partSql = SqlSelectSize + partSql; // 添加查询总数量的SQL前缀 + // 执行查询总数量的SQL语句,如果提供了countSql,则使用countSql + count = runLimitQueryNum(session, + dataquery.getCountSql() == null ? partSql : dataquery + .getCountSql()); + } + // 创建DataResult实例,包含结果集、总记录数、当前页码和每页大小 + result = DataResult.getInstance(limap, count, Integer + .valueOf(dataquery.getCurrentPage()), dataquery + .getPagesize()); + } catch (Exception e) { + throw new SQLException(e); // 捕获异常并转换为SQLException抛出 + } + long endTime = new Date().getTime(); // 记录方法结束执行的时间 + result.setRuntime(endTime - startTime); // 设置查询运行时间 + return result; // 返回查询结果对象 + } + + + /** + * 查询条件转换成sql语句 + * + * @param dataquery + * 查询条件封装 + * @return + * @throws SQLException + */ + public static String praseSQL(DataQuery dataquery) throws SQLException { + String distinct = ""; // 初始化distinct字符串,用于可能的去重查询 + if (dataquery.isDistinct()) { + distinct = " distinct "; // 如果需要去重,则设置distinct字符串 + } + StringBuffer SQL_run = new StringBuffer().append("select ") // 开始构建SQL查询语句 + .append(distinct) // 添加distinct关键字(如果有) + .append(dataquery.getTitles().toUpperCase()) // 添加查询字段,并转换为大写 + .append(getSql_part(dataquery)); // 添加SQL语句的其余部分(例如FROM、WHERE等) + return upCaseSQLKEY(SQL_run.toString()); // 将SQL关键字转换为大写并返回 + } + + + /** + * 将SQL关键字转换为大写 + * + * @param SQL + * @return + */ + private static String upCaseSQLKEY(String SQL) { + SQL = SQL.replace(" select ", " SELECT "); // 将SQL语句中的"select"关键字转换为大写 + SQL = SQL.replace(" from ", " FROM "); // 将SQL语句中的"from"关键字转换为大写 + SQL = SQL.replace(" as ", " AS "); // 将SQL语句中的"as"关键字转换为大写 + SQL = SQL.replace(" where ", " WHERE "); // 将SQL语句中的"where"关键字转换为大写 + SQL = SQL.replace(" order by ", " ORDER BY "); // 将SQL语句中的"order by"关键字转换为大写 + return SQL; // 返回转换后的SQL语句 + } + + + @SuppressWarnings("unchecked") + private static List runLimitQuery(Session session_, String Sql, + int firstResourt, int sizeResourt) { + // 初始化结果列表 + List list = null; + try { + // 使用传入的Session创建SQL查询 + SQLQuery sqlQuery = session_.createSQLQuery(Sql); + // 设置查询结果的起始位置 + sqlQuery.setFirstResult(firstResourt); + // 设置查询结果的最大数量 + sqlQuery.setMaxResults(sizeResourt); + // 执行查询并获取结果列表 + list = sqlQuery.list(); + } catch (Exception e) { + // 捕获并抛出运行时异常,以便调用者处理 + throw new RuntimeException(e); + } + + // 返回查询结果列表 + return list; + } + + + private static int runLimitQueryNum(Session session_, String countSql) { + // 使用传入的Session创建SQL查询,用于执行计数SQL语句 + SQLQuery sqlQuery = session_.createSQLQuery(countSql); + // 执行查询并获取结果列表的第一个元素,即记录总数 + Object num = sqlQuery.list().get(0); + // 将查询结果转换为Integer类型 + Integer renum = (Integer) Integer.valueOf(num.toString()); + // 获取Integer对象的int值 + int n = renum.intValue(); + // 返回记录总数 + return n; + } + + + private static String getSql_part(DataQuery query) throws SQLException { + // 构建SQL语句的剩余部分,包括FROM子句、WHERE子句和排序子句 + String sql_part = getSql_from(query) + getSql_where(query) + + getSortWhere(query); + // 返回构建好的SQL部分 + return sql_part; + } + + + private static String getSortWhere(DataQuery query) { + // 获取排序条件列表 + List sortList = query.sort; + // 初始化排序子句,以" order by "开始 + StringBuffer where = new StringBuffer(" order by "); + // 标记是否至少有一个有效的排序条件 + boolean isHaveSort = false; + // 遍历排序条件列表 + for (Iterator iterator = sortList.iterator(); iterator.hasNext();) { + // 获取当前排序条件对象 + DBSort name = (DBSort) iterator.next(); + // 检查排序条件对象及其属性是否非空 + if (name != null && name.getSortTitleText() != null + && name.getSortTypeText() != null + && !name.getSortTitleText().equals("") + && !name.getSortTypeText().equals("")) { + // 添加排序字段和排序类型到排序子句 + where.append(name.getSortTitleText()); + where.append(" "); + where.append(name.getSortTypeText()); + // 标记已添加至少一个有效排序条件 + isHaveSort = true; + // 如果还有更多排序条件,添加逗号分隔符 + if (iterator.hasNext()) { + where.append(" , "); + } + } + } + // 如果没有有效排序条件,返回空字符串 + if (!isHaveSort) { + return ""; + } + // 返回构建好的排序子句 + return where.toString(); + } + + private static String getSql_from(DataQuery query) { + // 构建SQL语句的FROM子句 + // 获取查询对象中的表名,并添加到"from"关键字后,前后添加空格以分隔其他子句 + String sql_from = " from " + query.getTables() + " "; + // 返回构建好的FROM子句 + return sql_from; + } + + + private static String getSql_where(DataQuery query) throws SQLException { + // 检查查询规则是否为空,如果为空则抛出SQLException + if (query.queryRule == null) { + throw new SQLException("whereList is null!"); + } + // 获取查询规则迭代器 + Iterator it_ = query.queryRule.iterator(); + // 初始化WHERE子句的StringBuffer,并预置"where 1=1"以方便后续条件的拼接 + StringBuffer where_ = new StringBuffer(""); + where_.append(" where 1=1 "); + // 遍历查询规则,将每个规则的条件添加到WHERE子句中 + while (it_.hasNext()) { + DBRule _queryld = it_.next(); + // 只有当规则和规则的值不为空时,才将其条件添加到WHERE子句 + if (_queryld != null && _queryld.getValue() != null) + where_.append(_queryld.getThisLimit()); + } + // 将StringBuffer转换为String + String sql_where = where_.toString(); + // 如果用户定义的WHERE子句不为空,则将其添加到SQL的WHERE子句中 + if (query.getUserWhere() != null + && query.getUserWhere().trim().length() > 1) { + sql_where = sql_where + " " + query.getUserWhere() + " "; + } + // 返回构建好的WHERE子句 + return sql_where; + } + + +} diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/SQLQuery.java b/src/farm-core/src/main/java/com/farm/core/sql/query/SQLQuery.java new file mode 100644 index 0000000..a5e1d6a --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/SQLQuery.java @@ -0,0 +1,104 @@ +package com.farm.core.sql.query; + +import java.sql.SQLException; + +import org.hibernate.Session; + +import com.farm.core.sql.result.DataResult; +import com.farm.util.spring.HibernateSessionFactory; + +public class SQLQuery { + private String sql; // SQL查询语句 + private int pagesize; // 每页显示的记录数 + private int currentPage; // 当前页码 + private String countSql; // 用于查询总记录数的SQL语句 + + private SQLQuery() { + // 私有构造函数,防止直接实例化 + } + + /** + * 获取SQLQuery实例 + * @param sql SQL查询语句 + * @param countSql 数量查询可以为空NULL + * @param pagesize 每页显示的记录数 + * @param currentPage 当前页码 + * @return SQLQuery实例 + */ + public static SQLQuery getInstance(String sql, String countSql, + int pagesize, int currentPage) { + SQLQuery query = new SQLQuery(); + query.setCurrentPage(currentPage); + query.setPagesize(pagesize); + query.setSql(sql); + query.setCountSql(countSql); + return query; + } + + /** + * 执行查询 + * + * @param session Hibernate会话 + * @return 查询结果 + * @throws SQLException 如果查询过程中发生SQL异常 + */ + public DataResult search(Session session) throws SQLException { + return HibernateQueryHandle.runSqlQuery(session, sql, countSql, + pagesize, currentPage); + } + + + /** + * 执行查询 + * + * @return 查询结果 + * @throws SQLException 如果查询过程中发生SQL异常 + */ + public DataResult search() throws SQLException { + Session session = HibernateSessionFactory.getSession(); // 获取Hibernate会话 + DataResult result = null; + try { + result = this.search(session); // 使用获取的会话执行查询 + } catch (Exception e) { + throw new SQLException(e); // 捕获异常并转换为SQLException抛出 + } finally { + session.close(); // 确保会话被关闭 + } + return result; + } + + // --------------------------------------------------------------------- + // 以下是属性的getter和setter方法 + public String getSql() { + return sql; + } + + public void setSql(String sql) { + this.sql = sql; + } + + public int getPagesize() { + return pagesize; + } + + public void setPagesize(int pagesize) { + this.pagesize = pagesize; + } + + public int getCurrentPage() { + return currentPage; + } + + public void setCurrentPage(int currentPage) { + this.currentPage = currentPage; + } + + public String getCountSql() { + return countSql; + } + + public void setCountSql(String countSql) { + this.countSql = countSql; + } + +} diff --git a/src/farm-core/src/main/java/com/farm/core/sql/query/Searcher.java b/src/farm-core/src/main/java/com/farm/core/sql/query/Searcher.java new file mode 100644 index 0000000..71491f9 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/query/Searcher.java @@ -0,0 +1,60 @@ +package com.farm.core.sql.query; + +import java.sql.SQLException; +import java.util.Date; + +import org.hibernate.Session; + +import com.farm.core.sql.result.DataResult; +import com.farm.util.spring.HibernateSessionFactory; + +/** + * DataQuery的查询器,可以通过线程启动(将查询结果更新到缓存中)或直接执行dosearch + * + * @author 王东 + * @version 2014-10-29 + * + */ +public class Searcher implements Runnable { + + private DataQuery query = null; // 查询条件对象 + private DataResult result = null; // 查询结果对象 + + @SuppressWarnings("unused") + private Searcher() { + // 私有构造函数,防止无参实例化 + } + + public Searcher(DataQuery query) { + this.query = query; // 初始化Searcher时设置查询条件 + } + + /* + * 只有通过缓存查询,且缓存过期才会启动此线程进行查询 + */ + @Override + public void run() { + Session session = HibernateSessionFactory.getSession(); // 获取Hibernate会话 + try { + result = doSearch(session); // 执行查询操作 + // 启用缓存功能,将当前结果存入缓存 + String key = DataQuery.getQueryMD5Key(query); // 根据查询条件生成MD5键 + if (key != null) { + result.setCtime(new Date()); // 设置结果的时间戳 + DataQuery.resultCache.put(key, result); // 将结果存入缓存 + } + } finally { + session.close(); // 确保会话最终被关闭 + } + } + + public DataResult doSearch(Session session) { + try { + result = HibernateQueryHandle.runDataQuery(session, this.query); // 执行数据查询 + } catch (SQLException e) { + throw new RuntimeException(e); // 捕获SQL异常,转换为运行时异常抛出 + } + return result; // 返回查询结果 + } +} + diff --git a/src/farm-core/src/main/java/com/farm/core/sql/result/DataResult.java b/src/farm-core/src/main/java/com/farm/core/sql/result/DataResult.java new file mode 100644 index 0000000..cfb7726 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/result/DataResult.java @@ -0,0 +1,708 @@ +package com.farm.core.sql.result; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.apache.commons.beanutils.BeanUtils; +import org.apache.log4j.Logger; + +/** + * 结果集合封装类,提供分页支持,对结果集合进行常见操作 + * + * @author 王东 2010年底编写 2012-08-17 增加注释 + */ +public class DataResult { + private static final Logger log = Logger.getLogger(DataResult.class); + private long runtime; + /** + * + */ + @SuppressWarnings("unused") + private static final long serialVersionUID = 1L; + /** + * 每页记录数 + */ + private int pageSize = 10; + /** + * 当前页 + */ + private int currentPage; + /** + * 总记录数 + */ + private int totalSize; + + /** + * 总页数 + */ + private int totalPage; + + /** + * 结果集合 + */ + private List> resultList; + /** + * 结果集合 + */ + private List> resultListArray; + /** + * 创建时间 + */ + private Date ctime; + /** + * 结果集字段名 + */ + private List titles; + + private String message;// 页面消息 + // 排序字段 + private String sortTitleText; + // 排序类型 + private String sortTypeText; + // 开始页(显示5页) + private int startPage; + // 结束页(显示5页) + private int endPage; + + /** + * 私有构造方法 + */ + private DataResult() { + } + + public static DataResult getInstance() { + // 调用重载的getInstance方法,传入默认参数,返回一个默认的DataResult实例 + return getInstance(new ArrayList(), 0, 1, 0); + } + + /** + * 获得类实例 + * + * @param data 记录集合,包含查询结果的数据 + * @param _totalSize 总记录数,表示查询结果的总条数 + * @param _currentPage 当前页,表示当前分页的页码 + * @param _PageSize 每页记录数,表示每页显示的记录条数 + * @return 结果集合封装对象,包含分页信息和数据集合 + */ + public static DataResult getInstance(List> data, int _totalSize, int _currentPage, + int _PageSize) { + // 创建DataResult实例 + DataResult result = new DataResult(); + // 设置记录集合 + result.resultList = data; + // 设置总记录数 + result.totalSize = _totalSize; + // 设置当前页 + result.currentPage = _currentPage; + // 设置每页记录数 + result.pageSize = _PageSize; + + // 如果总记录数为0,则设置总页数、起始页和结束页为0 + if (result.totalSize == 0) { + result.totalPage = 0; + result.startPage = 0; + result.endPage = 0; + return result; + } + + // 计算总页数 + result.totalPage = result.totalSize / result.pageSize + 1; + // 如果总记录数能被每页记录数整除,则总页数减1 + if (result.totalSize % result.pageSize == 0) { + result.totalPage = result.totalPage - 1; + } + + // 计算起始页 + result.startPage = result.currentPage - 2; + // 计算结束页 + result.endPage = result.currentPage + 2; + + // 如果起始页小于1,则调整起始页和结束页 + if (result.startPage < 1) { + int cha = 1 - result.startPage; // 计算起始页与1的差值 + result.startPage = 1; // 设置起始页为1 + result.endPage = result.endPage + cha; // 调整结束页 + } + + // 如果结束页大于总页数,则设置结束页为总页数 + if (result.endPage > result.totalPage) { + result.endPage = result.totalPage; + } + + // 返回设置好的DataResult实例 + return result; + } + + + /** + * 加载列表类型的结果集合 resultListArray 保存一个数组类型的数据副本 + */ + public void LoadListArray() { + resultListArray = new ArrayList>(); + for (Map node : this.getResultList()) { + List list = new ArrayList(); + for (String key : titles) { + list.add(node.get(key)); + } + resultListArray.add(list); + } + } + + /** + * 合并列(在结果集合中增加标志位(titleKey + "ROWSPAN")如CIDROWSPAN,其值: 0代表已处理被合并 + * n>0代表合并的行数) 合并逻辑:titleKey字段值相同则合并 + * + * @param titleKey + * @return + */ + public DataResult mergeCells(String titleKey) { + String key = titleKey + "ROWSPAN"; + for (int i = 0; i < resultList.size(); i++) { + // System.out.println(list.get(i).get("CNAME")); + Object cellsVal = resultList.get(i).get(titleKey);// 合并内容 + Object rowspan = resultList.get(i).get(key);// 合并行数 + if (rowspan == null) { + // 合并信息放入rowspan中null代表未处理0代表已处理被合并 n>0代表已处理已经合并 + int rowspanNum = 0; + for (int n = i; n < resultList.size(); n++) { + Object tempVal = resultList.get(n).get(titleKey); + if (tempVal != null && tempVal.equals(cellsVal)) { + rowspanNum++; + resultList.get(i).put(key, 0); + } else { + break; + } + } + // 设置合并数 + resultList.get(i).put(key, rowspanNum); + } else { + continue; + } + } + return this; + } + + /** + * 加载列表类型的结果集合 resultListArray 保存一个数组类型的数据副本 + */ + public void LoadListArray() { + // 初始化resultListArray为一个新的ArrayList,用于存储转换后的列表数据 + resultListArray = new ArrayList>(); + + // 遍历getResultList()返回的Map列表,每个Map代表一条记录 + for (Map node : this.getResultList()) { + // 为每条记录创建一个新的ArrayList,用于存储该记录的值 + List list = new ArrayList(); + + // 遍历titles数组,titles包含了需要从记录中提取的键名 + for (String key : titles) { + // 将每个键对应的值添加到list中 + list.add(node.get(key)); + } + + // 将包含记录值的list添加到resultListArray中 + resultListArray.add(list); + } + } + + + /** + * 设置结果集合的消息参数 + * + * @param dataResult + * 结果集合对象 + * @param messager + * 消息文本 + * @return 结果集合对象 + */ + public static DataResult setMessager(DataResult dataResult, String messager) { + // 检查传入的dataResult是否为null + if (dataResult == null) { + // 如果为null,则创建一个新的DataResult实例 + dataResult = new DataResult(); + // 并初始化其resultList属性,为一个空的ArrayList,用于存储查询结果 + dataResult.resultList = new ArrayList>(); + } + // 设置DataResult的消息属性为传入的messager字符串 + dataResult.setMessage(messager); + // 返回设置好消息的DataResult实例 + return dataResult; + } + + + /** + * 打印结果集合内容 + */ + public void printDataInfo() { + // 打印调试信息的开始分隔符 + System.out.println( + "############ debug开始 #############################################################"); + // 调用DataResults类的静态方法printMaps,打印当前对象的结果列表 + DataResults.printMaps(this.getResultList()); + // 打印当前页码 + System.out.println("当前页:" + this.getCurrentPage()); + // 打印总页数 + System.out.println("全部页:" + this.gettotalPage()); + // 打印总记录数 + System.out.println("全部记录:" + this.getTotalSize()); + // 打印每页的记录数 + System.out.println("每页数:" + this.getPageSize()); + // 打印消息内容 + System.out.println("消息:" + this.message); + // 打印调试信息的结束分隔符 + System.out.println( + "############ debug结束 #############################################################"); + } + + + /** + * 对结果集合中某个字段值进行替换,用于数据字典的翻译 + * + * @param dictionary + * 字典map + * @param title + * 翻译字段名 如:TYPE + */ + public DataResult runDictionary(Map dictionary, String title) { + for (Map node : resultList) { + String key = String.valueOf(node.get(title)); + Object value = dictionary.get(key); + if (value != null) { + node.put(title, value); + } + } + return this; + } + + /** + * 对结果集合中某个字段值进行替换,用于数据字典的翻译 + * + * @param str + * 字典描述字符串 "1:可用,2:禁用" + * @param title + * 翻译字段名 如:TYPE + */ + public DataResult runDictionary(Map dictionary, String title) { + // 遍历结果列表中的每个节点 + for (Map node : resultList) { + // 从节点中获取标题对应的键值,转换为字符串 + String key = String.valueOf(node.get(title)); + // 在字典中查找对应的值 + Object value = dictionary.get(key); + // 如果在字典中找到了对应的值,则替换节点中的原值 + if (value != null) { + node.put(title, value); + } + } + // 返回当前DataResult对象,以便链式调用 + return this; + } + + + /** + * 翻译结果集合中的时间格式 yyyyMMddHHmmss + * 前提是数据库中的字段值必须是如201208220408的格式yyyyMMddHHmmss支持14或12位的 + * + * @param title + * 翻译字段名 如:TYPE + * @param yyyyMMddHHmmss + * 翻译成的格式 + */ + public void runformatTime(String title, String yyyyMMddHHmmss) { + // 获取查询结果列表 + List> list = this.getResultList(); + // 遍历结果列表中的每个节点 + for (Map node : list) { + try { + String time = null; + // 检查节点中标题对应的值是否为java.sql.Date类型 + if (node.get(title) instanceof java.sql.Date) { + // 将java.sql.Date转换为java.util.Date + java.util.Date d = new java.util.Date(((java.sql.Date) node.get(title)).getTime()); + // 创建日期格式化对象,格式为"yyyyMMdd" + SimpleDateFormat ormat = new SimpleDateFormat("yyyyMMdd"); + // 格式化日期 + time = ormat.format(d); + } else { + // 如果不是java.sql.Date类型,直接获取字符串值 + time = (String) node.get(title); + } + // 如果时间为空或空白字符串,跳过当前循环 + if (time == null || time.trim().length() <= 0) { + continue; + } + // 如果时间字符串长度为12,表示只有日期和时间到分钟 + if (12 == time.length()) { + // 创建原时间格式化对象,格式为"yyyyMMddHHmm" + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm"); + // 创建新时间格式化对象,格式由参数yyyyMMddHHmmss指定 + SimpleDateFormat newSdf = new SimpleDateFormat(yyyyMMddHHmmss); + // 解析原时间字符串为Date对象 + Date date = sdf.parse(time); + // 格式化Date对象为新的时间字符串,并更新节点中的值 + node.put(title, newSdf.format(date)); + } else { + // 如果时间字符串长度不为12,尝试补全时间字符串到14位 + try { + // 补全时间字符串 + time = (time + "00000000000000").substring(0, 14); + // 创建原时间格式化对象,格式为"yyyyMMddHHmmss" + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + // 创建新时间格式化对象,格式由参数yyyyMMddHHmmss指定 + SimpleDateFormat newSdf = new SimpleDateFormat(yyyyMMddHHmmss); + // 解析原时间字符串为Date对象 + Date date = sdf.parse(time); + // 格式化Date对象为新的时间字符串,并更新节点中的值 + node.put(title, newSdf.format(date)); + } catch (ParseException e) { + // 如果解析失败,将节点中的值设置为null + node.put(title, null); + } + } + } catch (Exception e) { + // 捕获并记录异常 + log.warn(e); + } + } + } + + + /** + * 从一个结果集合中去掉另一个结果集合(去重字段和id字段必须为字符串) + * + * @param result + * 结果集合 + * @param mapTitle + * 除去时依照的重复字段 + * @return 结果集合对象 + */ + public DataResult removeDataResult(DataResult result, String mapTitle) { + // 创建一个HashSet来存储所有不重复的键值 + Set keyset = new HashSet(); + // 遍历结果列表,收集所有已有的重复字段 + for (Map node : result.getResultList()) { + keyset.add((String) node.get(mapTitle)); + } + // 创建一个临时列表来存储需要删除的节点 + List> temp = new ArrayList>(); + // 遍历当前对象的结果列表 + for (Map node : resultList) { + // 获取节点中指定标题的键值 + String key = (String) node.get(mapTitle); + // 检查键值是否非空 + if (key != null && !"".equals(key)) { + // 尝试将键值添加到keyset中,如果添加失败,说明键值已存在,即重复 + if (!keyset.add(key)) { + // 将重复的节点添加到临时列表中 + temp.add(node); + // 更新总大小 + totalSize = totalSize - 1; + } + } + } + // 遍历临时列表,从结果列表中移除重复的节点 + for (Map node : temp) { + resultList.remove(node); + } + // 返回修改后的DataResult对象 + return result; + } + + /** + * 按字段去重 + * + * @param title + * 去重字段名 如:TYPE + * @return 结果集合对象 + */ + public DataResult runDistinct(String title) { + // 获取当前DataResult对象的结果列表 + List> list = this.getResultList(); + // 创建一个新的列表,用于存储去重后的结果 + List> listresult = new ArrayList>(); + // 创建一个HashSet,用于存储不重复的键值 + Set keySet = new HashSet(); + // 遍历原始结果列表 + for (Map node : list) { + // 获取每个节点中指定标题的键值,并转换为字符串 + String key = node.get(title).toString(); + // 尝试将键值添加到keySet中,如果添加成功,说明键值不重复 + if (keySet.add(key)) { + // 将不重复的节点添加到新列表中 + listresult.add(node); + } + } + // 将去重后的列表设置回DataResult对象 + this.setResultList(listresult); + // 返回当前DataResult对象,以便进行链式调用 + return this; + } + + + /** + * 获得每页记录数 + * + * @return + */ + public int getPageSize() { + return pageSize; + } + + /** + * 获得当前页 + * + * @return + */ + public int getCurrentPage() { + return currentPage; + } + + /** + * 获得总页数 + * + * @return + */ + public int gettotalPage() { + return totalPage; + } + + /** + * 获得结果集合 + * + * @return + */ + public List> getResultList() { + return resultList; + } + + /** + * 获得结果集消息 + * + * @return + */ + public String getMessage() { + return message; + } + + /** + * 设置结果集消息 + * + * @param message + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * 设置结果集中数据对象 + * + * @param resultList + */ + public void setResultList(List> resultList) { + this.resultList = resultList; + } + + /** + * 为数据添加一个字段 + * + * @param titel + * 要添加的字段名 + * @param value + * 要填充的值 + */ + public void addTitle(String titel, String value) { + // 遍历结果列表中的每个节点 + for (Map node : resultList) { + // 在每个节点中添加一个新的键值对,键为titel,值为value + node.put(titel, value); + } + // 注意:此方法没有返回值,它直接修改了当前对象中的resultList + } + + + /** + * 获得LIst类型的数据封装 + * + * @return + */ + public List> getResultListArray() { + return resultListArray; + } + + /** + * 填充LIst类型的数据封装 + * + * @param resultListArray + */ + public void setResultListArray(List> resultListArray) { + this.resultListArray = resultListArray; + } + + /** + * 获得记录总数 + * + * @return + */ + public int getTotalSize() { + return totalSize; + } + + /** + * 获得数据总页数 + * + * @return + */ + public int getTotalPage() { + return totalPage; + } + + /** + * 获得字段名序列 + * + * @return + */ + public List getTitles() { + return titles; + } + + /** + * 设置字段名序列 + * + * @param titles字段名序列 + */ + public void setTitles(List titles) { + this.titles = titles; + } + + /** + * 获得排序字段 + * + * @return + */ + public String getSortTitleText() { + return sortTitleText; + } + + public void setSortTitleText(String sortTitleText) { + this.sortTitleText = sortTitleText; + } + + /** + * 获得创建时间 + * + * @return + */ + public Date getCtime() { + return ctime; + } + + /** + * 设置创建时间 + * + * @return + */ + public void setCtime(Date ctime) { + this.ctime = ctime; + } + + /** + * 获得排序类型字段 + * + * @return + */ + public String getSortTypeText() { + return sortTypeText; + } + + /** + * 设置排序类型字段 + * + * @param sortTypeText + */ + public void setSortTypeText(String sortTypeText) { + this.sortTypeText = sortTypeText; + } + + /** + * 获得一个对象集合 + * + * @param class1 + * @return + */ + @SuppressWarnings("unchecked") + public List getObjectList(@SuppressWarnings("rawtypes") Class class1) { + // 创建一个泛型列表,用于存储转换后的对象 + @SuppressWarnings("rawtypes") + List list = new ArrayList(); + // 遍历getResultList()返回的列表,每个元素是一个Map,代表数据记录 + for (Map node : getResultList()) { + Object obj = null; + try { + // 使用传入的class1实例化一个新的对象 + obj = class1.newInstance(); + // 遍历Map中的每个键值对,键是字段名,值是字段值 + for (Entry field : node.entrySet()) { + // 使用BeanUtils将Map中的键值对设置到新对象的相应属性中 + // 注意:这里将键转换为小写,以确保属性名匹配 + BeanUtils.setProperty(obj, field.getKey().toLowerCase(), field.getValue()); + } + } catch (Exception e) { + // 如果在实例化对象或设置属性时发生异常,抛出运行时异常 + throw new RuntimeException(e); + } + // 将填充好的对象添加到列表中 + list.add(obj); + } + // 返回包含所有转换对象的列表 + return list; + } + + + public int getStartPage() { + // 返回分页查询的起始页码 + return startPage; + } + + public void setStartPage(int startPage) { + // 设置分页查询的起始页码 + this.startPage = startPage; + } + + public int getEndPage() { + // 返回分页查询的结束页码 + return endPage; + } + + public void setEndPage(int endPage) { + // 设置分页查询的结束页码 + this.endPage = endPage; + } + + public long getRuntime() { + // 返回查询操作的运行时间 + return runtime; + } + + public void setRuntime(long runtime) { + // 设置查询操作的运行时间 + this.runtime = runtime; + } + + public void runHandle(ResultsHandle handle) { + // 遍历结果列表,对每行数据执行处理 + for (Map row : this.getResultList()) { + // 调用传入的处理接口,处理当前行数据 + handle.handle(row); + } + } + +} +} diff --git a/src/farm-core/src/main/java/com/farm/core/sql/result/DataResults.java b/src/farm-core/src/main/java/com/farm/core/sql/result/DataResults.java new file mode 100644 index 0000000..93828a4 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/result/DataResults.java @@ -0,0 +1,200 @@ +package com.farm.core.sql.result; + +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.log4j.Logger; + +/** + * 结果集合工具类 + * + * @author 王东 + * + */ +public class DataResults { + private static final Logger log = Logger.getLogger(DataResults.class); + + /** + * 由setMessage方法获得一个带消息的DataResult对象 + * + * @param message消息 + * @return DataResult对象 + */ + public static DataResult setException(DataResult result, Exception e) { + // 检查传入的DataResult对象是否为null,如果是,则创建一个新的实例 + if (result == null) { + result = DataResult.getInstance( + new ArrayList>(), 0, 1, 10); + } + // 检查传入的异常对象e是否为null,如果不是,则设置DataResult的消息为异常信息 + if (e != null) { + // 将异常对象和异常消息拼接后设置为DataResult的消息 + result.setMessage(e + e.getMessage()); + // 记录错误日志,包括异常信息 + log.error(result.getMessage()); + } + // 返回设置好的DataResult对象 + return result; + } + + + /** + * 由一个hibernater结果集合获得一个List> + * + * @param names + * a.id,a.subject,b.rname,a.visit,COUNT(a.id) AS num, + * @param resulresult + * List + * @return + */ + public static List> getMaps(String names, + List t) { + + // 检查输入参数names和t是否为null,如果是,则抛出IllegalArgumentException异常 + if (names == null || t == null) { + throw new IllegalArgumentException("参数异常!"); + } + // 将中文逗号替换为英文逗号,并将字符串转换为大写 + names = names.replace(",", ",").toUpperCase(); + // 使用逗号分割names字符串,得到字符串数组 + String[] nameArray = names.split(","); + // 创建一个ArrayList来存储最终的Map列表 + List> list = new ArrayList>(); + // 获取t的迭代器,用于遍历所有的Object数组 + for (Iterator iterator = t.iterator(); iterator.hasNext();) { + // 获取下一个Object数组 + Object[] objects = (Object[]) iterator.next(); + // 创建一个HashMap来存储当前数组的键值对 + Map mapresult = new HashMap(); + // 获取结果记录字段值的数量 + int valueLength = objects.length; + // 如果名称数组的长度小于字段值数量,则使用名称数组的长度 + if (nameArray.length < valueLength) { + valueLength = nameArray.length; + } + try { + // 遍历字段值,将其填充到Map中 + for (int i = 0; i < valueLength; i++) { + // 获取当前字段值 + Object value = objects[i]; + // 初始化key变量 + String key = null; + // 如果names为"*",则使用索引作为key + if (names.trim().equals("*")) { + key = String.valueOf(i); + } else { + // 否则,从名称数组中获取key + try { + key = nameArray[i].trim(); + // 如果key中包含" AS ",则提取" AS "之后的部分作为新的key + if (key.indexOf(" AS ") >= 0) { + key = key.substring(key.trim().indexOf(" AS ") + 3); + } + // 将key中的点号"."替换为下划线"_" + key = key.replace(".", "_").trim(); + } catch (Exception e) { + // 如果在处理key时发生异常,记录错误日志 + log.error("参数填充错误!(key和value数量可能不匹配)"); + } + } + // 将key和value放入mapresult中 + mapresult.put(key, value); + } + } catch (Exception e) { + // 如果在填充Map时发生异常,记录错误日志 + log.error("参数填充错误!(key和value数量可能不匹配)"); + } + // 将当前Map添加到列表中 + list.add(mapresult); + } + // 返回包含所有Map的列表 + return list; + } + + /** + * 由字段名序列获得结构数据 + * + * @param names + * 如name,type,ctime + * @return + */ + public static List getTitles(String names) { + // 创建一个ArrayList来存储处理后的标题 + List list = new ArrayList(); + // 检查传入的names是否为null,如果是,则抛出IllegalArgumentException异常 + if (names == null) { + throw new IllegalArgumentException("参数异常!"); + } + // 将中文逗号","替换为英文逗号",",并将所有字符转换为大写 + names = names.replace(",", ",").toUpperCase(); + // 使用逗号分隔names字符串,得到字符串数组 + String[] nameArray = names.split(","); + // 遍历字符串数组 + for (String name : nameArray) { + // 初始化key变量 + String key = ""; + // 去除name两端的空白字符 + key = name.trim(); + // 检查key中是否包含" AS ",如果包含,则提取" AS "之后的部分作为新的key + if (key.indexOf(" AS ") >= 0) { + key = key.substring(key.trim().indexOf(" AS ") + 3); + } + // 将key中的点号"."替换为下划线"_",并去除两端可能出现的空白字符 + key = key.replace(".", "_").trim(); + // 将处理后的key添加到列表中 + list.add(key); + } + // 返回包含所有处理后的标题的列表 + return list; + } + + + /** + * 通过字符串生成一个和List>相对应的key + * + * @param key + * 如a.asdf 或 ass as name + * @return 如A_ASDF或NAME + */ + public static String getMapKey(String key) { + // 去除key字符串两端的空白字符 + key = key.trim(); + // 检查key中是否包含" AS "字符串,如果包含,则提取" AS "之后的部分作为新的key + if (key.indexOf(" AS ") >= 0) { + key = key.substring(key.trim().indexOf(" AS ") + 3); + } + // 将key中的点号"."替换为下划线"_",并去除两端可能出现的空白字符 + key = key.replace(".", "_").trim(); + // 将key转换为大写字母 + return key.toUpperCase(); + } + + + /** + * 遍历打印Map集合(list) + * + * @param listmap + */ + public static void printMaps(List> listmap) { + // 获取listmap的迭代器,用于遍历所有的Map对象 + for (Iterator> iterator = listmap.iterator(); iterator.hasNext();) { + // 获取下一个Map对象 + Map name = (Map) iterator.next(); + // 获取Map对象的键集合 + Set keyset = name.keySet(); + // 获取键集合的迭代器,用于遍历所有的键 + for (Iterator iterator2 = keyset.iterator(); iterator2.hasNext();) { + // 获取下一个键 + String name2 = (String) iterator2.next(); + // 打印键和对应的值 + System.out.println(name2 + ":" + name.get(name2)); + } + // 打印分隔线,用于区分不同的Map对象 + System.out.println("------------------------------------------"); + } + } + diff --git a/src/farm-core/src/main/java/com/farm/core/sql/result/ResultsHandle.java b/src/farm-core/src/main/java/com/farm/core/sql/result/ResultsHandle.java new file mode 100644 index 0000000..3581942 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/result/ResultsHandle.java @@ -0,0 +1,18 @@ +package com.farm.core.sql.result; + +import java.util.Map; + +/** + * 结果集合的迭代接口 + * + * @author Administrator + * + */ +public interface ResultsHandle { + /** + * 结果集合中的行 + * + * @param row + */ + public void handle(Map row); +} diff --git a/src/farm-core/src/main/java/com/farm/core/sql/utils/HibernateSQLTools.java b/src/farm-core/src/main/java/com/farm/core/sql/utils/HibernateSQLTools.java new file mode 100644 index 0000000..37c78ec --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/sql/utils/HibernateSQLTools.java @@ -0,0 +1,145 @@ +package com.farm.core.sql.utils; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.hibernate.Query; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.persister.entity.AbstractEntityPersister; + +import com.farm.core.sql.query.DBRule; + +public abstract class HibernateSQLTools { + + private AbstractEntityPersister classMetadata; + + protected abstract Class getTypeClass(); + + protected abstract SessionFactory getSessionFactory(); + + /** + * 在更新时创建对象键值对 + * + * @param keyValses + * @return Address = 'Zhongshan 23', City = 'Nanjing' + */ + public static String getValusSqlStr(Map keyValses) { + boolean isFirst = true; + StringBuffer returnStr = new StringBuffer(); + for (Entry node : keyValses.entrySet()) { + if (isFirst) { + isFirst = false; + } else { + returnStr.append(","); + } + returnStr.append(node.getKey()); + returnStr.append(" = "); + returnStr.append("'"); + returnStr.append(node.getValue()); + returnStr.append("'"); + } + return returnStr.toString(); + } + + /** + * 创建批量删除sql + * + * @param session + * @param rules 条件序列 + */ + public void deleteSqlFromFunction(Session session, List rules) { + classMetadata = (AbstractEntityPersister) getSessionFactory().getClassMetadata(getTypeClass()); + String whereStr; + if (rules == null || rules.size() <= 0) { + whereStr = ""; + } else { + whereStr = " WHERE 1=1" + DBRule.makeWhereStr(rules); + } + SQLQuery sqlquery = session.createSQLQuery("DELETE FROM " + classMetadata.getTableName() + whereStr); + sqlquery.executeUpdate(); + } + + /** + * 创建批量查询SQL + * + * @param session + * @param rules 条件序列 + * @return + */ + @SuppressWarnings("unchecked") + public List selectSqlFromFunction(Session session, List rules) { + classMetadata = (AbstractEntityPersister) getSessionFactory().getClassMetadata(getTypeClass()); + String whereStr; + if (rules == null || rules.size() <= 0) { + whereStr = ""; + } else { + whereStr = " WHERE 1=1" + DBRule.makeWhereStr(rules); + } + Query sqlquery = session.createQuery("FROM " + getTypeClass().getName() + whereStr); + List list = sqlquery.list(); + return list; + } + + @SuppressWarnings("unchecked") + public List selectSqlFromFunction(Session session, List rules, int maxnum) { + classMetadata = (AbstractEntityPersister) getSessionFactory().getClassMetadata(getTypeClass()); + String whereStr; + if (rules == null || rules.size() <= 0) { + whereStr = ""; + } else { + whereStr = " WHERE 1=1" + DBRule.makeWhereStr(rules); + } + Query sqlquery = session.createQuery("FROM " + getTypeClass().getName() + whereStr); + sqlquery.setMaxResults(maxnum); + List list = sqlquery.list(); + return list; + } + + /** + * 创建批量更新SQL + * + * @param sessionFatory + * @param values + * @param rules + */ + public void updataSqlFromFunction(Session session, Map values, List rules) { + classMetadata = (AbstractEntityPersister) getSessionFactory().getClassMetadata(getTypeClass().getClass()); + if (values == null || values.size() <= 0) { + return; + } + String whereStr; + if (rules == null || rules.size() <= 0) { + whereStr = ""; + } else { + whereStr = " WHERE 1=1" + DBRule.makeWhereStr(rules); + } + SQLQuery sqlquery = session.createSQLQuery("UPDATE " + classMetadata.getTableName() + " SET " + + HibernateSQLTools.getValusSqlStr(values) + whereStr); + sqlquery.executeUpdate(); + } + + /** + * 创建自定义统计SQL + * + * @param sessionFatory + * @param values + * @param rules + */ + @SuppressWarnings("unchecked") + public int countSqlFromFunction(Session session, List rules) { + classMetadata = (AbstractEntityPersister) getSessionFactory().getClassMetadata(getTypeClass()); + String whereStr; + if (rules == null || rules.size() <= 0) { + whereStr = ""; + } else { + whereStr = " WHERE 1=1" + DBRule.makeWhereStr(rules); + } + SQLQuery sqlquery = session + .createSQLQuery("select count(*) num FROM " + classMetadata.getTableName() + whereStr); + List list = sqlquery.list(); + return Integer.valueOf(list.get(0).toString()); + } +} diff --git a/src/farm-core/src/main/java/com/farm/core/time/TimeTool.java b/src/farm-core/src/main/java/com/farm/core/time/TimeTool.java new file mode 100644 index 0000000..3ccfbce --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/core/time/TimeTool.java @@ -0,0 +1,507 @@ +package com.farm.core.time; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +public class TimeTool { + /** + * 获得12位的日期编码 + * + * @return + */ + public static String getTimeDate12() { + // yyyyMMddhhmm + SimpleDateFormat _sdf = new SimpleDateFormat("yyyyMMddHHmm"); + Date _date = new Date(); + + return _sdf.format(_date); + } + + /** + * 获得某月天数 + * + * @param year + * 4位年 + * @param month + * 2位月 + * @return 有几天 + */ + public static int getMonthMaxDay(String year, String month) { + Calendar cal = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM"); + if (month.trim().length() == 1) { + month = "0" + month; + } + try { + cal.setTime(sdf.parse(year + month)); + } catch (ParseException e) { + throw new RuntimeException(); + } + return cal.getActualMaximum(Calendar.DATE); + } + + /** + * 获得之前num年的年份列表 + * + * @param num + * 年份数量 + * @return + */ + public static List getFirstYearList(int num) { + String currentYear = getTimeDate12().substring(0, 4); + List list = new ArrayList(); + Integer curentYearint = Integer.valueOf(currentYear); + for (int i = 0; i < num; i++) { + String[] yearNode = new String[2]; + yearNode[0] = curentYearint.toString(); + yearNode[1] = curentYearint.toString() + "年"; + list.add(yearNode); + curentYearint--; + } + return list; + } + + /** + * 获得季度列表 + * + * @return + */ + public static List getQuarterList() { + List list = new ArrayList(); + String[] node = new String[2]; + node[0] = "1"; + node[1] = "一季度"; + list.add(node); + + String[] node2 = new String[2]; + node2[0] = "2"; + node2[1] = "二季度"; + list.add(node2); + + String[] node3 = new String[2]; + node3[0] = "3"; + node3[1] = "三季度"; + list.add(node3); + + String[] node4 = new String[2]; + node4[0] = "4"; + node4[1] = "四季度"; + list.add(node4); + return list; + } + + /** + * 获得月份列表 + * + * @return + */ + public static List getMonthList() { + List list = new ArrayList(); + String[] node = new String[2]; + node[0] = "1"; + node[1] = "一月"; + list.add(node); + + String[] node2 = new String[2]; + node2[0] = "2"; + node2[1] = "二月"; + list.add(node2); + + String[] node3 = new String[2]; + node3[0] = "3"; + node3[1] = "三月"; + list.add(node3); + + String[] node4 = new String[2]; + node4[0] = "4"; + node4[1] = "四月"; + list.add(node4); + + String[] node5 = new String[2]; + node5[0] = "5"; + node5[1] = "五月"; + list.add(node5); + + String[] node6 = new String[2]; + node6[0] = "6"; + node6[1] = "六月"; + list.add(node6); + + String[] node7 = new String[2]; + node7[0] = "7"; + node7[1] = "七月"; + list.add(node7); + + String[] node8 = new String[2]; + node8[0] = "8"; + node8[1] = "八月"; + list.add(node8); + + String[] node9 = new String[2]; + node9[0] = "9"; + node9[1] = "九月"; + list.add(node9); + + String[] node10 = new String[2]; + node10[0] = "10"; + node10[1] = "十月"; + list.add(node10); + + String[] node11 = new String[2]; + node11[0] = "11"; + node11[1] = "十一月"; + list.add(node11); + + String[] node12 = new String[2]; + node12[0] = "12"; + node12[1] = "十二月"; + list.add(node12); + return list; + } + + /** + * 由12位的日期编码 获得多少天后的日期编码 + * + * @param addday + * 多少天后(+ 之后-之前) + * @param currentTime12 + * 计算的基准时间 12位日期编码 + * @return + */ + public static Date getTimeDate12ForDay(int addday, Date date) { + Date _date = null; + _date = date; + return getDateAfter(_date, addday); + } + + /** + * 获得多少分钟前的时间 + * + * @param frontMinute + * 多少分钟(+ 之后-之前) + * @return + */ + public static Date getTimeDate12ForMinute(int frontMinute, Date date) { + Date _date = null; + Calendar cal = Calendar.getInstance();// 使用默认时区和语言环境获得一个日历。 + cal.setTime(date); + cal.add(Calendar.MINUTE, frontMinute);// 取当前日期的前一天. + _date = cal.getTime(); + return _date; + } + + /** + * 格式化时间12位的 + * + * @param timeDate12_14 + * 时间 + * @param yyyyMMddHHmmss + * 格式化字符串 + * @return + */ + public static String getFormatTimeDate12(String timeDate12_14, + String yyyyMMddHHmmss) { + try { + if (timeDate12_14.length() > 14) { + timeDate12_14 = timeDate12_14.substring(0, 14); + } + if (12 == timeDate12_14.length()) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm"); + SimpleDateFormat newSdf = new SimpleDateFormat(yyyyMMddHHmmss); + Date date; + + date = sdf.parse(timeDate12_14); + + return newSdf.format(date); + } else { + if (14 == timeDate12_14.length()) { + SimpleDateFormat sdf = new SimpleDateFormat( + "yyyyMMddHHmmss"); + SimpleDateFormat newSdf = new SimpleDateFormat( + yyyyMMddHHmmss); + Date date = sdf.parse(timeDate12_14); + return newSdf.format(date); + } else { + return timeDate12_14; + } + } + } catch (ParseException e) { + return e.toString(); + } + } + + /** + * 获得14位的日期编码 + */ + public static String getTimeDate14() { + /* yyyyMMddhhmmss */ + SimpleDateFormat _sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + Date _date = new Date(); + + return _sdf.format(_date); + } + + /** + * 获得18位的随即数 + */ + public static String getRandom18() { + // TODO Auto-generated method stub + String _random = UUID.randomUUID().toString(); + + return _random.substring(0, 18); + } + + @SuppressWarnings("static-access") + /** + * 获得32位日期加随即尾数的主键 + */ + public static String getOid() { + String _oid = new TimeTool().getTimeDate14() + + new TimeTool().getRandom18(); + return _oid; + } + + /** + * 得到相差几天的时间 + * + * @param date + * 时间 + * @param day + * 几天(+,-) + * @return + */ + private static Date getDateAfter(Date date, int day) { + Calendar now = Calendar.getInstance(); + now.setTime(date); + now.set(Calendar.DATE, now.get(Calendar.DATE) + day); + return now.getTime(); + } + + /** + * 获得当前月 + * + * @return + */ + public static String getCurrentMonth() { + Calendar now = Calendar.getInstance(); + now.setTime(new Date()); + return String.valueOf(now.get(Calendar.MONTH) + 1); + } + + /** + * 获得当前季度 + * + * @return + */ + public static String getCurrentQuarter() { + Calendar now = Calendar.getInstance(); + now.setTime(new Date()); + int month = now.get(Calendar.MONTH) + 1; + switch (month) { + case 1: + return "1"; + case 2: + return "1"; + case 3: + return "1"; + case 4: + return "2"; + case 5: + return "2"; + case 6: + return "2"; + case 7: + return "3"; + case 8: + return "3"; + case 9: + return "3"; + case 10: + return "4"; + case 11: + return "4"; + case 12: + return "4"; + default: + break; + } + return "-1"; + } + + /** + * 根据年月选择日 + * + * @param rankingYear + * 年 + * @param rankingMonth + * 月 + * @return + */ + public static List getDayListByMonth(String rankingYear, + String rankingMonth) { + List list = new ArrayList(); + String[] dayStr = { "01", "02", "03", "04", "05", "06", "07", "08", + "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", + "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", + "29", "30", "31" }; + // 如果是1月、3月、5月、7月、8月、10月、12月,为31天 + if ("1".equals(rankingMonth) || "3".equals(rankingMonth) + || "5".equals(rankingMonth) || "7".equals(rankingMonth) + || "8".equals(rankingMonth) || "10".equals(rankingMonth) + || "12".equals(rankingMonth)) { + for (int i = 0; i < dayStr.length; i++) { + list.add(dayStr[i]); + } + // 如果是4月、6月、9月、11月,为30天 + } else if ("4".equals(rankingMonth) || "6".equals(rankingMonth) + || "9".equals(rankingMonth) || "11".equals(rankingMonth)) { + for (int i = 0; i < dayStr.length - 1; i++) { + list.add(dayStr[i]); + } + } else { + int yearInt = Integer.parseInt(rankingYear); + // 判断是平年还是闰年,平年2月28天,闰年2月29天 + if (yearInt % 4 == 0 && yearInt % 100 != 0 || yearInt % 400 == 0) { + for (int i = 0; i < dayStr.length - 2; i++) { + list.add(dayStr[i]); + } + } else { + for (int i = 0; i < dayStr.length - 3; i++) { + list.add(dayStr[i]); + } + } + } + return list; + } + + /** + * 计算两个Date间的相差分钟 + * + * @param dateBefore + * 早一点的时间 + * @param dateCurrent + * 晚一点的时间 + * @return + */ + public static int countMinuteMinus(Date dateBefore, Date dateCurrent) { + // 当前时间 + Date curentTime = dateCurrent; + // 当前时间 + Calendar curentC = Calendar.getInstance(); + curentC.setTime(curentTime); + // 上次访问时间 + Calendar curentV = Calendar.getInstance(); + curentV.setTime(dateBefore); + // 相差分钟数 + long timeMillis = (curentC.getTimeInMillis() - curentV + .getTimeInMillis()) / (1000 * 60); + int time = (int) timeMillis; + return time; + } + + /** + * 计算两个Date间的相差天数 + * + * @param dateBefore + * 早一点的时间 + * @param dateCurrent + * 晚一点的时间 + * @return + */ + public static int countDayMinus(Date dateBefore, Date dateCurrent) { + // 当前时间 + Date curentTime = dateCurrent; + // 当前时间 + Calendar curentC = Calendar.getInstance(); + curentC.setTime(curentTime); + // 上次访问时间 + Calendar curentV = Calendar.getInstance(); + curentV.setTime(dateBefore); + // 相差分钟数 + long timeMillis = (curentC.getTimeInMillis() - curentV + .getTimeInMillis()) / (1000 * 60 * 60 * 24); + int time = (int) timeMillis; + return time; + } + + /** + * 解析日期 + * + * @param sdate + * @param string + * @return + * @throws ParseException + */ + public static Date parseDate(String dateStr, String yyyyMMdd) + throws ParseException { + SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance(); + df.applyPattern(yyyyMMdd); + Date ddTest = df.parse(dateStr); + return ddTest; + } + + /** + * 获得几天后的日期 + * + * @param date + * @param i + * @return + */ + public static Date nextDay(Date date, int i) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.DAY_OF_MONTH, 1); + Date date1 = new Date(calendar.getTimeInMillis()); + return date1; + } + + /** + * 格式化时间 + * + * @param date + * @param yyyyMMddHHmmss + * @return + */ + public static String format(Date date, String yyyyMMddHHmmss) { + SimpleDateFormat sdf = new SimpleDateFormat(yyyyMMddHHmmss); + return sdf.format(date); + } + + /** + * 获得星期数(周日为0) + * + * @param date + * @return + */ + public static int getWeekNum(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int w = cal.get(Calendar.DAY_OF_WEEK) - 1; + if (w < 0) { + w = 0; + } + return w; + } + + /** + * 获得日 + * + * @param date + * @return + */ + public static int getDayNum(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int w = cal.get(Calendar.DAY_OF_MONTH); + if (w < 0) { + w = 0; + } + return w; + } +} diff --git a/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheGenerater.java b/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheGenerater.java new file mode 100644 index 0000000..6fea9ab --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheGenerater.java @@ -0,0 +1,5 @@ +package com.farm.util.cache; + +public interface FarmCacheGenerater{ + public Object generateData(); +} diff --git a/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheName.java b/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheName.java new file mode 100644 index 0000000..3be41b4 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheName.java @@ -0,0 +1,33 @@ +package com.farm.util.cache; + +/** + * 缓存名称 + * + * @author macpl + * + */ +public enum FarmCacheName { + //AI问答消息缓存 + wcpAiMessages("wcp-ai-messages"), + //AI问答中的用户 + wcpAiUserTalking("wcp-ai-talkuser") + ; + + /** + * 持久缓存 + */ + private String permanentCacheName; + + FarmCacheName(String permanentCacheName) { + this.permanentCacheName = permanentCacheName; + } + + /** + * 如果只有一个缓存就是这个持久缓缓存 + * + * @return + */ + public String getPermanentCacheName() { + return permanentCacheName; + } +} diff --git a/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheNames.java b/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheNames.java new file mode 100644 index 0000000..73a0da6 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/cache/FarmCacheNames.java @@ -0,0 +1,44 @@ +package com.farm.util.cache; + +/** + * 缓存名称(有持久缓存的) + * + * @author macpl + * + */ +public enum FarmCacheNames { + ; + + /** + * 持久缓存 + */ + private String permanentCacheName; + /** + * 动态缓存 + */ + private String liveCacheName; + + FarmCacheNames(String permanentCacheName) { + this.permanentCacheName = permanentCacheName; + this.liveCacheName = permanentCacheName + "-live"; + } + + /** + * 如果只有一个缓存就是这个持久缓缓存 + * + * @return + */ + public String getPermanentCacheName() { + return permanentCacheName; + } + + /** + * 动态缓存,短时间的缓存 + * + * @return + */ + public String getLiveCacheName() { + return liveCacheName; + } + +} diff --git a/src/farm-core/src/main/java/com/farm/util/cache/FarmCaches.java b/src/farm-core/src/main/java/com/farm/util/cache/FarmCaches.java new file mode 100644 index 0000000..f4d6b92 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/cache/FarmCaches.java @@ -0,0 +1,431 @@ +package com.farm.util.cache; + +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Element; + +/** + * 知识库缓存数据 + * + * @author wangdong + * + */ +public class FarmCaches { + private static FarmCaches OBJ; + private CacheManager cacheManager; + static final Logger log = Logger.getLogger(FarmCaches.class); + + synchronized public static FarmCaches getInstance() { + if (OBJ == null) { + OBJ = new FarmCaches(); + OBJ.cacheManager = CacheManager.create(FarmCaches.class.getResource("/config/WcpCacheConfig.xml")); + } +// {// 测试时-屏蔽不需要测试的缓存 +// Set wnames = new HashSet(); +// wnames.add("app-all-types"); +// wnames.add("app-all-typepops"); +// wnames.add("app-all-metadocs"); +// wnames.add("app-all-metaquestions"); +// wnames.add("wcp-all-typenum"); +// for (String name : OBJ.cacheManager.getCacheNames()) { +// if (!wnames.contains(name)) { +// OBJ.clearCache(name); +// } +// } +// } + return OBJ; + } + + /** + * 多参数生成key + * + * @param currentUserId + * @return + */ + public static String getManyParaToKey(String... paras) { + String key = ""; + for (String para : paras) { + if (StringUtils.isBlank(para)) { + para = "NONE"; + } + if (StringUtils.isBlank(key)) { + key = para; + } else { + key = key + "-" + para; + } + } + return key; + } + + /** + * 获得缓存状态信息 + * + * @return + */ + public Map getCacheInfo() { + Map map = new HashMap<>(); + String[] names = cacheManager.getCacheNames(); + if (names != null) { + for (String name : names) { + Cache cache = cacheManager.getCache(name); + if (cache != null) { + map.put(name, cache.getSize()); + } + } + } + return map; + } + + /** + * 清空所有缓存 + */ + public void clearAllCache() { + String[] names = cacheManager.getCacheNames(); + if (names != null) { + for (String name : names) { + clearCache(name); + } + } + } + + private void clearCache(String cacheName) { + Cache cache = cacheManager.getCache(cacheName); + if (cache != null) { + cache.removeAll(); + } + } + + /** + * 清空指定缓存 + * + * @param cacheName + */ + public void clearCache(FarmCacheName farmCacheName) { + clearCache(farmCacheName.getPermanentCacheName()); + } + + /** + * 獲得cache的數量 + * + * @param cacheName + * @return + */ + public int getCacheSize(FarmCacheName farmCacheName) { + Cache cache = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + if (cache == null) { + throw new RuntimeException("the cache " + farmCacheName.getPermanentCacheName() + " is not exist!"); + } + return cache.getSize(); + } + + /** + * 清空缓存 + * + * @param permanentCacheName + * @param liveCacheName + */ + public void clearCache(FarmCacheNames farmCacheName) { + clearCache(farmCacheName.getLiveCacheName()); + clearCache(farmCacheName.getPermanentCacheName()); + } + + /** + * 缓存是否启用(live时间为0时为禁用) + * + * @param farmCacheName + * @return + */ + public boolean isAble(FarmCacheName farmCacheName) { + final Cache live = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + // 如果任意缓存的存活时间时0则缓存不生效 + long l_live_time = live.getCacheConfiguration().getTimeToLiveSeconds(); + if (l_live_time == 0) { + return false; + } else { + return true; + } + } + + /** + * 缓存是否启用(live时间为0时为禁用) + * + * @param farmCacheName + * @return + */ + public boolean isAble(FarmCacheNames farmCacheName) { + final Cache permanent = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + final Cache live = cacheManager.getCache(farmCacheName.getLiveCacheName()); + // 如果任意缓存的存活时间时0则缓存不生效 + long l_live_time = live.getCacheConfiguration().getTimeToLiveSeconds(); + long p_live_time = permanent.getCacheConfiguration().getTimeToLiveSeconds(); + if (l_live_time == 0 || p_live_time == 0) { + return false; + } else { + return true; + } + } + + /** + * 获取缓存数据(异步) + * + * @param key 缓存key + * @param generater 数据生产者 + * @param permanentCacheName 永久缓存名称 + * @param liveCacheName 活动缓存名称 + * @return + */ + public Object getCacheData(final String key, final FarmCacheGenerater generater, + final FarmCacheNames farmCacheName) { + long startTime = new Date().getTime(); + try { + synchronized (key + farmCacheName.getLiveCacheName()) { + final Cache permanent = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + final Cache live = cacheManager.getCache(farmCacheName.getLiveCacheName()); + { + // 如果任意缓存的存活时间时0则缓存不生效 + long l_live_time = live.getCacheConfiguration().getTimeToLiveSeconds(); + long p_live_time = permanent.getCacheConfiguration().getTimeToLiveSeconds(); + log.debug(farmCacheName.getPermanentCacheName() + ":一级过期时间" + l_live_time); + log.debug(farmCacheName.getPermanentCacheName() + ":一级过期时间" + p_live_time); + if (l_live_time == 0 || p_live_time == 0) { + log.debug("--------------------FarmCache--禁用缓存" + farmCacheName.getPermanentCacheName() + + " -------------------"); + return generater.generateData(); + } + } + // 是否是异步加载缓存 + final boolean isAsynchronous = true; + // 先从二级里面取, + Element result = null; + result = live.get(key); + // 取到就返回,取不到就从一级里面取 + if (result != null) { + log.debug("--------------------FarmCache--:返回(" + key + ")生存数据--------" + + farmCacheName.getPermanentCacheName() + "/" + farmCacheName.getLiveCacheName() + + "-------------------"); + return result.getObjectValue(); + } else { + result = permanent.get(key); + } + if (result != null) { + // ,取到就返回 + {// 并且启动一个线程更新二级缓存和一级缓存, + Thread thread = new Thread(new Runnable() { + public void run() { + Object data = generater.generateData(); + Element element = new Element(key, data); + permanent.put(element); + live.put(element); + if (isAsynchronous) { + log.debug("--------------------FarmCache--:异步填充(" + key + ")数据--------" + + farmCacheName.getPermanentCacheName() + "/" + + farmCacheName.getLiveCacheName() + "-------------------"); + } else { + log.debug("--------------------FarmCache--:同步填充(" + key + ")数据--------" + + farmCacheName.getPermanentCacheName() + "/" + + farmCacheName.getLiveCacheName() + "-------------------"); + } + } + }); + if (isAsynchronous) { + thread.start(); + } else { + thread.run(); + } + } + log.debug("--------------------FarmCache--:返回(" + key + ")过期数据--------" + + farmCacheName.getPermanentCacheName() + "/" + farmCacheName.getLiveCacheName() + + "-------------------"); + return result.getObjectValue(); + } else { + // 取不到就直接更新二级缓存和一级缓存后再返回 + Object data = generater.generateData(); + Element element = new Element(key, data); + permanent.put(element); + live.put(element); + log.debug("--------------------FarmCache--:返回(" + key + ")实时数据--------" + + farmCacheName.getPermanentCacheName() + "/" + farmCacheName.getLiveCacheName() + + "-------------------"); + return data; + } + } + } finally { + long endTime = new Date().getTime(); + long executeTime = endTime - startTime; + if(executeTime>100) { + log.warn( + "FarmCaches generater runTime:--<" + executeTime + "ms>--" + "--[" + farmCacheName.name() + "] "); + }else { + log.info( + "FarmCaches generater runTime:--<" + executeTime + "ms>--" + "--[" + farmCacheName.name() + "] "); + } + } + } + + /** + * 获取缓存数据(同步) + * + * @param key 缓存key + * @param generater 数据生产者 + * @param CacheName 活动缓存名称 + * @return + */ + public Object getCacheData(String key, FarmCacheGenerater generater, FarmCacheName farmCacheName) { + long startTime = new Date().getTime(); + try { + synchronized (key + farmCacheName.getPermanentCacheName()) { + final Cache live = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + { + // 如果任意缓存的存活时间时0则缓存不生效 + long l_live_time = live.getCacheConfiguration().getTimeToLiveSeconds(); + if (l_live_time == 0) { + log.debug("--------------------FarmCache--禁用缓存" + farmCacheName.getPermanentCacheName() + + " -------------------"); + return generater.generateData(); + } + } + // 先从二级里面取, + Element result = null; + result = live.get(key); + // 取到就返回,取不到就从一级里面取 + if (result != null) { + log.debug("--------------------FarmCache--:返回(" + key + ")生存数据--------" + + farmCacheName.getPermanentCacheName() + "-------------------"); + return result.getObjectValue(); + } else { + // 取不到就直接更新二级缓存和一级缓存后再返回 + Object data = generater.generateData(); + Element element = new Element(key, data); + live.put(element); + log.debug("--------------------FarmCache--:返回(" + key + ")实时数据--------" + + farmCacheName.getPermanentCacheName() + "-------------------"); + return data; + } + } + } finally { + long endTime = new Date().getTime(); + long executeTime = endTime - startTime; + if(executeTime>100) { + log.warn( + "FarmCaches generater runTime:--<" + executeTime + "ms>--" + "--[" + farmCacheName.name() + "] "); + }else { + log.info( + "FarmCaches generater runTime:--<" + executeTime + "ms>--" + "--[" + farmCacheName.name() + "] "); + } + } + } + + /** + * 记录数据到缓存中 + * + * @param key + * @param val + * @param CacheName + * @return + */ + public void putCacheData(String key, Object val, FarmCacheName farmCacheName) { + final Cache live = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + { + // 如果任意缓存的存活时间时0则缓存不生效 + long l_live_time = live.getCacheConfiguration().getTimeToLiveSeconds(); + if (l_live_time == 0) { + log.info("--------------------FarmCache--禁用缓存" + farmCacheName.getPermanentCacheName() + + " -------------------"); + return; + } + } + Element element = new Element(key, val); + live.put(element); + } + + /** + * 获得缓存数据 + * + * @param key + * @param CacheName + * @return + */ + public Object getCacheData(String key, FarmCacheName farmCacheName) { + final Cache live = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + { + // 如果任意缓存的存活时间时0则缓存不生效 + long l_live_time = live.getCacheConfiguration().getTimeToLiveSeconds(); + if (l_live_time == 0) { + log.info("--------------------FarmCache--禁用缓存" + farmCacheName.getPermanentCacheName() + + " -------------------"); + return null; + } + } + log.debug("--------------------FarmCache--:返回(" + key + ")生存数据--------" + farmCacheName.getPermanentCacheName() + + "-------------------"); + Element returnVal = live.get(key); + if (returnVal == null) { + return null; + } else { + return returnVal.getObjectValue(); + } + } + + /** + * 删除一个缓存数据 + * + * @param key + * @param CacheName + */ + public void removeCacheData(String key, FarmCacheName farmCacheName) { + final Cache live = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + live.remove(key); + } + + + public void removeCacheData(String key, FarmCacheNames farmCacheName) { + final Cache live1 = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + live1.remove(key); + final Cache live2 = cacheManager.getCache(farmCacheName.getLiveCacheName()); + live2.remove(key); + } + + + + /** + * 获得一个缓存的有效时间 + * + * @param sharelevel1cache + * @return + */ + public long getliveTime(FarmCacheName farmCacheName) { + final Cache live = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + long l_live_time = live.getCacheConfiguration().getTimeToLiveSeconds(); + return l_live_time; + } + + /** + * 缓存对象是否存在 + * + * @param docId + * @param doctypecache + * @return + */ + public boolean isHaveVal(String key, FarmCacheName farmCacheName) { + final Cache live = cacheManager.getCache(farmCacheName.getPermanentCacheName()); + { + // 如果任意缓存的存活时间时0则缓存不生效 + long l_live_time = live.getCacheConfiguration().getTimeToLiveSeconds(); + if (l_live_time == 0) { + log.info("--------------------FarmCache--禁用缓存" + farmCacheName.getPermanentCacheName() + + " -------------------"); + return false; + } + } + return live.get(key) != null; + } +} diff --git a/src/farm-core/src/main/java/com/farm/util/spring/BeanFactory.java b/src/farm-core/src/main/java/com/farm/util/spring/BeanFactory.java new file mode 100644 index 0000000..8bdf327 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/spring/BeanFactory.java @@ -0,0 +1,34 @@ +package com.farm.util.spring; + +import javax.servlet.ServletContext; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import com.farm.core.config.AppConfig; + +//读取配置文件进行加载 +public class BeanFactory { + private static ApplicationContext appContext; + + public static Object getBean(String beanId) { + getContext(); + return appContext.getBean(beanId); + } + + public static ApplicationContext getContext() { + if (appContext == null) { + appContext = new ClassPathXmlApplicationContext(AppConfig + .getString("init.config.spring.configs").split(",")); + } + return appContext; + } + + public static Object getBean(String beanId, ServletContext servletContext) { + ApplicationContext ctx = WebApplicationContextUtils + .getWebApplicationContext(servletContext); + return ctx.getBean(beanId); + } + +} diff --git a/src/farm-core/src/main/java/com/farm/util/spring/HibernateSessionFactory.java b/src/farm-core/src/main/java/com/farm/util/spring/HibernateSessionFactory.java new file mode 100644 index 0000000..01edc24 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/spring/HibernateSessionFactory.java @@ -0,0 +1,27 @@ +package com.farm.util.spring; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +/** + * spring hibernateSessionFactory + * + * @author 王东 + * + */ +public class HibernateSessionFactory { + private static final SessionFactory sessionf = (SessionFactory) BeanFactory + .getBean("sessionFactory"); + + public static void closeSession(Session session) { + session.close(); + } + + public static Session getSession() { + return sessionf.openSession(); + } + + public static SessionFactory getFactory() { + return sessionf; + } +} diff --git a/src/farm-core/src/main/java/com/farm/util/validate/ValidUtils.java b/src/farm-core/src/main/java/com/farm/util/validate/ValidUtils.java new file mode 100644 index 0000000..369947a --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/validate/ValidUtils.java @@ -0,0 +1,8 @@ +package com.farm.util.validate; + + +public class ValidUtils { + public static boolean isEmptyString(String str) { + return str == null || str.trim().length() <= 0; + } +} diff --git a/src/farm-core/src/main/java/com/farm/util/web/FarmFormatUnits.java b/src/farm-core/src/main/java/com/farm/util/web/FarmFormatUnits.java new file mode 100644 index 0000000..cd4de91 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/web/FarmFormatUnits.java @@ -0,0 +1,110 @@ +package com.farm.util.web; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 转义工具集合 + * + * @author Administrator + * + */ +public class FarmFormatUnits { + /** + * 为文件设置大小并加上单位 + * + * @param fileLength + * 文件大小(b) + * @return + */ + public static String getFileLengthAndUnit(int fileLength) { + String unit = "b"; + Integer length = fileLength; + if ((Integer) fileLength / 1024 > 0) { + length = (Integer) fileLength / 1024; + unit = "kb"; + } + if ((Integer) fileLength / 1024 / 1024 > 0) { + length = (Integer) fileLength / 1024 / 1024; + unit = "mb"; + } + return length + unit; + } + + /** + * 去掉日期时间的格式(去掉'-'、':'、'空格') + * + * @param timeStr + * @return + */ + public static String getReFormateTime14(String timeStr) { + timeStr = timeStr.replaceAll("-", "").replaceAll(":", "").replaceAll( + " ", "") + + "00000000000000"; + return timeStr.substring(0, 14); + } + + /** + * 格式化时间 + * + * @param timeStr08_14 + * yyyyMMddHHmmss + * @param isshowCurrentDay + * 是否当天显示为“今天” + * @return yyyy-MM-dd HH:mm:ss + */ + public static String getFormateTime(String timeStr08_14, + boolean isshowCurrentDay) { + if (timeStr08_14 == null || timeStr08_14.trim().length() <= 0) { + return null; + } + int tlength = timeStr08_14.length(); + timeStr08_14 = timeStr08_14 + "00000000"; + String yyyy = timeStr08_14.substring(0, 4); + String MM = timeStr08_14.substring(4, 6); + String dd = timeStr08_14.substring(6, 8); + String HH = timeStr08_14.substring(8, 10); + String mm = timeStr08_14.substring(10, 12); + String ss = timeStr08_14.substring(12, 14); + String returnData = null; + if (tlength == 8 && returnData == null) { + returnData = yyyy + "-" + MM + "-" + dd; + } + if (tlength == 10 && returnData == null) { + returnData = yyyy + "-" + MM + "-" + dd + " " + HH; + } + if (tlength == 12 && returnData == null) { + returnData = yyyy + "-" + MM + "-" + dd + " " + HH + ":" + mm; + } + if (returnData == null) { + returnData = yyyy + "-" + MM + "-" + dd + " " + HH + ":" + mm + ":" + + ss; + } + SimpleDateFormat _sdf = new SimpleDateFormat("yyyy-MM-dd"); + String currentday = _sdf.format(new Date()); + return isshowCurrentDay ? returnData.replace(currentday, "今天") + : returnData; + } + + /** + * 时间去格式 + * + * @param timeStr + * 格式化的時間yyyy-MM-dd HH:mm:ss + * @param length + * 最后截取时间的长度 + * @return yyyyMMddHHmmss + */ + public static String reFormateTime(String timeStr, int length) { + if (timeStr == null || timeStr.trim().length() <= 0) { + return null; + } + timeStr = timeStr.replace(":", "").replace("-", "").replace(" ", ""); + if (timeStr.length() > length) { + timeStr = timeStr.substring(0, length); + } + return timeStr; + + } + +} diff --git a/src/farm-core/src/main/java/com/farm/util/web/FarmHtmlUtils.java b/src/farm-core/src/main/java/com/farm/util/web/FarmHtmlUtils.java new file mode 100644 index 0000000..8d05d20 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/web/FarmHtmlUtils.java @@ -0,0 +1,155 @@ +package com.farm.util.web; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; + +public class FarmHtmlUtils { + /** + * 转义html + * + * @param input + * @return + */ + public static String escapeHtml(String input) { + input = input.replaceAll("&", "&"); + input = input.replaceAll("<", "<"); + input = input.replaceAll(">", ">"); + input = input.replaceAll("\"", """); + input = input.replaceAll("'", "'"); + return input; + } + + /** + * 删除Html标签 + * + * @param inputString + * @return + */ + public static String HtmlRemoveTag(String html, String... tagNames) { + if (html == null) { + return null; + } + String htmlStr = html; // 含html标签的字符串 + String textStr = ""; + for (String tagName : tagNames) { + java.util.regex.Pattern p_script; + java.util.regex.Matcher m_script; + java.util.regex.Pattern p_style; + java.util.regex.Matcher m_style; + try { + + // } + String regEx_html1 = "<" + tagName + "\\b[^>]*>"; // 定义HTML标签的正则表达式 + String regEx_html2 = "]*>"; // 定义HTML标签的正则表达式 + + p_script = Pattern.compile(regEx_html1, Pattern.CASE_INSENSITIVE); + m_script = p_script.matcher(htmlStr); + htmlStr = m_script.replaceAll(""); // 过滤script标签 + + p_style = Pattern.compile(regEx_html2, Pattern.CASE_INSENSITIVE); + m_style = p_style.matcher(htmlStr); + htmlStr = m_style.replaceAll(""); // 过滤style标签 + textStr = htmlStr; + + } catch (Exception e) { + // System.err.println("Html2Text: " + e.getMessage()); + } + } + return textStr;// 返回文本字符串 + } + + /** + * 删除Html标签 + * + * @param inputString + * @return + */ + public static String HtmlRemoveTag(String html) { + if (html != null) { + // 段落间没有句号分隔的,自动添加句号,方便向量检索时划分段落 + html = html.replace("", "。"); + html = html.replace("

", "。"); + html = html.replaceAll("([!。!;;]+)\\s*\\。", "$1"); + html = html.replaceAll("\\s{2,}", " "); + html = html.replaceAll("]*?>[\\s\\S]*?<\\/script> + // } + String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或]*?>[\\s\\S]*?<\\/style> + // } + String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式 + + p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE); + m_script = p_script.matcher(htmlStr); + htmlStr = m_script.replaceAll(""); // 过滤script标签 + + p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE); + m_style = p_style.matcher(htmlStr); + htmlStr = m_style.replaceAll(""); // 过滤style标签 + + p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE); + m_html = p_html.matcher(htmlStr); + htmlStr = m_html.replaceAll(""); // 过滤html标签 + + textStr = htmlStr; + + } catch (Exception e) { + // System.err.println("Html2Text: " + e.getMessage()); + } + + return textStr.replaceAll("\\s+", " ");// 返回文本字符串 + } + + /** + * 将style字符串转义为map + * + * @param style 字符串如width:100.0%;height:auto; + * @return + */ + public static Map parseStyleToMap(String style) { + Map css = new HashMap<>(); + for (String node : style.split(";")) { + String[] nodeArray = node.split(":"); + if (nodeArray.length == 2) { + css.put(nodeArray[0].trim().toLowerCase(), nodeArray[1].trim()); + } + } + return css; + } + + /** + * 将style的map连接为style字符串 + * + * @param styles + * @return + */ + public static String joinStyleMap(Map styles) { + String style = null; + for (Entry node : styles.entrySet()) { + if (StringUtils.isNotBlank(node.getKey()) && StringUtils.isNotBlank(node.getValue())) { + if (style == null) { + style = node.getKey() + ":" + node.getValue(); + } else { + style = style + node.getKey() + ":" + node.getValue(); + } + } + } + return style; + } +} diff --git a/src/farm-core/src/main/java/com/farm/util/web/FarmproHotnum.java b/src/farm-core/src/main/java/com/farm/util/web/FarmproHotnum.java new file mode 100644 index 0000000..f37fc76 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/web/FarmproHotnum.java @@ -0,0 +1,48 @@ +package com.farm.util.web; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.log4j.Logger; + +import com.farm.core.time.TimeTool; + +/** + * 计算访问热度 + * + * @author Administrator + * + */ +public class FarmproHotnum { + static final Logger log = Logger.getLogger(FarmproHotnum.class); + + /** + * 计算文章热度 + * + * @param date12最后一次访问时间yyyyMMddHHmm + * @param hotNum + * 上次热度 + * @param visitNum + * 新增访问量(一般为1) + * @param hotWeight + * 冷却系数(一般为19,24小时从100衰减到1,越大衰减的越快) + * @return + */ + public static int getHotnum(String date12, Integer hotNum, + Integer visitNum, int hotWeight) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm"); + int minuteMinus = 0; + try { + minuteMinus = TimeTool.countMinuteMinus(sdf.parse(date12.substring( + 0, 12)), new Date()); + } catch (ParseException e) { + log.error(e + e.getMessage()); + } + // 本期得分 = 上一期得分 × exp(-(冷却系数) × 间隔的小时数) + 本期本期票数 + return Integer.valueOf(String.valueOf(Math.round(hotNum + * Math.exp(-((float) hotWeight / 100) * minuteMinus / 60)))) + + visitNum * 10; + } + +} diff --git a/src/farm-core/src/main/java/com/farm/util/web/WebHotCase.java b/src/farm-core/src/main/java/com/farm/util/web/WebHotCase.java new file mode 100644 index 0000000..097059d --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/web/WebHotCase.java @@ -0,0 +1,99 @@ +package com.farm.util.web; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class hotCase { + public String key; + public int num; + + public hotCase(String key, int num) { + this.key = key; + this.num = num; + } +} + +/** + * 计算热词(如搜索关键字的统计) + * + * @author Administrator + * + */ +public class WebHotCase { + private static List HOT_CASE = new ArrayList(); + private static Map HOT_CASE_MAP = new HashMap(); + private static int maxNum = 1000; + private static int minNum = 500; + private static int index = 0; + + /** + * 录入一个查询用例 + * + * @param caseStr + */ + public static void putCase(String caseStr) { + Integer num = HOT_CASE_MAP.get(caseStr); + if (num == null) { + num = 0; + } + index++; + HOT_CASE_MAP.put(caseStr, num + 1); + if (HOT_CASE_MAP.size() >= maxNum || index == 1 || index == 5 || index == 10 || index % 20 == 0) { + clearHotCase(); + } + } + + /** + * 获得查询case + * + * @param caseStr + */ + public static List getCases(int num) { + List list = new ArrayList(); + for (int n = 0; n < HOT_CASE.size() && n < num; n++) { + list.add(HOT_CASE.get(n).key); + } + return list; + } + + /** + * 清理map + */ + private static void clearHotCase() { + // 清空list + HOT_CASE.clear(); + // map放入list + for (String key : HOT_CASE_MAP.keySet()) { + int num = HOT_CASE_MAP.get(key); + HOT_CASE.add(new hotCase(key, num)); + } + // list排序 + Collections.sort(HOT_CASE, new Comparator() { + public int compare(hotCase o1, hotCase o2) { + return o2.num - o1.num; + }; + }); + // list截串 + if (HOT_CASE.size() >= minNum) { + HOT_CASE = HOT_CASE.subList(0, minNum); + } + if (index >= minNum) { + index = minNum; + } + // 装回map + HOT_CASE_MAP.clear(); + for (hotCase hc : HOT_CASE) { + int cnum = hc.num; + // 每次清理 热度都会衰减一半 + if (cnum > 0) { + cnum = cnum / 2; + } + HOT_CASE_MAP.put(hc.key, cnum); + } + } + +} diff --git a/src/farm-core/src/main/java/com/farm/util/web/WebVisitBuff.java b/src/farm-core/src/main/java/com/farm/util/web/WebVisitBuff.java new file mode 100644 index 0000000..c995b47 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/util/web/WebVisitBuff.java @@ -0,0 +1,53 @@ +package com.farm.util.web; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * 控制用户访问的计数器工具,用来计算一个KEY在一定时间内是否已经被标记(如控制相同用户不重复计算文章的访问量) + * + * @author Administrator + * + */ +public class WebVisitBuff { + private static Map BUFF_S = new HashMap(); + private Set pool = new HashSet(); + private int max = 0; + + /** + * 获得控制计数器工具对象实例 + * + * @param domain + * 域关键字 + * @param maxNum + * 最大存储的Key数量,超过该数量时池被重置 + * @return + */ + public static WebVisitBuff getInstance(String domain, int maxNum) { + if (BUFF_S.get(domain) == null) { + WebVisitBuff ob = new WebVisitBuff(); + BUFF_S.put(domain, ob); + } + BUFF_S.get(domain).max = maxNum; + return BUFF_S.get(domain); + } + + /** + * 是否能够被访问,如果在规定时间内出现相同字符串则不能被访问 + * + * @return + */ + public boolean canVisite(String key) { + if (pool.size() > max) { + pool.clear(); + } + if (pool.contains(key)) { + return false; + } else { + pool.add(key); + return true; + } + } +} diff --git a/src/farm-core/src/main/java/com/farm/web/WebUtils.java b/src/farm-core/src/main/java/com/farm/web/WebUtils.java new file mode 100644 index 0000000..92e57d7 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/WebUtils.java @@ -0,0 +1,244 @@ +package com.farm.web; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.time.TimeTool; +import com.farm.util.spring.BeanFactory; +import com.farm.web.constant.FarmConstant; + +public class WebUtils { + /** + * 通过Spring获得对象 + * + * @param beanIndex + * @return + */ + protected Object BEAN(String beanIndex) { + return BeanFactory.getBean(beanIndex); + } + + @SuppressWarnings("unchecked") + public List getCurrentUserMenus(HttpSession session) { + List menuList = (List) session + .getAttribute(FarmConstant.SESSION_USERMENU); + return menuList; + } + + /** + * 获得当前登录用户对象 + * + * @return + */ + public static LoginUser getCurrentUser(HttpSession session) { + LoginUser user = (LoginUser) session + .getAttribute(FarmConstant.SESSION_USEROBJ); + return user; + } + + public LoginUser getCurrentUserByDebug(HttpSession session) { + LoginUser user = new LoginUser() { + @Override + public String getName() { + return "测试"; + } + + @Override + public String getLoginname() { + return "debug"; + } + + @Override + public String getId() { + return "debug"; + } + }; + return user; + } + + /** + * 使用httpSession设置当前登录用户 + * + * @param user + * @param session + * @return + */ + @SuppressWarnings("unused") + public LoginUser setCurrentUser(LoginUser user, HttpSession session) { + session.setAttribute(FarmConstant.SESSION_USEROBJ, user); + String photoid = null; + if (photoid != null && photoid.trim().length() > 0) { + // if (session == null) { + // getSession().put(AloneConstant.SESSION_USERPHOTO, + // EkpFileFaceImpl.getInstance().getFileUrl(photoid)); + // } else { + // session.setAttribute(AloneConstant.SESSION_USERPHOTO, + // EkpFileFaceImpl.getInstance().getFileUrl(photoid)); + // } + } + return user; + } + + /** + * 清除当前登录用户 + * + * @param user + * @return + */ + public void clearCurrentUser(HttpSession session) { + session.setAttribute(FarmConstant.SESSION_USEROBJ, null); + } + + /** + * 使用httpSession设置当前登录用户权限 + * + * @param user + * @return + */ + public void setCurrentUserAction(Set userAction, HttpSession session) { + session.setAttribute(FarmConstant.SESSION_USERACTION, userAction); + } + + /** + * 使用httpSession设置当前登录时间 + * + * @param user + * @return + */ + public void setLoginTime(HttpSession session) { + session.setAttribute(FarmConstant.SESSION_LOGINTIME, + TimeTool.getTimeDate14()); + } + + /** + * 获得当前登录时间 + */ + public String getLoginTime(HttpSession session) { + return (String) session.getAttribute(FarmConstant.SESSION_LOGINTIME); + } + + /** + * 使用httpSession设置当前登录用户菜单 + * + * @param user + * @return + */ + public void setCurrentUserMenu(List userMenu, HttpSession session) { + session.setAttribute(FarmConstant.SESSION_USERMENU, userMenu); + } + + /** + * 如果httpsession有就返回httpsession没有就返回strutsSession + * + * @param httpSession + * @return + */ + public HttpSession getSession(HttpSession httpSession) { + return httpSession; + } + + /** + * 获得用户ip地址 + * + * @return + */ + public static String getCurrentIp(HttpServletRequest httpRequest) { + return httpRequest.getRemoteAddr(); + } + + /** + * 设置一个保存30天的cookie + * + * @param cookieName + * @param value + */ + public void setCookie(String cookieName, String value, + HttpServletResponse httpResponse) { + Cookie cookie = new Cookie(cookieName, value); + int expireday = 60 * 60 * 24 * 30; // 不设置的话,则cookies不写入硬盘,而是写在内存,只在当前页面有用,以秒为单位 + cookie.setMaxAge(expireday); + httpResponse.addCookie(cookie); + } + + /** + * 删除一个cookie + * + * @param cookieName + * @param value + */ + public void delCookie(String cookieName, HttpServletRequest httpRequest, + HttpServletResponse httpResponse) { + if (cookieName == null || cookieName.equals("")) { + return; + } + Cookie[] cookies = httpRequest.getCookies(); + int length = 0; + + if (cookies != null && cookies.length > 0) { + length = cookies.length; + for (int i = 0; i < length; i++) { + String cname = cookies[i].getName(); + if (cname != null && cname.equals(cookieName)) { + String cValue = cookies[i].getValue(); + setCookie(cname, cValue, httpResponse); + } else { + continue; + } + } + } + } + + public String getCookieValue(String cookieName, + HttpServletRequest httpRequest) { + if (cookieName == null || cookieName.equals("")) { + return null; + } + Cookie[] cookies = httpRequest.getCookies(); + int length = 0; + + if (cookies != null && cookies.length > 0) { + length = cookies.length; + for (int i = 0; i < length; i++) { + String cname = cookies[i].getName(); + if (cname != null && cname.equals(cookieName)) { + String cValue = cookies[i].getValue(); + return cValue; + } else { + continue; + } + } + return null; + } else { + return null; + } + } + + /** + * 将id序列字符串转化为id的list序列 + * + * @param ids + * @return + */ + public List parseIds(String ids) { + if (ids == null) { + return new ArrayList(); + } + ids = ids.replace(",", ","); + String[] markdot = ids.split(","); + List list_ = new ArrayList(); + for (int i = 0; i < markdot.length; i++) { + String temp = markdot[i]; + if (temp != null && !temp.equals("") && !temp.equals(" ")) + list_.add(temp); + } + return list_; + } +} diff --git a/src/farm-core/src/main/java/com/farm/web/action/FarmAction.java b/src/farm-core/src/main/java/com/farm/web/action/FarmAction.java new file mode 100644 index 0000000..739a87f --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/action/FarmAction.java @@ -0,0 +1,193 @@ +package com.farm.web.action; + +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.apache.log4j.MDC; + +import com.farm.core.AuthorityService; +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.page.ViewMode; +import com.farm.web.online.OnlineUserOpImpl; +import com.farm.web.online.OnlineUserOpInter; + +/** + * 权限资源 + * + * @author MAC_alone + * + */ +public class FarmAction { + private String name; + private String password; + private String autoLogin; + private HttpSession httpSession; + private HttpServletRequest httprequest; + private HttpServletResponse httprespons; + private ViewMode page; + private List> result; + private List menus; + private String menuId; + private static final Logger log = Logger.getLogger(FarmAction.class); + +// /** +// * 用户登录 +// * +// * @return +// */ +// public void loginCommit(HttpSession session, +// HttpServletResponse httpResponse, HttpServletRequest httpRequest) { +// AuthorityService authAdapter = farmService.getAuthorityService(); +// page = ViewMode.getInstance(); +// try { +// if (!authAdapter.isLegality(name, password)) { +// page.setError("登录失败:密码错误"); +// log.error("登录失败:密码错误"); +// return; +// } else { +// } +// } catch (Exception e) { +// page.setError(e.getMessage() + "用户验证失败"); +// log.error("登录失败:用户验证失败"); +// return; +// } +// try { +// {// 登录成功 +// // 开始写入session用户信息 +// if (httpSession == null) { +// WebUtils.setCurrentUser(authAdapter.getUserByLoginName(name)); +// WebUtils.setLoginTime(session); +// } else { +// WebUtils.setCurrentUser(authAdapter.getUserByLoginName(name), +// httpSession); +// WebUtils.setLoginTime(httpSession); +// } +// +// // 开始写入session用户权限 +// if (httpSession == null) { +// WebUtils.setCurrentUserAction(authAdapter +// .getUserAuthKeys(WebUtils.getCurrentUser(session).getId())); +// } else { +// WebUtils.setCurrentUserAction( +// authAdapter.getUserAuthKeys(WebUtils.getCurrentUser( +// httpSession).getId()), httpSession); +// } +// // 开始写入session用户菜单 +// if (httpSession == null) { +// WebUtils.setCurrentUserMenu(authAdapter.getUserMenu(WebUtils.getCurrentUser( +// session).getId())); +// } else { +// WebUtils.setCurrentUserMenu(authAdapter.getUserMenu(WebUtils.getCurrentUser( +// httpSession).getId()), httpSession); +// } +// // 写入用户上线信息 +// OnlineUserOpInter ouop = null; +// if (httpSession == null) { +// ouop = OnlineUserOpImpl.getInstance( +// WebUtils.getCurrentIp(httpRequest), name, session); +// } else { +// ouop = OnlineUserOpImpl.getInstance( +// httprequest.getRemoteAddr(), name, +// WebUtils.getSession(httpSession)); +// } +// ouop.userLoginHandle(authAdapter.getUserByLoginName(name)); +// // 记录用户登录时间 +// authAdapter.loginHandle(WebUtils.getCurrentUser(httpSession).getId()); +// } +// MDC.put("USERID", WebUtils.getCurrentUser(httpSession).getId()); +// log.info("登录成功"); +// } catch (Exception e) { +// page.setError(e + e.getMessage()); +// log.error("登录失败:" + e.getMessage()); +// return; +// } +// } + +// /** +// * 获得menu +// * +// * @return +// */ +// public List findMenu(HttpSession session) { +// return WebUtils.getCurrentUserMenus(session); +// } + + // ---------------------------------------------------------------------------------- + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List> getResult() { + return result; + } + + public void setResult(List> result) { + this.result = result; + } + + public String getMenuId() { + return menuId; + } + + public void setMenuId(String menuId) { + this.menuId = menuId; + } + + public HttpSession getHttpSession() { + return httpSession; + } + + public void setHttpSession(HttpSession httpSession) { + this.httpSession = httpSession; + } + + public String getAutoLogin() { + return autoLogin; + } + + public HttpServletRequest getHttprequest() { + return httprequest; + } + + public void setHttprequest(HttpServletRequest httprequest) { + this.httprequest = httprequest; + } + + public HttpServletResponse getHttprespons() { + return httprespons; + } + + public void setHttprespons(HttpServletResponse httprespons) { + this.httprespons = httprespons; + } + + public void setAutoLogin(String autoLogin) { + this.autoLogin = autoLogin; + } + + public List getMenus() { + return menus; + } + + public void setMenus(List menus) { + this.menus = menus; + } +} diff --git a/src/farm-core/src/main/java/com/farm/web/constant/FarmConstant.java b/src/farm-core/src/main/java/com/farm/web/constant/FarmConstant.java new file mode 100644 index 0000000..11a6098 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/constant/FarmConstant.java @@ -0,0 +1,53 @@ +package com.farm.web.constant; + + +public class FarmConstant { + /** + * 菜单树索引编码长度,用来计算上层节点时使用 + */ + public static final int MENU_TREECODE_UNIT_LENGTH=32; + /** + * SESSION当前登录用户 + */ + public static final String SESSION_USEROBJ = "USEROBJ"; + /** + * SESSION当前登录用户头像 + */ + public static final String SESSION_USERPHOTO = "USERPHOTO"; + /** + * SESSION被权限系统拦截的URL + */ + public static final String SESSION_GO_URL = "WANTURL"; + + /** + * SESSION登录前来自的页面URL + */ + public static final String SESSION_FROM_URL = "FROMURL"; + /** + * SESSION当前登录时间 + */ + public static final String SESSION_LOGINTIME = "LOGINTIME"; + /** + * SESSION当前登录组织机构 + */ + public static final String SESSION_ORG = "USERORG"; + /** + * SESSION当前登录角色 + */ + public static final String SESSION_ROLES = "LOGINROLES"; + /** + * SESSION当前用户权限 + */ + public static final String SESSION_USERACTION = "USERACTION"; + /** + * SESSION当前用户菜单List> + * TREECODE,TYPE,URL,ID,IMG,SORT,PARENTID,NAME + */ + public static final String SESSION_USERMENU = "USERMENU"; + + + /** + * licence + */ + public static String LICENCE; +} diff --git a/src/farm-core/src/main/java/com/farm/web/easyui/EasyUiTreeNode.java b/src/farm-core/src/main/java/com/farm/web/easyui/EasyUiTreeNode.java new file mode 100644 index 0000000..9e2d75a --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/easyui/EasyUiTreeNode.java @@ -0,0 +1,796 @@ +package com.farm.web.easyui; + +import java.io.Serializable; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.query.DataQuerys; +import com.farm.core.sql.result.DataResult; + +/** + * 用来封装easyUI tree节点的数据实体 + * + * @author 王东 + * @date 2013-4-18 [{ "id": 1, "text": "Node 1", "state": "closed", "children": + * @note [{ "id": 11, "text": "Node 11" },{ "id": 12, "text": "Node 12" }] },{ + * "id": 2, "text": "Node 2", "state": "closed" }] + */ +public class EasyUiTreeNode implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + static final Logger log = Logger.getLogger(EasyUiTreeNode.class); + private String id; + private String text; + private String state = "open"; + private String iconCls; + private String url; + private String para; + private boolean checked; + private List children = new ArrayList(); + + public EasyUiTreeNode(String id, String text) { + this.id = id; + this.text = text; + } + + public EasyUiTreeNode(String id, String text, String state) { + this.id = id; + this.text = text; + if (state != null) { + this.state = state; + } + } + + public EasyUiTreeNode(String id, String text, String state, String iconCls) { + this.id = id; + this.text = text; + if (state != null) { + this.state = state; + } + if (iconCls != null && iconCls.trim().length() > 0) { + this.iconCls = iconCls; + } + } + + public EasyUiTreeNode(String id, String text, String state, String iconCls, + String url, String params) { + this.id = id; + this.text = text; + if (state != null) { + this.state = state; + } + if (url != null) { + this.url = url; + } + if (params != null) { + this.para = params; + } + if (iconCls != null && iconCls.trim().length() > 0) { + this.iconCls = iconCls; + } + } + + public EasyUiTreeNode(String id, String text, String state, boolean checked) { + this.id = id; + this.text = text; + if (state != null) { + this.state = state; + } + this.checked = checked; + } + + /** + * 为节点集合添加一个节点(为根节点设置关闭状态)用于异步树 + * + * @param nodeList + * 操作序列 + * @param parentId + * 父亲节点id + * @param id + * 当前节点id + * @param text + * 当前节点名称 + * @param state + * 当前节点状态'open' 或者 'closed' + */ + public static List addNode_initState( + List nodeList, String parentId, String id, + String text, String state, String icon, String url, String params) { + if (nodeList == null) { + nodeList = new ArrayList(); + } + EasyUiTreeNode oNode = findNode(nodeList, parentId); + if (oNode == null) { + nodeList + .add(new EasyUiTreeNode(id, text, state, icon, url, params)); + } else { + oNode.setState("closed"); + } + return nodeList; + } + + /** + * 为节点集合添加一个节点(标准方法) + * + * @param nodeList + * 操作序列 + * @param parentId + * 父亲节点id + * @param id + * 当前节点id + * @param text + * 当前节点名称 + * @param state + * 当前节点状态'open' 或者 'closed' + */ + public static List addNode_Standard( + List nodeList, String parentId, String id, + String text, String state) { + if (nodeList == null) { + nodeList = new ArrayList(); + } + EasyUiTreeNode oNode = findNode(nodeList, parentId); + if (oNode == null) { + nodeList.add(new EasyUiTreeNode(id, text, state)); + } else { + oNode.getChildren().add(new EasyUiTreeNode(id, text, state)); + } + return nodeList; + } + + public static List addNode_Standard( + List nodeList, String parentId, String id, + String text, String state, boolean idcheck) { + if (nodeList == null) { + nodeList = new ArrayList(); + } + EasyUiTreeNode oNode = findNode(nodeList, parentId); + if (oNode == null) { + nodeList.add(new EasyUiTreeNode(id, text, state, idcheck)); + } else { + oNode.getChildren().add( + new EasyUiTreeNode(id, text, state, idcheck)); + oNode.setChecked(false); + } + return nodeList; + } + + public static List addNode_Standard( + List nodeList, String parentId, String id, + String text, String state, boolean idcheck, String icon) { + if (nodeList == null) { + nodeList = new ArrayList(); + } + EasyUiTreeNode oNode = findNode(nodeList, parentId); + if (oNode == null) { + EasyUiTreeNode node = new EasyUiTreeNode(id, text, state, idcheck); + if (icon != null) { + node.setIconCls(icon); + } + nodeList.add(node); + } else { + EasyUiTreeNode node = new EasyUiTreeNode(id, text, state, idcheck); + if (icon != null) { + node.setIconCls(icon); + } + oNode.getChildren().add(node); + oNode.setChecked(false); + } + return nodeList; + } + + /** + * 格式化异步ajax子树数据 + * + * @param result1 + * 依据父id查询出来的节点集合 + * @param result2 + * 依据父id查询出来的节点的子节点集合 + * @param parentIdIndex + * 父id的key + * @param idIndex + * id的key + * @param titleIndex + * 显示字段的key + * @return + */ + public static List formatAsyncAjaxTree( + List> result1, + List> result2, String parentIdIndex, + String idIndex, String titleIndex, String iconIndex) { + result1.addAll(result2); + List treeNodes = new ArrayList(); + try { + for (Map node : result1) { + if (node.get(idIndex) == null) { + continue; + } + treeNodes = EasyUiTreeNode.addNode_initState(treeNodes, node + .get(parentIdIndex).toString(), node.get(idIndex) + .toString(), node.get(titleIndex).toString(), null, + node.get(iconIndex) != null ? node.get(iconIndex) + .toString() : null, null, null); + } + } catch (Exception e) { + log.error(e.getMessage());; + } + return treeNodes; + } + + /** + * 格式化异步ajax子树数据 + * + * @param result1 + * 依据父id查询出来的节点集合 + * @param result2 + * 依据父id查询出来的节点的子节点集合 + * @param parentIdIndex + * 父id的key + * @param idIndex + * id的key + * @param titleIndex + * 显示字段的key + * @param iconIndex + * 图标的key + * @param urlIndex + * url的key + * @param paramsIndex + * url参数的key + * @param currentUserMenus + * 当前用户所拥有的菜单,用来做权限过滤的 + * @return + */ + public static List formatAsyncAjaxTreeForMenuTree( + List> result1, + List> result2, String parentIdIndex, + String idIndex, String titleIndex, String iconIndex, + String urlIndex, String paramsIndex, + List currentUserMenus) { + result1.addAll(result2); + List treeNodes = new ArrayList(); + try { + for (Map node : result1) { + boolean isShowMenu = false; + for (WebMenu menu : currentUserMenus) { + if (menu.getId().equals(node.get(idIndex))) { + isShowMenu = true; + break; + } + } + if (!isShowMenu) { + continue; + } + treeNodes = EasyUiTreeNode.addNode_initState(treeNodes, node + .get(parentIdIndex).toString(), node.get(idIndex) + .toString(), node.get(titleIndex).toString(), null, + node.get(iconIndex) != null ? node.get(iconIndex) + .toString() : null, + node.get(urlIndex) != null ? node.get(urlIndex) + .toString() : null, + node.get(paramsIndex) != null ? node.get(paramsIndex) + .toString() : null); + } + } catch (Exception e) { + log.error(e.getMessage());; + } + return treeNodes; + } + + /** + * 格式化ajax子树数据 + * + * @param result1 + * 依据父id查询出来的节点集合 + * @param result2 + * 依据父id查询出来的节点的子节点集合 + * @param parentIdIndex + * 父id的key + * @param idIndex + * id的key + * @param titleIndex + * 显示字段的key + * @return + */ + public static List formatAjaxTree( + List> result1, String parentIdIndex, + String idIndex, String titleIndex) { + List treeNodes = new ArrayList(); + try { + for (Map node : result1) { + if (node.get(idIndex) == null) { + continue; + } + treeNodes = EasyUiTreeNode.addNode_Standard(treeNodes, node + .get(parentIdIndex).toString(), node.get(idIndex) + .toString(), node.get(titleIndex).toString(), null); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return treeNodes; + } + + /** + * 格式化ajax子树数据 + * + * @param result1 + * 依据父id查询出来的节点集合 + * @param result2 + * 依据父id查询出来的节点的子节点集合 + * @param parentIdIndex + * 父id的key + * @param idIndex + * id的key + * @param titleIndex + * 显示字段的key + * @param checkIndex + * 选中状态的key + * @return + */ + public static List formatAjaxTree( + List> result1, String parentIdIndex, + String idIndex, String titleIndex, String checkIndex, + String iconIndex) { + List treeNodes = new ArrayList(); + try { + for (Map node : result1) { + if (node.get(idIndex) == null) { + continue; + } + boolean ischeck = false; + if (node.get(checkIndex) == null) { + ischeck = false; + } else { + ischeck = true; + } + treeNodes = EasyUiTreeNode.addNode_Standard(treeNodes, node + .get(parentIdIndex).toString(), node.get(idIndex) + .toString(), node.get(titleIndex).toString(), null, + ischeck, node.get(iconIndex) == null ? null : node.get( + iconIndex).toString()); + } + } catch (Exception e) { + log.error(e.getMessage());; + } + return treeNodes; + } + + /** + * 遍历集合获得对象 + * + * @param nodeList + * @return + */ + public static EasyUiTreeNode findNode(List nodeList, + String id) { + for (EasyUiTreeNode node : nodeList) { + if (node.id.equals(id)) { + return node; + } else { + EasyUiTreeNode reNode = findNode(node.children, id); + if (reNode != null) { + return reNode; + } + } + } + return null; + } + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getText() { + return text; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getPara() { + return para; + } + + public void setPara(String para) { + this.para = para; + } + + public boolean isChecked() { + return checked; + } + + public void setChecked(boolean checked) { + this.checked = checked; + } + + public void setText(String text) { + this.text = text; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public String getIconCls() { + return iconCls; + } + + public void setIconCls(String iconCls) { + this.iconCls = iconCls; + } + + /** + * 加载第一层树节点 父节点的根目录的父id必须为"NONE",包含字段名ID,PARENTID,NAME + * + * @param parentId + * 父亲节点id + * @param SortTitle + * 排序字段index + * @param tableTitle + * 表名index + * @param id_title + * 表id的index + * @param parentId_title + * 表parentid的index + * @param name_title + * 表name的index + * @return DataResult + */ + public static DataResult queryTreeNodeTow(String parentId, + String SortTitle, String tableTitle, String id_title, + String parentId_title, String name_title, String icon_title) { + return queryTreeNodeTow(parentId, SortTitle, tableTitle, id_title, + parentId_title, name_title, icon_title, null); + } + + /** + * 加载第一层树节点 父节点的根目录的父id必须为"NONE",包含字段名ID,PARENTID,NAME + * + * @param parentId + * 父亲节点id + * @param SortTitle + * 排序字段index + * @param tableTitle + * 表名index + * @param id_title + * 表id的index + * @param parentId_title + * 表parentid的index + * @param name_title + * 表name的index + * @param userWhere + * @return + */ + public static DataResult queryTreeNodeTow(String parentId, + String SortTitle, String tableTitle, String id_title, + String parentId_title, String name_title, String icon_title, + String userWhere) { + if (parentId == null || parentId.trim().length() <= 0) { + parentId = "NONE"; + } + DataResult nodeResult = null; + DBSort sort = new DBSort("b." + SortTitle, "ASC"); + DataQuery query = DataQuery.getInstance("1", "b." + id_title + " as " + + id_title + ",b." + parentId_title + " as " + parentId_title + + ",b." + name_title + " as " + name_title + ",b." + icon_title + + " as " + icon_title, tableTitle + " a left join " + + tableTitle + " b on b." + parentId_title + "=a." + id_title); + query.setPagesize(100); + query.addSort(sort); + DataQuerys.wipeVirus(parentId); + if (userWhere != null) { + query.setSqlRule("and a." + parentId_title + "='" + parentId + "' " + + userWhere); + } else { + query + .setSqlRule("and a." + parentId_title + "='" + parentId + + "' "); + } + try { + nodeResult = query.search(); + } catch (SQLException e) { + log.error(e.getMessage());; + } + return nodeResult; + } + + /** + * 加载第一层树节点 父节点的根目录的父id必须为"NONE",包含字段名ID,PARENTID,NAME + * + * @param parentId + * 父亲节点id + * @param SortTitle + * 排序字段index + * @param tableTitle + * 表名index + * @param id_title + * 表id的index + * @param parentId_title + * 表parentid的index + * @param name_title + * 表name的index + * @param icon_title + * 表图标 + * @return DataResult + */ + public static DataResult queryTreeNodeOne(String parentId, + String SortTitle, String tableTitle, String id_title, + String parentId_title, String name_title, String icon_title) { + return queryTreeNodeOne(parentId, SortTitle, tableTitle, id_title, + parentId_title, name_title, icon_title, null, null); + } + + /** + * 加载第一层树节点 父节点的根目录的父id必须为"NONE",包含字段名ID,PARENTID,NAME + * + * @param parentId + * 父亲节点id + * @param SortTitle + * 排序字段index + * @param tableTitle + * 表名index + * @param id_title + * 表id的index + * @param parentId_title + * 表parentid的index + * @param name_title + * 表name的index + * @param icon_title + * 表图标 + * @param userWhere + * 表查询条件 + * @return DataResult + */ + public static DataResult queryTreeNodeOne(String parentId, + String SortTitle, String tableTitle, String id_title, + String parentId_title, String name_title, String icon_title, + String userWhere) { + return queryTreeNodeOne(parentId, SortTitle, tableTitle, id_title, + parentId_title, name_title, icon_title, userWhere, null); + } + + /** + * 加载第一层树节点 父节点的根目录的父id必须为"NONE",包含字段名ID,PARENTID,NAME + * + * @param parentId + * 父亲节点id + * @param SortTitle + * 排序字段index + * @param tableTitle + * 表名index + * @param id_title + * 表id的index + * @param parentId_title + * 表parentid的index + * @param name_title + * 表name的index + * @param userWhere + * @return + */ + public static DataResult queryTreeNodeOne(String parentId, + String SortTitle, String tableTitle, String id_title, + String parentId_title, String name_title, String icon_title, + String userWhere, String otherTitles) { + if (parentId == null || parentId.trim().length() <= 0) { + parentId = "NONE"; + } + DataResult nodeResult = null; + DBSort sort = new DBSort("a." + SortTitle, "ASC"); + DataQuery query = DataQuery.getInstance("1", (otherTitles == null ? "" + : (otherTitles + ",")) + + id_title + + "," + + parentId_title + + " as " + + parentId_title + + "," + + name_title + + " as " + + name_title + + ",a." + + icon_title + + " as " + icon_title, tableTitle + " a"); + query.setPagesize(100); + query.addSort(sort); + DataQuerys.wipeVirus(parentId); + if (userWhere != null) { + query.setSqlRule("and " + parentId_title + "='" + parentId + "' " + + userWhere); + } else { + query.setSqlRule("and " + parentId_title + "='" + parentId + "'"); + } + try { + nodeResult = query.search(); + } catch (SQLException e) { + log.error(e.getMessage());; + } + return nodeResult; + } + + /** + * 格式化easyUi树节点集合 + * + * @param resultList + * 结果集合List> + * @param resultList + * @param parentIndex + * @param idIndex + * @param titleIndex + * @param iconIndex + * @return + */ + public static List formatTreeNodes( + List> resultList, String parentIndex, + String idIndex, String titleIndex, String iconIndex) { + List treeNodes = new ArrayList(); + try { + for (Map node : resultList) { + if (node.get(idIndex) == null) { + continue; + } + treeNodes = EasyUiTreeNode.addNode_initState(treeNodes, node + .get(parentIndex).toString(), node.get(idIndex) + .toString(), node.get(titleIndex).toString(), null, + node.get(iconIndex) != null ? node.get(iconIndex) + .toString() : null, null, null); + } + } catch (Exception e) { + log.error(e.getMessage());; + } + return treeNodes; + } + + /** + * 加载第一层树节点 父节点的根目录的父id必须为"NONE",包含字段名ID,PARENTID,NAME + * + * @param parentId + * 父亲节点id + * @param SortTitle + * 排序字段index + * @param tableTitle + * 表名index + * @param id_title + * 表id的index + * @param parentId_title + * 表parentid的index + * @param name_title + * 表name的index + * @param userWhere + * @return + */ + public static DataQuery queryTreeNodeOneAuth(String parentId, + String SortTitle, String tableTitle, String id_title, + String parentId_title, String name_title, String icon_title, + String userWhere, String otherTitles,boolean authFlag) { + if (parentId == null || parentId.trim().length() <= 0) { + parentId = "NONE"; + } + @SuppressWarnings("unused") + DataResult nodeResult = null; + DBSort sort = new DBSort("a." + SortTitle, "ASC"); + DataQuery query = DataQuery.getInstance("1", (otherTitles == null ? "" + : (otherTitles + ",")) + + id_title + + "," + + parentId_title + + " as " + + parentId_title + + "," + + name_title + + " as " + + name_title + + ",a." + + icon_title + + " as " + icon_title, tableTitle + " a"); + query.setPagesize(100); + query.addSort(sort); + DataQuerys.wipeVirus(parentId); + if(authFlag) + { + query.setSqlRule("and a." + parentId_title + " is not null"); + query.setSqlRule("and " + parentId_title + "='" + parentId + "'"); + } + else + { + if (userWhere != null) { + query.setSqlRule("and " + parentId_title + "='" + parentId + "' " + + userWhere); + } else { + query.setSqlRule("and " + parentId_title + "='" + parentId + "'"); + } + } + + return query; + } + + + + + /** + * 加载第一层树节点 父节点的根目录的父id必须为"NONE",包含字段名ID,PARENTID,NAME + * + * @param parentId + * 父亲节点id + * @param SortTitle + * 排序字段index + * @param tableTitle + * 表名index + * @param id_title + * 表id的index + * @param parentId_title + * 表parentid的index + * @param name_title + * 表name的index + * @param userWhere + * @return + */ + public static DataQuery queryTreeNodeTowAuth(String parentId, + String SortTitle, String tableTitle, String id_title, + String parentId_title, String name_title, String icon_title, + String userWhere,boolean authFlag) { + if (parentId == null || parentId.trim().length() <= 0) { + parentId = "NONE"; + } + @SuppressWarnings("unused") + DataResult nodeResult = null; + DBSort sort = new DBSort("b." + SortTitle, "ASC"); + DataQuery query = DataQuery.getInstance("1", "b." + id_title + " as " + + id_title + ",b." + parentId_title + " as " + parentId_title + + ",b." + name_title + " as " + name_title + ",b." + icon_title + + " as " + icon_title, tableTitle + " a left join " + + tableTitle + " b on b." + parentId_title + "=a." + id_title); + query.setPagesize(100); + query.addSort(sort); + DataQuerys.wipeVirus(parentId); + if(authFlag) + { + query.setSqlRule("and a." + parentId_title + " is not null"); + query.setSqlRule("and a." + parentId_title + "='" + parentId + + "' "); + } + else + { + if (userWhere != null) { + query.setSqlRule("and a." + parentId_title + "='" + parentId + "' " + + userWhere); + } else { + query.setSqlRule("and a." + parentId_title + "='" + parentId + + "' "); + } + } + + return query; + } + +} diff --git a/src/farm-core/src/main/java/com/farm/web/easyui/EasyUiUtils.java b/src/farm-core/src/main/java/com/farm/web/easyui/EasyUiUtils.java new file mode 100644 index 0000000..b2e69f3 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/easyui/EasyUiUtils.java @@ -0,0 +1,227 @@ +package com.farm.web.easyui; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; + +/** + * UI扩展工具类 + * + * @author 王东 + * @date 2013-4-28 + */ +public class EasyUiUtils { + /** + * 1 字符串 + */ + private static String EDITOR_TYPE_TEXT = "text"; + /** + * 2 数字 + */ + private static String EDITOR_TYPE_SELECT = "numberbox"; + /** + * 3 枚举 + */ + @SuppressWarnings("unused") + private static String EDITOR_TYPE_CHECKBOX = "{ \"type\":\"checkbox\", \"options\":{\"on\":true,\"off\":false} }"; + /** + * 4 单选{ "type":"checkbox", "options":{"on":true,"off":false} } + */ + @SuppressWarnings("unused") + private static String EDITOR_TYPE_NUMBERBOX = "numberbox"; + + public static Map formatGridData(DataResult result) { + Map map = new HashMap(); + map.put("total", result.getTotalSize()); + map.put("rows", result.getResultList()); + return map; + } + + /** + * 将结果集转义成propertyGrid对象的json格式 1 字符串2 数字3 枚举4 单选rules中存放逗号分隔的选项 + * + * @param list + * 结果集中的list + * @param nameIndex + * @param valueIndex + * @param GroupIndex + * @param editorType + * @return + */ + @SuppressWarnings("unchecked") + public static List> formatPropertygridData( + List> list, String nameIndex, + String valueIndex, String GroupIndex, String editorType, + String ruleIndex, String idIndex) { + // [{"name":"Name","value":"Bill Smith","group":"ID Settings","editor":"text"}] + List> returnList = new ArrayList>(); + for (@SuppressWarnings("rawtypes") + Iterator iterator = list.iterator(); iterator.hasNext();) { + Map map = (Map) iterator.next(); + Map easyMap = new HashMap(); + easyMap.put("name", map.get(nameIndex).toString()); + easyMap.put("value", map.get(valueIndex).toString()); + easyMap.put("group", map.get(GroupIndex).toString()); + easyMap.put("id", map.get(idIndex).toString()); + // 1是文本2是枚举 + Object editor = EDITOR_TYPE_TEXT; + if ("2".equals(map.get(editorType).toString())) { + editor = EDITOR_TYPE_SELECT; + } + if ("3".equals(map.get(editorType).toString())) { + if(map.get(ruleIndex)!=null){ + editor = getComboboxOptions(map.get(ruleIndex).toString()); + } + } + if ("4".equals(map.get(editorType).toString())) { + Map type = new HashMap(); + type.put("type", "checkbox"); + Map type2 = new HashMap(); + type2.put("on", true); + type2.put("off", false); + type.put("options", type2); + editor = type; + // { "type":"checkbox", "options":{"on":true,"off":false} } + } + easyMap.put("editor", editor); + returnList.add(easyMap); + } + + return returnList; + } + + /** + * 生成 propertyGrid中的下拉框JSON + * + * @param Rules + * 逗号分隔的枚举项 + * @return + */ + private static Map getComboboxOptions(String Rules) { + // "editor":{ + // "type":"combobox", + // "options":{ + // "data":[{"value":1,"text":"一"},{"value":2,"text":"二"}], + // "panelHeight":"auto" + // } + Map map1 = new HashMap(); + // --------------------------------------- + String[] ruleArray = Rules.split(","); + List> ruleList = new ArrayList>(); + for (int i = 0; i < ruleArray.length; i++) { + Map nodeMap = new HashMap(); + nodeMap.put("value", ruleArray[i]); + nodeMap.put("text", ruleArray[i]); + ruleList.add(nodeMap); + } + Map mapOptions = new HashMap(); + mapOptions.put("data", ruleList); + mapOptions.put("panelHeight", "auto"); + map1.put("type", "combobox"); + map1.put("options", mapOptions); + return map1; + } + + /** + * 格式化ajax子树数据 + * + * @param result1 + * 依据父id查询出来的节点集合 + * @param result2 + * 依据父id查询出来的节点的子节点集合 + * @param parentIdIndex + * 父id的key + * @param idIndex + * id的key + * @param titleIndex + * 显示字段的key + * @param checkIndex + * 选中状态的key + * @return + */ + public static List formatAjaxTree( + List> result1, String parentIdIndex, + String idIndex, String titleIndex, String checkIndex) { + return EasyUiTreeNode.formatAjaxTree(result1, parentIdIndex, idIndex, + titleIndex, checkIndex, null); + } + + /** + * 格式化ajax子树数据 + * + * @param result1 + * 依据父id查询出来的节点集合 + * @param result2 + * 依据父id查询出来的节点的子节点集合 + * @param parentIdIndex + * 父id的key + * @param idIndex + * id的key + * @param titleIndex + * 显示字段的key + * @return + */ + public static List formatAjaxTree( + List> result1, String parentIdIndex, + String idIndex, String titleIndex) { + return EasyUiTreeNode.formatAjaxTree(result1, parentIdIndex, idIndex, + titleIndex); + } + + /** + * 格式化异步ajax子树数据 + * + * @param result1 + * 依据父id查询出来的节点集合 + * @param result2 + * 依据父id查询出来的节点的子节点集合 + * @param parentIdIndex + * 父id的key + * @param idIndex + * id的key + * @param titleIndex + * 显示字段的key + * @return + */ + public static List formatAsyncAjaxTree( + List> result1, + List> result2, String parentIdIndex, + String idIndex, String titleIndex, String imgIndex) { + return EasyUiTreeNode.formatAsyncAjaxTree(result1, result2, + parentIdIndex, idIndex, titleIndex, imgIndex); + } + + /** + * 格式化grid的查询条件 + * + * @param request + * @param query + * @return + */ + public static DataQuery formatGridQuery(HttpServletRequest request, + DataQuery query) { + // page=1&rows=10&sort=TITLE&order=asc + if (query == null) { + query = new DataQuery(); + } + if (request.getParameter("page") != null) { + query.setCurrentPage(request.getParameter("page").toString()); + } + if (request.getParameter("rows") != null) { + query.setPagesize(Integer.valueOf(request.getParameter("rows"))); + } + if (request.getParameter("sort") != null) { + query.addSort(new DBSort(request.getParameter("sort"), request + .getParameter("order"))); + } + return query; + } +} diff --git a/src/farm-core/src/main/java/com/farm/web/local/ConfDirHandle.java b/src/farm-core/src/main/java/com/farm/web/local/ConfDirHandle.java new file mode 100644 index 0000000..9cb8e5b --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/local/ConfDirHandle.java @@ -0,0 +1,44 @@ +package com.farm.web.local; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +public class ConfDirHandle { + /** + * 对配置文件做处理 + * + * @param strPath + * 配置文件夹路径 + * @param index + * 配置文件关键字 + * @param handle + * @param context + */ + public static void findDirForConf(String strPath, String[] indexs, + ConfHandleInter handle, Object context) { + try { + strPath=URLDecoder.decode(strPath,"utf-8"); + } catch (UnsupportedEncodingException e) { + System.out.println("ERROR:配置文件夹路径,解析错误"); + } + File dir = new File(strPath); + File[] files = dir.listFiles(); + if (files == null) + return; + for (int i = 0; i < files.length; i++) { + if (files[i].isDirectory()) { + findDirForConf(files[i].getAbsolutePath(), indexs, handle, + context); + } else { + String strFileName = files[i].getAbsolutePath().toLowerCase(); + for (String index : indexs) { + if (strFileName.replace("\\", ".").replace("/", ".") + .indexOf(index) >= 0) { + handle.execute(context, files[i]); + } + } + } + } + } +} diff --git a/src/farm-core/src/main/java/com/farm/web/local/ConfHandleInter.java b/src/farm-core/src/main/java/com/farm/web/local/ConfHandleInter.java new file mode 100644 index 0000000..4db191a --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/local/ConfHandleInter.java @@ -0,0 +1,7 @@ +package com.farm.web.local; + +import java.io.File; + +public interface ConfHandleInter { + public void execute(Object para,File file); +} diff --git a/src/farm-core/src/main/java/com/farm/web/online/OnlineUserOpImpl.java b/src/farm-core/src/main/java/com/farm/web/online/OnlineUserOpImpl.java new file mode 100644 index 0000000..73a98db --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/online/OnlineUserOpImpl.java @@ -0,0 +1,212 @@ +package com.farm.web.online; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpSession; + + +import com.farm.core.sql.result.DataResult; +import com.farm.web.constant.FarmConstant; + + +/** + * 在线用户管理 非集群实现 实现该功能需要将方法: userLoginHandle() + * userVisitHandle()加入到用户登录,和用户访问系统资源的代码中 + * + * @author wangdong + * + */ +public class OnlineUserOpImpl implements OnlineUserOpInter { + /** + * 当前用户ip + */ + private String ip; + private String loginName; + private HttpSession httpSession; + private Map strutsSession; + + @Override + public boolean doUserDownLine(String loginName) { + OnlineUserOpInter.onlineUserTable.remove(loginName); + return true; + } + + @Override + public DataResult findOnlineUser() { + List> list = new ArrayList>(); + for (String key : OnlineUserOpInter.onlineUserTable.keySet()) { + // 处理时间----开始 + // 上次访问时间 + Date date = (Date) OnlineUserOpInter.onlineUserTable.get(key).get( + OnlineUserOpInter.key_TIME); + // 登录时间 + Date visitdate = (Date) OnlineUserOpInter.onlineUserTable.get(key) + .get(OnlineUserOpInter.key_LOGINTIME); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat curentDayf = new SimpleDateFormat("yyyy-MM-dd"); + // 当前时间 + Date curentTime = new Date(); + // 当前时间 + Calendar curentC = Calendar.getInstance(); + curentC.setTime(curentTime); + // 上次访问时间 + Calendar curentV = Calendar.getInstance(); + curentV.setTime(date); + // 登录时间 + Calendar curentl = Calendar.getInstance(); + curentl.setTime(visitdate); + // 相差分钟数 + long timeMillis = (curentC.getTimeInMillis() - curentV + .getTimeInMillis()) + / (1000 * 60); + // 登录时长 + long visitMillis = (curentC.getTimeInMillis() - curentl + .getTimeInMillis()) + / (1000 * 60); + if (timeMillis > OnlineUserOpInter.onlineVilaMinute) { + // 超时用户判为不在线 + OnlineUserOpInter.onlineUserTable.remove(key); + continue; + } + // 处理时间----结束 + Map map = new HashMap(); + map.put(OnlineUserOpInter.key_LNAME, key); + map.put(OnlineUserOpInter.key_VISITTIME, visitMillis); + map.put(OnlineUserOpInter.key_TIME, sdf.format(date).replace( + curentDayf.format(new Date()), "今天")); + map.put(OnlineUserOpInter.key_USEROBJ, + OnlineUserOpInter.onlineUserTable.get(key).get( + OnlineUserOpInter.key_USEROBJ)); + map.put(OnlineUserOpInter.key_LOGINTIME, sdf + .format(OnlineUserOpInter.onlineUserTable.get(key).get( + OnlineUserOpInter.key_LOGINTIME)).replace( + curentDayf.format(new Date()), "今天")); + map.put(OnlineUserOpInter.key_IP, OnlineUserOpInter.onlineUserTable + .get(key).get(OnlineUserOpInter.key_IP)); + list.add(map); + + } + DataResult result = DataResult.getInstance(list, list.size(), 1, list + .size()); + return result; + } + + @Override + public void userLoginHandle(Object user) { + if (!((httpSession == null && strutsSession == null) + || loginName == null || ip == null)) { + Map userMap = new HashMap(); + userMap.put(OnlineUserOpInter.key_IP, ip); + userMap.put(OnlineUserOpInter.key_TIME, new Date()); + userMap.put(OnlineUserOpInter.key_LNAME, loginName); + userMap.put(OnlineUserOpInter.key_LOGINTIME, new Date()); + userMap.put(OnlineUserOpInter.key_USEROBJ, user); + // 将用户注册在在线表中 + OnlineUserOpInter.onlineUserTable.put(loginName, userMap); + } else { + throw new RuntimeException("参数错误"); + } + } + + @Override + public void userVisitHandle() { + // 用户没有在在线表中就将用户注销 + if (!((httpSession == null && strutsSession == null) + || loginName == null || ip == null)) { + Map userMap = OnlineUserOpInter.onlineUserTable + .get(loginName); + if (userMap == null) { + // 没有在线 + clearSessionUser(); + return; + } else { + userMap.put(OnlineUserOpInter.key_TIME, new Date()); + if (!userMap.get(OnlineUserOpInter.key_IP).equals(ip)) { + // 用户ip不匹配 + clearSessionUser(); + return; + } else { + // 没有问题,用户是在线不处理 + } + } + } else { + throw new RuntimeException("参数错误"); + } + } + + // ----------private------------------------------------------------ + private void clearSessionUser() { + if (this.httpSession != null) { + httpSession.removeAttribute(FarmConstant.SESSION_USEROBJ); + } + if (this.strutsSession != null) { + strutsSession.put(FarmConstant.SESSION_USEROBJ, null); + strutsSession.clear(); + } + } + + // ----------get/set------------------------------------------------ + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public HttpSession getHttpSession() { + return httpSession; + } + + public void setHttpSession(HttpSession httpSession) { + this.httpSession = httpSession; + } + + public Map getStrutsSession() { + return strutsSession; + } + + public void setStrutsSession(Map strutsSession) { + this.strutsSession = strutsSession; + } + + public String getLoginName() { + return loginName; + } + + public void setLoginName(String loginName) { + this.loginName = loginName; + } + + // --------------------------------------构造方法 + public static OnlineUserOpInter getInstance(String ip, String loginName, + HttpSession httpSession) { + OnlineUserOpImpl obj = new OnlineUserOpImpl(); + obj.setHttpSession(httpSession); + obj.setLoginName(loginName); + obj.setIp(ip); + return obj; + } + + public static OnlineUserOpInter getInstance(String ip, String loginName, + Map strutsSession) { + OnlineUserOpImpl obj = new OnlineUserOpImpl(); + obj.setIp(ip); + obj.setLoginName(loginName); + obj.setStrutsSession(strutsSession); + return obj; + } + + public static OnlineUserOpInter getInstance() { + OnlineUserOpImpl obj = new OnlineUserOpImpl(); + return obj; + } + +} diff --git a/src/farm-core/src/main/java/com/farm/web/online/OnlineUserOpInter.java b/src/farm-core/src/main/java/com/farm/web/online/OnlineUserOpInter.java new file mode 100644 index 0000000..3fcb372 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/online/OnlineUserOpInter.java @@ -0,0 +1,86 @@ +package com.farm.web.online; + +import java.util.HashMap; +import java.util.Map; + + +import com.farm.core.sql.result.DataResult; + + +/** + * 在线用户管理 非集群实现 实现该功能需要将方法: userLoginHandle() + * userVisitHandle()加入到用户登录,和用户访问系统资源的代码中 + * + * @author wangdong + * @date 2012-03-01 + */ +public interface OnlineUserOpInter { + /** + * 在线用户注册表,勿调用、勿操作 + */ + static final Map> onlineUserTable = new HashMap>(); + /** + * 最近访问时间 + */ + static final String key_TIME = "TIME"; + /** + * 用户IP + */ + static final String key_IP = "IP"; + /** + * 用户loginName + */ + static final String key_LNAME = "LNAME"; + /** + * 用户对象 + */ + static final String key_USEROBJ = "USEROBJ"; + /** + * 用户登录时间 + */ + static final String key_LOGINTIME = "LOGINTIME"; + /** + * 登录时长 + */ + static final String key_VISITTIME = "VISITTIME"; + /** + * 在线用户判超时时间 (分) + */ + static final long onlineVilaMinute = 60; + + + /** + * 用户访问handle 判断当前用户是否在线,不在线就(从session中)注销掉用户 + * + * @param strutsSession + * STRUTS的session + * @param ip + * 用户ip + */ + public void userVisitHandle(); + + /** + * 用户登录时对在线用户的操作 注册在线用户 + * + * @param httpSession + * session + * @param ip + * 用户ip + */ + public void userLoginHandle(Object user); + + /** + * 查看当前在线用户 + * + * @return + */ + public DataResult findOnlineUser(); + + /** + * 强制用户下线 + * + * @param loginName + * @return + */ + public boolean doUserDownLine(String loginName); +} diff --git a/src/farm-core/src/main/java/com/farm/web/task/ServletInitJobInter.java b/src/farm-core/src/main/java/com/farm/web/task/ServletInitJobInter.java new file mode 100644 index 0000000..7842353 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/task/ServletInitJobInter.java @@ -0,0 +1,17 @@ + +package com.farm.web.task; + +import javax.servlet.ServletContext; + +/** + * 随系统启动任务接口 + * + * @author 王东 + * + */ +public interface ServletInitJobInter { + /**被执行的任务 + * @param context + */ + public void execute(ServletContext context); +} diff --git a/src/farm-core/src/main/java/com/farm/web/task/SysInit.java b/src/farm-core/src/main/java/com/farm/web/task/SysInit.java new file mode 100644 index 0000000..96496f6 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/task/SysInit.java @@ -0,0 +1,51 @@ +package com.farm.web.task; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; + +import org.apache.log4j.Logger; + +import com.farm.util.spring.BeanFactory; + +public class SysInit extends HttpServlet { + + /** + * 任务集合 + */ + private static List list = new ArrayList(); + private static final long serialVersionUID = 1L; + + // 配置系统所有默认启动任务 + + public SysInit() { + super(); + } + + private final Logger log = Logger.getLogger(this.getClass()); + + public void destroy() { + super.destroy(); + } + + public void init() throws ServletException { + list = ((TaskListInter) BeanFactory.getBean("startServerTasksId", getServletContext())).getTasks(); + log.info("--系统准备运行" + list.size() + "项"); + if (list == null) { + list = new ArrayList(); + } + int n = 0; + try { + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + n++; + ServletInitJobInter name = (ServletInitJobInter) iterator.next(); + name.execute(this.getServletContext()); + } + } catch (Exception e) { + log.error("第" + n + "项任务启动失败:" + e.getMessage()); + } + } +} diff --git a/src/farm-core/src/main/java/com/farm/web/task/TaskListInter.java b/src/farm-core/src/main/java/com/farm/web/task/TaskListInter.java new file mode 100644 index 0000000..9523ac2 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/task/TaskListInter.java @@ -0,0 +1,11 @@ +package com.farm.web.task; + +import java.util.List; + +/**由spring注入启动任务,被sysinit类调用来启动配置的任务 + * @author Administrator + * + */ +public interface TaskListInter { + public List getTasks(); +} diff --git a/src/farm-core/src/main/java/com/farm/web/task/impl/ServerLicenceInit.java b/src/farm-core/src/main/java/com/farm/web/task/impl/ServerLicenceInit.java new file mode 100644 index 0000000..9531074 --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/task/impl/ServerLicenceInit.java @@ -0,0 +1,64 @@ +package com.farm.web.task.impl; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import javax.servlet.ServletContext; + +import org.apache.log4j.Logger; + +import com.farm.web.constant.FarmConstant; +import com.farm.web.task.ServletInitJobInter; + +public class ServerLicenceInit implements ServletInitJobInter { + + private final static Logger log = Logger.getLogger(ServerLicenceInit.class); + + @Override + public void execute(ServletContext context) { + try { + FarmConstant.LICENCE = read( + new File(context.getRealPath("") + File.separator + + "licence.data")).replace("\n", ""); + } catch (Exception e) { + FarmConstant.LICENCE = null; + } + try { +// System.out.println("info: case is "+FarmConstant.LICENCE + " for " +// + MayCase.isCase(FarmConstant.LICENCE)); + } catch (Exception e) { + System.out.println("info: case is "+FarmConstant.LICENCE + " for "+ ":false"); + } + } + + public String read(File file) throws Exception { + StringBuffer lines = new StringBuffer(); + InputStream inputStream = null; + BufferedReader reader = null; + InputStreamReader inputStreamReader = null; + try { + inputStream = new FileInputStream(file); + inputStreamReader = new InputStreamReader(inputStream); + reader = new BufferedReader(inputStreamReader); + String line = null; + while ((line = reader.readLine()) != null) { + lines.append(line).append("\n"); + } + } catch (IOException e) { + log.info(e.getMessage(), e); + } finally { + try { + inputStreamReader.close(); + inputStream.close(); + reader.close(); + } catch (IOException e) { + log.info(e.getMessage(), e); + } + } + return lines.toString(); + } +} diff --git a/src/farm-core/src/main/java/com/farm/web/task/impl/TaskListImpl.java b/src/farm-core/src/main/java/com/farm/web/task/impl/TaskListImpl.java new file mode 100644 index 0000000..7f4f68d --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/task/impl/TaskListImpl.java @@ -0,0 +1,20 @@ +package com.farm.web.task.impl; + +import java.util.List; + +import com.farm.web.task.ServletInitJobInter; +import com.farm.web.task.TaskListInter; + +public class TaskListImpl implements TaskListInter { + private List tasks; + + @Override + public List getTasks() { + return tasks; + } + + public void setTasks(List tasks) { + this.tasks = tasks; + } + +} diff --git a/src/farm-core/src/main/java/com/farm/web/test/FarmTest.java b/src/farm-core/src/main/java/com/farm/web/test/FarmTest.java new file mode 100644 index 0000000..529ddbe --- /dev/null +++ b/src/farm-core/src/main/java/com/farm/web/test/FarmTest.java @@ -0,0 +1,7 @@ +package com.farm.web.test; + +import com.farm.core.auth.domain.LoginUser; + +public class FarmTest { + public LoginUser user =null; +} diff --git a/src/farm-core/src/test/java/com/farm/text/MarkLicenceKey.java b/src/farm-core/src/test/java/com/farm/text/MarkLicenceKey.java new file mode 100644 index 0000000..b2bbcff --- /dev/null +++ b/src/farm-core/src/test/java/com/farm/text/MarkLicenceKey.java @@ -0,0 +1,10 @@ +package com.farm.text; + +import com.farm.core.auth.util.KeyUtil; +public class MarkLicenceKey { + public static void main(String[] args) { + System.out.println(KeyUtil.getMKey()); + //System.out.println(KeyUtil.getFkey("8C8-60723AA5")); + System.out.println(KeyUtil.getFkey("C4B-8AF11814")); + } +} diff --git a/src/wcp-api/pom.xml b/src/wcp-api/pom.xml new file mode 100644 index 0000000..edbc752 --- /dev/null +++ b/src/wcp-api/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + com.farm.wcp + wcp-api + ${wcp.version} + + 3.2.0 + + + UTF-8 + UTF-8 + + UTF-8 + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/src/wcp-api/src/main/java/com/farm/wcp/api/WcpAppInter.java b/src/wcp-api/src/main/java/com/farm/wcp/api/WcpAppInter.java new file mode 100644 index 0000000..f9bcfe4 --- /dev/null +++ b/src/wcp-api/src/main/java/com/farm/wcp/api/WcpAppInter.java @@ -0,0 +1,73 @@ +package com.farm.wcp.api; + +import java.rmi.Remote; +import java.rmi.RemoteException; + +import com.farm.wcp.api.exception.DocCreatErrorExcepiton; +import com.farm.wcp.domain.Results; +//WcpAPPInter接口继承了Remote类,Remote干嘛的? +public interface WcpAppInter extends Remote { + + /** + * 创建html知识 + * + * @param knowtitle + * 标题 + * @param knowtypeId + * 分类 + * @param text + * 内容 + * @param knowtag + * tag + * @param groupId + * 小组 + * @param fileId + * 内容图 + * @param currentUserId + * 创建用户 + * @return + * @throws RemoteException + */ + //创建html知识,传入参数(标题,标题,分类,内容,小组,内容图,创建用户) + //内容图是社么? + public String creatHTMLKnow(String knowtitle, String knowtypeId, String text, String knowtag, String currentUserId) + //抛出一些异常 + throws RemoteException, DocCreatErrorExcepiton; + + /** + * 对附件做索引(同时会保存附件文本内容在数据库中方便后续重建索引) + * + * @param fileid + * 附件id + * @param docid + * 知识id + * @param text + * 索引文字 + * @throws ErrorTypeException + * @throws RemoteException + */ + //抽象类,功能负责对附件做索引,需要传一些参数(附件Id,知识id,索引文字),保存附件文本内容 + public void runLuceneIndex(String fileid, String docid, String text) throws RemoteException; + + /** + * 获得分类下的知识 + * + * @param typeid + * @param pagesize + * @param pagenum + * @return + */ + //get方法获得文档的类型,需要传入参数(类型id,页的大小,最近页,登录的名字) + public Results getTypeDocs(String typeid, int pagesize, int currentpage, String loginname)throws RemoteException; + //抛出RemoteException异常 + /** + * 获得所有知识分类 + * + * @param typeid + * @param pagesize + * @param currentpage + * @return + */ + //get方法获得所有知识分类,需要参数登录名字,抛出RemoteException异常,RemoteException干嘛的? + public Results getAllTypes(String loginname)throws RemoteException; +} diff --git a/src/wcp-api/src/main/java/com/farm/wcp/api/client/WcpAppClient.java b/src/wcp-api/src/main/java/com/farm/wcp/api/client/WcpAppClient.java new file mode 100644 index 0000000..a07a9bb --- /dev/null +++ b/src/wcp-api/src/main/java/com/farm/wcp/api/client/WcpAppClient.java @@ -0,0 +1,30 @@ +package com.farm.wcp.api.client; + +import java.net.MalformedURLException; +import java.rmi.Naming; +import java.rmi.NotBoundException; +import java.rmi.RemoteException; + +import com.farm.wcp.api.WcpAppInter; + +public class WcpAppClient { + /** + * 执行wcp接口 + * + * @param rmiUrl + * rmi://127.0.0.1:8701/wcpapp + * @return + * @throws MalformedURLException + * @throws RemoteException + * @throws NotBoundException + */ + //创建一个WcpAPPInter类的get服务方法传入参数是rmiUrl + public static WcpAppInter getServer(String rmiUrl) + //抛出异常没有边界异常,远程异常,URL格式异常。 + throws MalformedURLException, RemoteException, NotBoundException { + //创建WcpAPPInter对象,使用静态方法lookup + WcpAppInter wcpApp = (WcpAppInter) Naming.lookup(rmiUrl); + //返回这个WcpApp的对象 + return wcpApp; + } +} diff --git a/src/wcp-api/src/main/java/com/farm/wcp/api/exception/DocCreatErrorExcepiton.java b/src/wcp-api/src/main/java/com/farm/wcp/api/exception/DocCreatErrorExcepiton.java new file mode 100644 index 0000000..97cae4e --- /dev/null +++ b/src/wcp-api/src/main/java/com/farm/wcp/api/exception/DocCreatErrorExcepiton.java @@ -0,0 +1,21 @@ +//导包 +package com.farm.wcp.api.exception; + +/** 文档无法创建异常 + * @author wangdong + * + */ +//文档创建错误异常的类继承了Exception异常类 +public class DocCreatErrorExcepiton extends Exception { + /** + * + */ + //设置serialVersionUID常量为1L,serialVersionUID是干嘛的? + private static final long serialVersionUID = 1L; + //初始化,构造方法 + public DocCreatErrorExcepiton(Exception e) { + //把异常抛出给他的父类exception异常类 + super(e); + } + +} diff --git a/src/wcp-api/src/main/java/com/farm/wcp/domain/Results.java b/src/wcp-api/src/main/java/com/farm/wcp/domain/Results.java new file mode 100644 index 0000000..c1a7d2f --- /dev/null +++ b/src/wcp-api/src/main/java/com/farm/wcp/domain/Results.java @@ -0,0 +1,52 @@ +package com.farm.wcp.domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +//Results类,Result前面返回值 getTypeDocs()get方法获得文档的类型 ,getAllTypes()get方法获得所有知识分类, +public class Results { + //创建一个list(List有序,可重复,有索引),泛型是Map集合。里面存储社么东西? + private List> list = new ArrayList<>(); + //Results类的成员对象有:totalsize(Result{文档有关}的size大小) + private int totalsize; + //记录文档最近的页 + private int currentpage; + //页面的大小 + private int pagesize; + + + //下面是Result的get set方法 + //获得list集合的方法 + public List> getList() { + return list; + } + //对list对象设置的set方法 + public void setList(List> list) { + this.list = list; + } + //get获取页的总大小 + public int getTotalsize() { + return totalsize; + } + //set设置页的总大小 + public void setTotalsize(int totalsize) { + this.totalsize = totalsize; + } + //获取最近的页 + public int getCurrentpage() { + return currentpage; + } + //设置最近的页 + public void setCurrentpage(int currentpage) { + this.currentpage = currentpage; + } + //get获取最近页的大小 + public int getPagesize() { + return pagesize; + } + //get最近页的大小 + public void setPagesize(int pagesize) { + this.pagesize = pagesize; + } + +} diff --git a/src/wcp-authority/pom.xml b/src/wcp-authority/pom.xml new file mode 100644 index 0000000..56b7787 --- /dev/null +++ b/src/wcp-authority/pom.xml @@ -0,0 +1,64 @@ + + 4.0.0 + com.farm + wcp-authority + ${wcp.version} + 用户和权限系统 + + 3.2.0 + + UTF-8 + UTF-8 + + UTF-8 + + + + com.farm + farm-core + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + com.farm + wcp-parameter + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.1 + + + + true + true + + + + + + + \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/AuthUtils.java b/src/wcp-authority/src/main/java/com/farm/authority/AuthUtils.java new file mode 100644 index 0000000..5be9ffa --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/AuthUtils.java @@ -0,0 +1,17 @@ +package com.farm.authority; + +import javax.servlet.http.HttpSession; + +import com.farm.authority.domain.Organization; +import com.farm.authority.service.UserServiceInter; +import com.farm.core.auth.domain.LoginUser; +import com.farm.util.spring.BeanFactory; +import com.farm.web.constant.FarmConstant; + +public class AuthUtils { + public static Organization getCurrentOrganization(HttpSession session) { + UserServiceInter users = (UserServiceInter) BeanFactory.getBean("userServiceImpl"); + LoginUser user = (LoginUser) session.getAttribute(FarmConstant.SESSION_USEROBJ); + return users.getOrg(user.getId()); + } +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/FarmAuthorityService.java b/src/wcp-authority/src/main/java/com/farm/authority/FarmAuthorityService.java new file mode 100644 index 0000000..7fa9e74 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/FarmAuthorityService.java @@ -0,0 +1,133 @@ +package com.farm.authority; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.farm.authority.domain.Action; +import com.farm.authority.domain.User; +import com.farm.authority.service.ActionServiceInter; +import com.farm.authority.service.UserServiceInter; +import com.farm.core.AuthorityService; +import com.farm.core.auth.domain.AuthKey; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.auth.exception.LoginUserNoExistException; +import com.farm.core.auth.util.AuthenticateInter; +import com.farm.core.auth.util.AuthenticateProvider; +import com.farm.util.spring.BeanFactory; + +public class FarmAuthorityService implements AuthorityService { + private UserServiceInter userServiceImpl; + private ActionServiceInter actionServiceImpl; + private AuthenticateInter authUtil = AuthenticateProvider.getInstance(); + private static FarmAuthorityService service; + + public static AuthorityService getInstance() { + if (service == null) { + service = new FarmAuthorityService(); + service.userServiceImpl = (UserServiceInter) BeanFactory.getBean("userServiceImpl"); + service.actionServiceImpl = (ActionServiceInter) BeanFactory.getBean("actionServiceImpl"); + } + return service; + } + + @Override + public void loginHandle(String userId) { + userServiceImpl.setLoginTime(userId); + } + + @Override + public Set getUserAuthKeys(String userId) { + User user = userServiceImpl.getUserEntity(userId); + List actions = null; + if (user.getType().equals("3")) { + actions = actionServiceImpl.getAllActions(); + } else { + actions = userServiceImpl.getUserActions(userId); + } + Set set = new HashSet(); + for (Action action : actions) { + set.add(action.getAuthkey()); + } + return set; + } + + @Override + public LoginUser getUserById(String userId) { + return userServiceImpl.getUserEntity(userId); + } + + @Override + public LoginUser getUserByLoginName(String loginName) { + return userServiceImpl.getUserByLoginName(loginName); + } + + @Override + public List getUserMenu(String userId) { + User user = userServiceImpl.getUserEntity(userId); + List list = null; + if (user.getType().equals("3")) { + list = actionServiceImpl.getAllMenus(); + } else { + list = userServiceImpl.getUserMenus(userId); + } + return list; + } + + @Override + public boolean isLegality(String loginName, String password) throws LoginUserNoExistException { + User user = userServiceImpl.getUserByLoginName(loginName); + if (user == null) { + throw new LoginUserNoExistException("该登录名不存在!"); + } + if (user.getType().equals("2")) { + throw new LoginUserNoExistException("该用户无登录权限!"); + } + if (!user.getState().equals("1")) { + throw new LoginUserNoExistException("该用户已停用!"); + } + if (authUtil.isMd5code(password)) { + if (password.toUpperCase().equals(user.getPassword())) { + return true; + } + } else { + if (authUtil.encodeLoginPasswordOnMd5(password, loginName).equals(user.getPassword())) { + return true; + } + } + return false; + } + + @Override + public AuthKey getAuthKey(String key) { + return actionServiceImpl.getCacheAction(key); + } + + @Override + public List getUserPostKeys(String userId) { + return userServiceImpl.getUserPostIds(userId); + } + + @Override + public String getUserOrgKey(String userId) { + return userServiceImpl.getUserOrganization(userId).getId(); + } + + public UserServiceInter getUserServiceImpl() { + return userServiceImpl; + } + + public void setUserServiceImpl(UserServiceInter userServiceImpl) { + this.userServiceImpl = userServiceImpl; + } + + public ActionServiceInter getActionServiceImpl() { + return actionServiceImpl; + } + + public void setActionServiceImpl(ActionServiceInter actionServiceImpl) { + this.actionServiceImpl = actionServiceImpl; + } + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/controller/ActionController.java b/src/wcp-authority/src/main/java/com/farm/authority/controller/ActionController.java new file mode 100644 index 0000000..7dc8e23 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/controller/ActionController.java @@ -0,0 +1,278 @@ +package com.farm.authority.controller; +//@RequestMapping("/edit") // 映射HTTP请求路径为"/edit",当客户端发送对该路径的请求时,将调用此方法 + +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import javax.annotation.Resource; + +import com.farm.authority.domain.Action; +import com.farm.authority.service.ActionServiceInter; +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; +//RequestMapping是干嘛的? 它用于将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。 +// MVC 和 REST 控制器的处理方法上是社么? +// 这个注解可以用在类或方法上 +// 表示类中的所有响应请求的方法都以该地址作为父路径。 +@RequestMapping("/action")//action是父路径 +@Controller +//Controller是干嘛的? +//Controller层的作用可概括如下: +// 1. 接收和处理用户请求。当用户发起请求时,Controller层会根据请求的URL、HTTP方法 +// 等信息来判断请求的目标,并调用相应的方法进行处理。 +//2. 调用Service层处理业务逻辑。当Controller需要进行业务逻辑处理时, +// 会调用Service层的方法,Service层会根据具体业务需求进行相应的处理。 +//3. 返回处理结果。Controller层在完成请求处理之后,会将处理结果封装成 +// 一个ModelAndView对象,然后将其发给前端页面进行显示 +//4. 控制页面跳转。当用户请求需要跳转到另一个页面时, +// Controller层负责选择正确的View并返回相应的ModelAndView, +// 然后前端页面根据ModelAndView中的信息进行页面渲染,完成页面跳转。 +// +//5. 验证数据。对于提交的表单数据等信息,Controller层会进行验证, +// 通过该验证可以确定数据的合法性,避免用户输入错误或者恶意提交的数据对系统造成危害。 +// +//6. 处理异常。在Controller处理过程中,可能会出现异常,此时需要在Controller中捕获 +// 并处理异常,避免异常向上抛出影响整个Web应用程序的正常运行。 +//ActionController类继承WebUtils +public class ActionController extends WebUtils { + //Logger对象是个不可变的类 + private final static Logger log = Logger.getLogger(ActionController.class); + @Resource + //在启动spring的时候,首先要启动容器 ; + //启动spring容器时,会默认寻找容器扫描范围内的可加载bean,然后查找哪些bean上的属性和方法上有@Resource注解; + //找到@Resource注解后,判断@Resource注解括号中的name属性是否为空,如果为空: + // 看spring容器中的bean的id与@Resource要注解的那个变量属性名是否相同,如相同,匹配成功; + // 如果不相同,看spring容器中bean的id对应的类型是否与@Resource要注解的那个变量属性对应的类型 + // 是否相等,若相等,匹配成功,若不相等,匹配失败。 + //如果@Resource注解括号中的name属性不为空,看name的属性值和容器中的bean的id名是否相等,如相等,则匹配成功;如不相等,则匹配失败。 + + ActionServiceInter actionServiceImpl; + //actionServiceImpl是个静态的ActionServiceInter类 + //下面是getActionServiceImpl的get/set方法 + public ActionServiceInter getActionServiceImpl() { + return actionServiceImpl; + } + //set方法设置setActionServiceImpl,参数有actionServiceImpl + public void setActionServiceImpl(ActionServiceInter actionServiceImpl) { + this.actionServiceImpl = actionServiceImpl; + } + + /** + * 查询结果集合 + * + * @return + */ + //query是父路径 + @RequestMapping("/query") + // + @ResponseBody + //其返回值会被自动序列化为指定格式的数据(如 JSON 或 XML),并直接写入 HTTP 响应体中,而不会触发视图解析器的处理 + //query是查询的意思 + public Map queryall(DataQuery query, HttpServletRequest request) { + try { + // 使用EasyUiUtils工具类格式化前端传来的查询条件,将其转换为DataQuery对象 + query = EasyUiUtils.formatGridQuery(request, query); + + // 创建一个简单的查询动作,并执行查询操作,返回DataResult对象 + DataResult result = actionServiceImpl.createActionSimpleQuery(query).search(); + + // 对查询结果中的CHECKIS字段进行字典转换,将1转换为“是”,0转换为“否” + //字典转化是社么?对一个字符串转化成字典里面的另一个字符串 + result.runDictionary("1:是,0:否", "CHECKIS"); + + // 对查询结果中的LOGINIS字段进行字典转换,将1转换为“是”,0转换为“否” + result.runDictionary("1:是,0:否", "LOGINIS"); + + // 对查询结果中的STATE字段进行字典转换,将1转换为“可用”,0转换为“不可用” + result.runDictionary("1:可用,0:不可用", "STATE"); + + // 使用ViewMode工具类将查询结果格式化为前端DataGrid所需的格式,并返回 + return ViewMode.getInstance().putAttrs(EasyUiUtils.formatGridData(result)).returnObjMode(); + } catch (Exception e) { + // 捕获并记录异常信息 + log.error(e.getMessage()); + + // 返回一个包含错误信息的Map对象 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + // 获取ViewMode的单例实例,并调用returnModelAndView方法,传入视图名称"authority/ActionResult" + // 返回一个ModelAndView对象,其中包含视图名称"authority/ActionResult",但不包含任何模型数据 + return ViewMode.getInstance() + .returnModelAndView("authority/ActionResult"); + } + + + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") // 映射HTTP请求路径为"/edit",当客户端发送对该路径的请求时, + // 将调用此方法 + @ResponseBody // 表示该方法的返回结果直接写入HTTP response body中,而不是解析为视图名称 + //HTTP response body + //HTTP响应体(Response Body)是HTTP响应中用于传输实际数据的部分 + //通常包含服务器向客户端发送的内容。其内容和格式取决于请求方法、状态码 + //以及响应头中的Content-Type字段 + public Map editSubmit(Action entity, HttpSession session) { // 方法接收一个Action对象和一个HttpSession对象作为参数 + try { + // 调用actionServiceImpl的editActionEntity方法编辑实体,并传入当前用户信息 + entity = actionServiceImpl.editActionEntity(entity, getCurrentUser(session)); + // 创建一个ViewMode对象,设置操作类型为ADD,并将编辑后的实体放入属性中,最后返回一个包含这些信息的Map对象 + return ViewMode.getInstance().setOperate(OperateType.ADD).putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + // 捕获并打印异常信息 + e.printStackTrace(); + log.error(e.getMessage()); + // 创建一个ViewMode对象,设置操作类型为ADD,并将错误信息放入属性中,最后返回一个包含这些信息的Map对象 + return ViewMode.getInstance().setOperate(OperateType.ADD).setError(e.getMessage()).returnObjMode(); + } + } + + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") //映射HTTP请求为/add的路径,当客户端对此方法请求时 + //调用下面的方法 + @ResponseBody + //一般和RequestMapping("/路径")连用 + public Map addSubmit(Action entity, HttpSession session) { + try { + // 调用actionServiceImpl的insertActionEntity方法,将Action实体插入数据库,并获取当前用户信息 + entity = actionServiceImpl.insertActionEntity(entity, getCurrentUser(session)); + // 创建一个ViewMode实例,并将插入后的entity对象放入其中,然后返回一个对象模式的结果 + return ViewMode.getInstance().putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + // 如果发生异常,记录错误日志 + log.error(e.getMessage()); + // 创建一个ViewMode实例,并设置错误信息,然后返回一个对象模式的结果 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + // 解析传入的ids字符串,将其转换为字符串数组 + for (String id : parseIds(ids)) { + // 调用actionServiceImpl的deleteActionEntity方法,删除指定id的实体,并传入当前用户信息 + actionServiceImpl.deleteActionEntity(id, getCurrentUser(session)); + } + // 返回一个成功的视图模式对象 + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + // 捕获并记录异常信息 + log.error(e.getMessage()); + // 返回一个包含错误信息的视图模式对象 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + + @RequestMapping("/info") + @ResponseBody + public Map view(String ids) { + try { + // 调用actionServiceImpl.getActionEntity方法获取实体信息,并将其放入ViewMode对象中 + return ViewMode.getInstance() + .putAttr("entity", actionServiceImpl.getActionEntity(ids)) + .returnObjMode(); + } catch (Exception e) { + // 捕获异常并记录错误日志 + log.error(e.getMessage()); + // 返回包含错误信息的Map对象 + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + // 映射URL路径为"/form",当请求路径为"/form"时,调用此方法 + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + // 根据pageset中的操作类型(operateType)执行不同的逻辑 + switch (pageset.getOperateType()) { + case (0): { // 操作类型为0:查看操作 + // 返回一个ModelAndView对象,包含以下属性: + // 1. "pageset":传入的pageset对象 + // 2. "entity":通过actionServiceImpl获取的实体对象(根据ids查询) + // 视图名称为"authority/ActionForm" + return ViewMode.getInstance() + .putAttr("pageset", pageset) // 添加pageset到模型 + .putAttr("entity", actionServiceImpl.getActionEntity(ids)) // 添加实体对象到模型 + .returnModelAndView("authority/ActionForm"); // 返回视图 + } + case (1): { // 操作类型为1:新增操作 + // 返回一个ModelAndView对象,仅包含"pageset"属性 + // 视图名称为"authority/ActionForm" + return ViewMode.getInstance() + .putAttr("pageset", pageset) // 添加pageset到模型 + .returnModelAndView("authority/ActionForm"); // 返回视图 + } + case (2): { // 操作类型为2:修改操作 + // 返回一个ModelAndView对象,包含以下属性: + // 1. "pageset":传入的pageset对象 + // 2. "entity":通过actionServiceImpl获取的实体对象(根据ids查询) + // 视图名称为"authority/ActionForm" + return ViewMode.getInstance() + .putAttr("pageset", pageset) // 添加pageset到模型 + .putAttr("entity", actionServiceImpl.getActionEntity(ids)) // 添加实体对象到模型 + .returnModelAndView("authority/ActionForm"); // 返回视图 + } + default: // 如果操作类型不在0、1、2中,执行默认逻辑 + break; + } + // 默认情况下,返回一个空的ModelAndView对象,视图名称为"authority/ActionForm" + return ViewMode.getInstance() + .returnModelAndView("authority/ActionForm"); // 返回视图 + } catch (Exception e) { // 捕获异常 + // 返回一个包含错误信息的ModelAndView对象 + // 视图名称为"authority/UserForm" + return ViewMode.getInstance() + .setError(e + e.getMessage()) // 设置错误信息 + .returnModelAndView("authority/UserForm"); // 返回视图 + } + } + + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/controller/ActiontreeController.java b/src/wcp-authority/src/main/java/com/farm/authority/controller/ActiontreeController.java new file mode 100644 index 0000000..e4496db --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/controller/ActiontreeController.java @@ -0,0 +1,364 @@ +package com.farm.authority.controller; + +import com.farm.authority.domain.Action; +import com.farm.authority.domain.Actiontree; +import com.farm.authority.service.ActionServiceInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiTreeNode; +import com.farm.web.easyui.EasyUiUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; + +/* * + *功能:构造权限控制层 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +// 声明这是一个Spring MVC控制器,并映射到"/actiontree"路径下的所有请求 +@RequestMapping("/actiontree") +@Controller +public class ActiontreeController extends WebUtils { + // 定义一个静态日志记录器,用于记录日志信息 + private final static Logger log = Logger.getLogger(ActiontreeController.class); + + // 注入ActionServiceInter接口的实现类,用于处理业务逻辑 + @Resource + ActionServiceInter actionServiceImpl; + + // 映射到"/actiontree/list"路径下的GET请求 + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + // 返回一个ModelAndView对象,指定视图为"authority/ActiontreeResult" + return ViewMode.getInstance().returnModelAndView("authority/ActiontreeResult"); + } +} + + +@RequestMapping("/icons") +// 创建并返回一个ModelAndView对象,视图名称为"authority/ActionCssIcon" +public ModelAndView icons(HttpSession session) { + // HttpSession对象作为参数传递给方法,但在这个方法中并未使用session对象进行任何操作 + return ViewMode.getInstance().returnModelAndView( + // 这个方法处理对"/icons"路径的请求,并返回一个ModelAndView对象,其中包含视图名称 + "authority/ActionCssIcon"); +} + +@RequestMapping("/actionsPage") +public ModelAndView actionsPage(HttpSession session) { + // 创建并返回一个ModelAndView对象,指定视图为"authority/ActionChoose" + // 这里的ModelAndView对象用于将数据模型和视图名称封装在一起,便于Spring MVC框架进行处理和渲染 + return ViewMode.getInstance().returnModelAndView( + "authority/ActionChoose"); +} + + +@RequestMapping("/treePage") +public ModelAndView treePage(HttpSession session, String ids) { + // 获取传入的ids参数,并将其放入ModelAndView对象中,以便在视图中使用 + return ViewMode.getInstance().putAttr("ids", ids) + .returnModelAndView("authority/ActiontreenodeChooseTreeWin"); +} + + + /** + * 查询所有主菜单结果集合 + * + * @return + */ + @RequestMapping("/query") // 映射HTTP请求路径为"/query",当客户端访问该路径时,会调用此方法[[3, 13, 27, 33, 35]] + @ResponseBody // 表示该方法的返回值直接写入HTTP response body中,而不是被解析为跳转路径[[13, 32]] + public Map queryall(DataQuery query, HttpServletRequest request) { // 定义一个处理查询请求的方法,接收DataQuery对象和HttpServletRequest对象作为参数 + try { + query = EasyUiUtils.formatGridQuery(request, query); // 使用EasyUiUtils工具类格式化查询参数,将请求中的参数应用到DataQuery对象上[[27]] + if (query.getQueryRule().size() == 0) { // 检查查询规则是否为空 + query.addRule(new DBRule("PARENTID", "NONE", "=")); // 如果为空,则添加一个默认的查询规则,即PARENTID等于"NONE" + } + DataResult result = actionServiceImpl.createActiontreeSimpleQuery(query).search(); // 调用actionServiceImpl的createActiontreeSimpleQuery方法创建查询,并执行查询操作,获取查询结果 + result.runDictionary("1:分类,2:菜单,3:权限", "TYPE"); // 对查询结果中的TYPE字段进行字典转换,将数字转换为对应的中文描述 + result.runDictionary("1:可用,0:禁用", "STATE"); // 对查询结果中的STATE字段进行字典转换,将数字转换为对应的中文描述 + return ViewMode.getInstance() // 创建一个ViewMode实例 + .putAttrs(EasyUiUtils.formatGridData(result)) // 使用EasyUiUtils工具类格式化查询结果,并将其放入ViewMode实例的属性中 + .returnObjMode(); // 返回格式化后的查询结果 + } catch (Exception e) { // 捕获可能发生的异常 + log.error(e.getMessage()); // 记录异常信息 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); // 创建一个ViewMode实例,并设置错误信息,返回错误信息 + } + } + + +/** + * 加载页面所有菜单 + * + * @return + */ +/** + * 查询所有菜单信息,并以JSON格式返回 + * + * @RequestMapping("/queryMenu") 定义了该方法处理的URL路径为/queryMenu + * @ResponseBody 注解表示该方法的返回值将直接作为HTTP响应体返回,而不是返回一个视图名称 + * @return Map 返回一个包含菜单信息的Map对象,格式化为EasyUI的grid数据格式 + */ +@RequestMapping("/queryMenu") +@ResponseBody +public Map loadAllMenu() { + try { + // 创建DataQuery实例,设置查询参数 + DataQuery query = DataQuery + .getInstance( + 1, + "ACT_TREE.NAME AS NAME, ACT_KEY.AUTHKEY AS SRCKEY, ACT_TREE.ID AS ID,ACT_TREE.PARENTID AS PARENTID", + "alone_auth_actiontree AS act_tree left join alone_auth_action AS act_key on act_tree.ACTIONID=act_key.ID"); + // 设置每页大小为100 + query.setPagesize(100); + // 使用ViewMode实例封装查询结果,并格式化为EasyUI的grid数据格式 + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(query.search())) + .returnObjMode(); + } catch (Exception e) { + // 捕获异常并记录日志 + log.error(e.getMessage()); + // 返回错误信息 + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } +} + + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") // 映射HTTP请求路径为"/edit",处理该路径下的请求 + @ResponseBody // 表示该方法的返回值直接写入HTTP响应体中,而不是返回一个视图 + public Map editSubmit(Actiontree entity, Action action, HttpSession session) { + try { + // 调用actionServiceImpl的editActiontreeEntity方法,传入entity对象、当前用户和action的authkey + // getCurrentUser(session)方法用于从session中获取当前用户信息 + entity = actionServiceImpl.editActiontreeEntity(entity, getCurrentUser(session), action.getAuthkey()); + + // 创建一个ViewMode实例,并将编辑后的entity对象放入其中,然后返回一个包含该entity的Map对象 + return ViewMode.getInstance().putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + // 如果发生异常,记录错误日志 + log.error(e.getMessage()); + + // 创建一个ViewMode实例,并设置错误信息,然后返回一个包含错误信息的Map对象 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + + /** + * 提交新增数据 + * + * @param entity + * 表单 + * @param authkey + * 权限uri + * @param session + * @return + */ + @RequestMapping("/add") // 映射URL路径为/add的请求到此方法 + @ResponseBody // 表示该方法的返回值直接写入HTTP响应体中,而不是返回一个视图 + public Map addSubmit(Actiontree entity, String authkey, HttpSession session) { + try { + // 调用actionServiceImpl的insertActiontreeEntity方法插入新的Actiontree实体 + // getCurrentUser(session)方法用于从session中获取当前用户信息 + entity = actionServiceImpl.insertActiontreeEntity(entity, getCurrentUser(session), authkey); + // 使用ViewMode工具类创建一个Map对象,并将插入后的entity对象放入其中,然后返回这个Map对象 + return ViewMode.getInstance().putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + // 如果发生异常,记录错误日志 + log.error(e.getMessage()); + // 使用ViewMode工具类创建一个Map对象,并将错误信息放入其中,然后返回这个Map对象 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + +/** + * 删除数据 + * + * @return + */ +@RequestMapping("/del") // 将HTTP请求路径为"/del"的请求映射到此方法上[[13, 14, 23]] +@ResponseBody // 表示该方法的返回值直接写入HTTP响应体中,而不是返回一个视图[[13, 14, 23]] +public Map delSubmit(String ids, HttpSession session) { // 定义处理方法,接收两个参数:ids(字符串类型)和session(HttpSession类型) + try { + for (String id : parseIds(ids)) { // 解析ids字符串,将其拆分为多个id,并遍历每个id + actionServiceImpl.deleteActiontreeEntity(id, getCurrentUser(session)); // 调用actionServiceImpl的deleteActiontreeEntity方法,传入id和当前用户对象,删除对应的实体 + } + return ViewMode.getInstance().returnObjMode(); // 如果删除成功,返回一个成功的响应对象 + } catch (Exception e) { // 捕获所有异常 + log.error(e.getMessage()); // 记录错误日志 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); // 返回一个包含错误信息的响应对象 + } +} + + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String domain, String ids, String parentid) { + // 创建一个ViewMode实例,用于封装视图和模型数据 + ViewMode mode = ViewMode.getInstance(); + try { + // 初始化Actiontree对象,用于存储父节点信息 + Actiontree parent = new Actiontree(); + // 初始化Actiontree对象,用于存储当前实体信息 + Actiontree entity = null; + + // 根据pageset的operateType字段判断操作类型 + switch (pageset.getOperateType()) { + case (1): { // 新增操作 + // 新增操作的具体逻辑(此处为空,可能需要后续实现) + break; + } + case (0): { // 展示操作 + // 根据ids获取Actiontree实体,并将其放入mode中 + entity = actionServiceImpl.getActiontreeEntity(ids); + mode.putAttr("entity", entity); + break; + } + case (2): { // 修改操作 + // 根据ids获取Actiontree实体,并将其放入mode中 + entity = actionServiceImpl.getActiontreeEntity(ids); + mode.putAttr("entity", entity); + break; + } + default: + // 默认情况,无操作 + break; + } + + // 如果parentid不为空,则获取父节点信息并放入mode中 + if (parentid != null && parentid.trim().length() > 0) { + parent = actionServiceImpl.getActiontreeEntity(parentid); + mode.putAttr("parent", parent); + } + + // 如果entity不为空且actionid不为空,则获取对应的Action实体并放入mode中 + if (entity != null && entity.getActionid() != null) { + Action treeAction = actionServiceImpl.getActionEntity(entity.getActionid()); + mode.putAttr("treeAction", treeAction); + } + } catch (Exception e) { + // 捕获异常并设置错误信息,返回错误视图 + return ViewMode.getInstance().setError(e.getMessage(), e).returnModelAndView("authority/ActiontreeForm"); + } + // 将pageset和domain信息放入mode中,并返回视图 + return mode.putAttr("pageset", pageset).putAttr("domain", domain) + .returnModelAndView("authority/ActiontreeForm"); + } + + + + /** + * 移动节点 + * + * @return + */ + @RequestMapping("/move") + @ResponseBody + public Map moveTreeNodeSubmit(String oid, String deid) { + // 尝试移动树节点 + try { + // 调用服务层的moveActionTreeNode方法,传入原始节点ID(oid)和目标节点ID(deid) + actionServiceImpl.moveActionTreeNode(oid, deid); + // 移动成功,返回包含操作结果的Map对象 + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + // 如果在移动过程中发生异常,记录错误日志 + log.error(e.getMessage()); + // 设置错误信息并返回包含错误信息的Map对象 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 加载子节点 + * + * @param id + * @param domain + * @return + */ + @RequestMapping("/loadtree") + @ResponseBody + public List loadTreeNode(String id, String domain) { + // 尝试加载树节点 + try { + // 调用服务层的getSyncTree方法,传入节点ID和域名,获取同步的树节点列表 + return actionServiceImpl.getSyncTree(id, domain); + } catch (Exception e) { + // 如果在加载过程中发生异常,记录错误日志 + log.error(e.getMessage()); + // 返回一个空的树节点列表 + return new ArrayList(); + } + } + + +/** + * 加载树节点根据用户权限 + * + * @return + */ +@RequestMapping("/cuserMenus") +@ResponseBody +public Object loadTreeNodeForCurrentUser(String id, String domain, HttpSession session) { + // 尝试为当前用户加载树节点菜单 + try { + // 查询第一级树节点菜单,包括名称、排序、ID、父ID、图标、URL和参数 + List> list1 = EasyUiTreeNode + .queryTreeNodeOne( + id, + "SORT", + "(SELECT c.NAME AS NAME, SORT, c.ID AS ID, PARENTID, ICON, b.AUTHKEY AS URL, c.PARAMS AS PARAM, domain FROM alone_auth_actiontree c LEFT JOIN alone_auth_action b ON c.ACTIONID = b.ID)", + "ID", "PARENTID", "NAME", "ICON", + "and a.DOMAIN='" + domain + "'", "URL,PARAM") + .getResultList(); + // 查询第二级树节点菜单,包括ID、父ID、名称、图标 + List> list2 = EasyUiTreeNode.queryTreeNodeTow( + id, "SORT", "alone_auth_actiontree", "ID", "PARENTID", + "NAME", "ICON", "and a.DOMAIN='" + domain + "'") + .getResultList(); + // 格式化异步加载的树节点菜单,结合当前用户的菜单权限 + return EasyUiTreeNode.formatAsyncAjaxTreeForMenuTree(list1, list2, + "PARENTID", "ID", "NAME", "ICON", "URL", "PARAM", + getCurrentUserMenus(session)); + } catch (Exception e) { + // 如果在加载过程中发生异常,记录错误日志 + log.error(e.getMessage()); + // 返回包含错误信息的对象 + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } +} + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/controller/OrganizationController.java b/src/wcp-authority/src/main/java/com/farm/authority/controller/OrganizationController.java new file mode 100644 index 0000000..7eee8cd --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/controller/OrganizationController.java @@ -0,0 +1,567 @@ +package com.farm.authority.controller; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.authority.AuthUtils; +import com.farm.authority.domain.Organization; +import com.farm.authority.service.OrganizationServiceInter; +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiTreeNode; +import com.farm.web.easyui.EasyUiUtils; + +/* * + *功能:组织机构控制层 + *详细: + * + * 版本:v0.1 + * @author zhaonaixia + * @time 2015-6-26 上午10:19:25 + * 说明: + */ +@RequestMapping("/organization") +@Controller +public class OrganizationController extends WebUtils { + // 定义日志记录器,用于记录日志信息 + private final static Logger log = Logger.getLogger(OrganizationController.class); + + // 注入OrganizationServiceInter的实现类,用于业务逻辑处理 + @Resource + OrganizationServiceInter organizationServiceImpl; + + // 获取OrganizationServiceInter实现类的实例 + public OrganizationServiceInter getOrganizationServiceImpl() { + return organizationServiceImpl; + } + + // 设置OrganizationServiceInter实现类的实例 + public void setOrganizationServiceImpl(OrganizationServiceInter organizationServiceImpl) { + this.organizationServiceImpl = organizationServiceImpl; + } +} + + + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") + @ResponseBody + public Map queryall(@ModelAttribute("query") DataQuery query, HttpServletRequest request) { + // 尝试执行查询操作 + try { + // 使用EasyUiUtils格式化查询条件,以便与EasyUI网格控件兼容 + query = EasyUiUtils.formatGridQuery(request, query); + // 如果没有查询规则,默认添加一个规则,查询PARENTID为"NONE"的记录 + if (query.getQueryRule().size() == 0) { + query.addRule(new DBRule("PARENTID", "NONE", "=")); + } + // 执行查询,获取数据结果 + DataResult result = organizationServiceImpl.createOrganizationSimpleQuery(query).search(); + // 对结果中的"STATE"字段进行字典转换,将状态码转换为可读的文本 + result.runDictionary("1:可用,0:禁用", "STATE"); + // 对结果中的"TYPE"字段进行字典转换,将类型码转换为可读的文本 + result.runDictionary("1:标准", "TYPE"); + // 将格式化后的数据结果放入ViewMode实例中,并返回JSON格式的响应 + return ViewMode.getInstance().putAttrs(EasyUiUtils.formatGridData(result)).returnObjMode(); + } catch (Exception e) { + // 捕获并记录异常信息 + log.error(e.getMessage()); + // 设置错误信息并返回JSON格式的响应 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + +/** + * 进入组织机构管理界面 + * + * @param session + * @return + */ + +@RequestMapping("/list") +public ModelAndView index(HttpSession session) { + // 获取ViewMode实例,用于封装视图和模型数据 + // 返回名为"authority/OrganizationResult"的视图,不包含任何模型数据 + return ViewMode.getInstance().returnModelAndView("authority/OrganizationResult"); +} + + +/** + * 进入组织机构管理界面 + * + * @param session + * @return + */ +@RequestMapping("/chooseOrg") +public ModelAndView chooseOrg(HttpSession session) { + // 获取ViewMode实例,用于封装视图和模型数据 + // 返回名为"authority/ChooseOrgResult"的视图,不包含任何模型数据 + return ViewMode.getInstance().returnModelAndView("authority/ChooseOrgResult"); +} + + +/** + * 组织机构tabs + * + * @param session + * @return + */ +@RequestMapping("/organizationTabs") +public ModelAndView orgTabs(RequestMode pageset, String ids, String parentID) { + // 根据操作类型返回不同的视图模型 + if (pageset.getOperateType() == 1) { + // 如果操作类型为1(通常表示新增操作) + // 设置pageset和parentId属性,并返回"authority/OrganizationTabs"视图 + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("parentId", parentID) + .returnModelAndView("authority/OrganizationTabs"); + } else { + // 如果操作类型不是1(通常表示编辑或查看操作) + // 根据提供的ids获取Organization实体 + Organization entity = organizationServiceImpl.getOrganizationEntity(ids); + // 设置pageset、entity、parentId和ids属性,并返回"authority/OrganizationTabs"视图 + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("entity", entity) + .putAttr("parentId", entity.getParentid()).putAttr("ids", ids) + .returnModelAndView("authority/OrganizationTabs"); + } +} + + +/** + * 岗位管理tabs + * + * @param session + * @return + */ + import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +/** + * 处理设置岗位权限标签页的请求 + * + * @param pageset 分页参数对象,包含了分页的相关信息,如当前页码、每页显示的记录数等。 + * 这些信息用于在岗位权限设置界面中实现分页显示。 + * @param ids 岗位ID字符串,可能包含了多个岗位的ID,用于指定需要设置权限的岗位。 + * 这些ID可以是逗号分隔的字符串,表示多个岗位。 + * @return 返回一个ModelAndView对象,该对象包含了视图名称和需要传递给视图的模型数据。 + * 视图名称"authority/PostResult"指定了用于显示岗位权限设置结果的JSP页面。 + * 模型数据中包含了分页参数对象pageset,以便在视图中使用分页信息。 + */ +@RequestMapping("/postConsoleTabs") +public ModelAndView postConsoleTabs(RequestMode pageset, String ids) { + // 使用ViewMode单例获取一个实例,然后添加属性pageset到模型中 + // 最后指定返回的视图名称为"authority/PostResult",并返回ModelAndView对象 + return ViewMode.getInstance().putAttr("pageset", pageset).returnModelAndView("authority/PostResult"); +} + + /** + * 设置岗位权限tabs + * + * @param session + * @return + */ + @RequestMapping("/postActionsTabs") + public ModelAndView postActionsTabs(RequestMode pageset, String ids) { + // 创建一个ModelAndView对象,并设置视图名称为"authority/OrgUserResult" + ModelAndView modelAndView = ViewMode.getInstance().putAttr("pageset", pageset).returnModelAndView("authority/OrgUserResult"); + + // 返回ModelAndView对象,该对象包含了视图信息和模型数据 + return modelAndView; + } + + +/** + * 移动节点 + * + * @return + */ +@RequestMapping("/OrgTreeNodeSubmit") +@ResponseBody +public Object moveTreeNodeSubmit(String ids, String id) { + try { + // 调用组织结构服务实现类的moveOrgTreeNode方法,移动组织树节点 + organizationServiceImpl.moveOrgTreeNode(ids, id); + // 返回成功响应对象 + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + // 打印堆栈跟踪信息 + e.printStackTrace(); + // 记录错误日志 + log.error(e.getMessage()); + // 返回错误响应对象,包含错误信息 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } +} + + +/** + * 提交修改数据 + * + * @return + */ +@RequestMapping("/edit") // 映射HTTP请求路径为"/edit" +@ResponseBody // 表示返回的结果直接写入HTTP响应体中,而不是返回一个视图 +public Map editSubmit(Organization org, HttpSession session) { // 定义一个处理POST请求的方法,接收Organization对象和HttpSession对象 + try { + // 调用organizationServiceImpl的editOrganizationEntity方法编辑组织实体,并传入当前用户信息 + Organization entity = organizationServiceImpl.editOrganizationEntity(org, getCurrentUser(session)); + // 创建一个ViewMode对象,设置操作类型为ADD,并将编辑后的实体放入属性中,最后返回一个Map对象 + return ViewMode.getInstance().setOperate(OperateType.ADD).putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + // 捕获异常并打印堆栈信息 + e.printStackTrace(); + // 记录错误日志 + log.error(e.getMessage()); + // 创建一个ViewMode对象,设置操作类型为ADD,并将错误信息放入属性中,最后返回一个Map对象 + return ViewMode.getInstance().setOperate(OperateType.ADD).setError(e.getMessage()).returnObjMode(); + } +} + + +/** + * 提交新增数据 + * + * @return + */ +@RequestMapping("/add") // 映射HTTP请求路径为"/add",即当客户端访问该路径时,会调用此方法 +@ResponseBody // 表示该方法的返回值直接作为HTTP响应体返回,而不是返回一个视图 +public Map addSubmit(Organization org, HttpSession session) { // 定义方法addSubmit,接收一个Organization对象和一个HttpSession对象作为参数 + try { + // 调用organizationServiceImpl的insertOrganizationEntity方法插入组织实体,并传入当前用户信息 + Organization entity = organizationServiceImpl.insertOrganizationEntity(org, getCurrentUser(session)); + // 创建一个ViewMode对象,设置操作类型为ADD,并将插入的实体对象放入属性中,最后返回一个Map对象 + return ViewMode.getInstance().setOperate(OperateType.ADD).putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { // 捕获所有异常 + e.printStackTrace(); // 打印堆栈跟踪信息 + log.error(e.getMessage()); // 记录错误日志 + // 创建一个ViewMode对象,设置操作类型为ADD,并将错误信息放入属性中,最后返回一个Map对象 + return ViewMode.getInstance().setOperate(OperateType.ADD).setError(e.getMessage()).returnObjMode(); + } +} + + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") // 映射URL路径为"/del"的请求到此方法 + @ResponseBody // 表示该方法的返回值直接写入HTTP响应体中,而不是返回一个视图 + public ModelAndView delSubmit(String ids, HttpSession session) { // 定义方法delSubmit,接收两个参数:ids(字符串类型)和session(HttpSession类型) + try { + for (String id : parseIds(ids)) { // 将ids字符串解析为多个id,并遍历每个id + organizationServiceImpl.deleteOrganizationEntity(id, getCurrentUser(session)); // 调用organizationServiceImpl的deleteOrganizationEntity方法,删除指定id的组织实体,并传入当前用户信息 + } + return ViewMode.getInstance().returnModelAndView("authority/OrganizationResult"); // 如果删除成功,返回一个ModelAndView对象,视图名为"authority/OrganizationResult" + } catch (Exception e) { // 捕获所有异常 + e.printStackTrace(); // 打印异常堆栈信息 + log.error(e.getMessage()); // 记录错误日志 + return ViewMode.getInstance().setError(e.getMessage()).returnModelAndView("authority/OrganizationResult"); // 返回一个包含错误信息的ModelAndView对象,视图名为"authority/OrganizationResult" + } + } + + + /** + * 移除岗位的用户 + * + * @return + */ + @RequestMapping("/removePostUser") + @ResponseBody + public ModelAndView removePostUserSubmit(String id, String ids, HttpSession session) { + try { + // 调用组织服务实现类的removePostUsers方法,传入岗位ID、用户ID列表和当前用户信息 + organizationServiceImpl.removePostUsers(id, ids, getCurrentUser(session)); + // 返回一个ModelAndView对象,视图名为"authority/OrgUserResult" + return ViewMode.getInstance().returnModelAndView("authority/OrgUserResult"); + } catch (Exception e) { + // 打印堆栈跟踪信息 + e.printStackTrace(); + // 记录错误日志 + log.error(e.getMessage()); + // 设置错误信息并返回一个ModelAndView对象,视图名为"authority/OrgUserResult" + return ViewMode.getInstance().setError(e.getMessage()).returnModelAndView("authority/OrgUserResult"); + } + } + + +/** + * 跳转 + * + * @return + */ +@RequestMapping("/orgTreeNodeTreeView") +public ModelAndView forSend(String ids) { + // 创建一个ModelAndView实例,并将参数ids添加到模型中 + return ViewMode.getInstance().putAttr("ids", ids) + // 设置视图名称为"authority/OrganizationTreenodeChooseTreeWin" + .returnModelAndView("authority/OrganizationTreenodeChooseTreeWin"); +} + + +/** + * 跳转到组织机构tree页面 + * + * @return + */ +@RequestMapping("/userORGTreeView") +public ModelAndView userOrgTree(String ids) { + // 创建一个ModelAndView对象,并设置视图名称为"authority/UserorgChooseTreeWin" + return ViewMode.getInstance().putAttr("ids", ids).returnModelAndView("authority/UserorgChooseTreeWin"); +} + + +/** + * 增加用户岗位 + * + * @return + */ +@RequestMapping("/userOrg") // 将HTTP请求映射到/userOrg路径,该方法处理此路径的请求[[4, 6, 13]] +@ResponseBody // 表示该方法的返回值直接写入HTTP响应体中,而不是返回一个视图[[27]] +public Object userORGSubmit(RequestMode pageset, String ids, String id, HttpSession session) { + try { + for (String userId : parseIds(ids)) { // 解析传入的ids字符串,将其转换为用户ID列表 + organizationServiceImpl.addUserPost(userId, id, getCurrentUser(session)); // 为每个用户ID添加岗位信息,使用当前用户的会话信息 + } + return ViewMode.getInstance().returnObjMode(); // 返回一个成功的响应对象 + } catch (Exception e) { + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); // 如果发生异常,返回一个包含错误信息的响应对象 + } +} + + +/** + * 加载选择岗位树 + * + * @return + */ +/** + * 映射到 "/postTree" 路径的 HTTP 请求处理方法。 + * 使用 @ResponseBody 注解,表示返回的对象将作为 HTTP 响应正文返回,而不是视图名称。 + * + * @param id 传入的参数,表示树的节点ID,用于加载特定组织结构下的岗位树。 + * @return 返回 Object 类型,具体由 organizationServiceImpl 的 loadPostTree 方法决定, + * 通常是一个表示岗位树的 JSON 对象。 + */ +@RequestMapping("/postTree") +@ResponseBody +public Object userORGLoadTree(String id) { + // 调用 organizationServiceImpl 的 loadPostTree 方法,传入 id 参数, + // 获取岗位树数据,并直接返回给客户端。 + return organizationServiceImpl.loadPostTree(id); +} + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ +/** + * 处理 "/form" 路径的 HTTP 请求,用于展示、新增或修改组织信息。 + * + * @param pageset 请求模式对象,包含操作类型等信息。 + * @param ids 组织的ID,用于查询特定组织信息。 + * @param parentId 父组织的ID,用于查询父组织信息。 + * @return 返回 ModelAndView 对象,包含视图名称和模型数据。 + */ +@RequestMapping("/form") +public ModelAndView view(RequestMode pageset, String ids, String parentId) { + try { + // 初始化父组织对象 + Organization parent = null; + + // 如果父组织ID不为空,查询父组织信息 + if (!parentId.equals("") && parentId != null) { + parent = organizationServiceImpl.getOrganizationEntity(parentId); + } + + // 根据操作类型执行不同逻辑 + switch (pageset.getOperateType()) { + case (1): { // 新增操作 + // 设置页面属性和父组织信息,返回新增组织信息的视图 + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("parent", parent) + .returnModelAndView("authority/OrganizationForm"); + } + case (0): { // 展示操作 + // 查询指定ID的组织信息 + Organization entity = organizationServiceImpl.getOrganizationEntity(ids); + // 设置页面属性、组织信息和父组织信息,返回展示组织信息的视图 + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("entity", entity) + .putAttr("parent", parent).returnModelAndView("authority/OrganizationForm"); + } + case (2): { // 修改操作 + // 查询指定ID的组织信息 + Organization entity = organizationServiceImpl.getOrganizationEntity(ids); + // 设置页面属性、组织信息和父组织信息,返回修改组织信息的视图 + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("entity", entity) + .putAttr("parent", parent).returnModelAndView("authority/OrganizationForm"); + } + } + } catch (Exception e) { + // 处理异常,设置错误信息,返回组织信息表单视图 + return ViewMode.getInstance().setError(e + e.getMessage()).returnModelAndView("authority/OrganizationForm"); + } + // 默认返回组织信息表单视图 + return ViewMode.getInstance().returnModelAndView("authority/OrganizationForm"); +} + + + /** + * 组织机构节点 + */ +/** + * 处理 "/organizationTree" 路径的 HTTP 请求,用于异步加载组织结构树节点。 + * + * @param id 传入的参数,表示树的节点ID,用于加载特定组织结构下的子节点。 + * @return 返回 Object 类型,通常是一个表示树节点的 JSON 对象。 + */ +@RequestMapping("/organizationTree") +@ResponseBody +public Object loadTreeNode(String id) { + // 如果传入的ID为null,则将其设置为"NONE",可能表示加载根节点 + if (id == null) { + id = "NONE"; + } + try { + // 查询一级子节点和二级子节点,并格式化为EasyUiTreeNode对象列表 + // queryTreeNodeOne 和 queryTreeNodeTow 方法分别查询一级和二级子节点 + // "SORT", "alone_auth_organization", "ID", "PARENTID", "NAME", "CTIME" 是查询用的参数 + return EasyUiTreeNode + .formatAsyncAjaxTree( + EasyUiTreeNode.queryTreeNodeOne(id, "SORT", "alone_auth_organization", "ID", "PARENTID", + "NAME", "CTIME").getResultList(), + EasyUiTreeNode + .queryTreeNodeTow(id, "SORT", "alone_auth_organization", "ID", "PARENTID", "NAME", "CTIME") + .getResultList(), "PARENTID", "ID", "NAME", "CTIME"); + } catch (Exception e) { + // 如果发生异常,记录错误日志并返回包含错误信息的对象 + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } +} + + +/** + * 组织机构节点Auth + */ +/** + * 处理 "/organizationTreeAuth" 路径的 HTTP 请求,用于异步加载带权限验证的组织结构树节点。 + * + * @param id 传入的参数,表示树的节点ID,用于加载特定组织结构下的子节点。 + * @param session HttpSession对象,用于获取当前用户的会话信息。 + * @return 返回 Object 类型,通常是一个表示树节点的 JSON 对象。 + */ +@RequestMapping("/organizationTreeAuth") +@ResponseBody +public Object loadTreeNode(String id, HttpSession session) { + // 初始化权限标志为false + boolean authFlag = false; + // 从会话中获取当前组织信息 + Organization org = AuthUtils.getCurrentOrganization(session); + + // 如果传入的ID为null,则将其设置为"NONE",可能表示加载根节点 + if (id == null) { + id = "NONE"; + // 如果当前组织不为null,则设置权限标志为true,并使用当前组织的父ID作为节点ID + if (org != null) { + authFlag = true; + id = org.getParentid(); + } + } + // ...(省略后续代码,可能包含查询节点、格式化返回数据以及异常处理等逻辑) +} +// 创建查询对象 query1,用于查询一级树节点,带有权限验证 +DataQuery query1 = EasyUiTreeNode.queryTreeNodeOneAuth(id, "SORT", "alone_auth_organization", "ID", "PARENTID", + "NAME", "CTIME", null, null, authFlag); + +// 创建查询对象 query2,用于查询二级树节点,带有权限验证 +DataQuery query2 = EasyUiTreeNode.queryTreeNodeTowAuth(id, "SORT", "alone_auth_organization", "ID", "PARENTID", + "NAME", "CTIME", null, authFlag); + +// 如果当前组织信息不为空,则为查询添加权限规则 +if (org != null) { + // 为 query1 添加规则,只查询树编码与当前组织树编码匹配的节点 + query1.addRule(new DBRule("treecode", AuthUtils.getCurrentOrganization(session).getTreecode(), "like-")); + // 为 query2 添加规则,只查询树编码与当前组织树编码匹配的节点 + query2.addRule(new DBRule("b.treecode", AuthUtils.getCurrentOrganization(session).getTreecode(), "like-")); + } + +// 尝试执行查询并格式化结果为异步加载的树节点 + try { + // 执行查询,获取一级和二级节点列表,然后格式化为 EasyUiTreeNode 对象列表 + return EasyUiTreeNode.formatAsyncAjaxTree(query1.search().getResultList(), query2.search().getResultList(), + "PARENTID", "ID", "NAME", "CTIME"); + } catch (Exception e) { + // 如果在查询或格式化过程中发生异常,记录错误日志 + log.error(e.getMessage()); + // 返回包含错误信息的 ViewMode 对象 + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); +} + + /** + * 返回树数据 v1.0 zhanghc 2015年9月6日下午1:58:25 + * + * @return List + */ + @RequestMapping("/loadTree") // 映射到 "/loadTree" 路径的 HTTP 请求 + @ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 + public List loadTree() { // 定义一个公共方法 loadTree,返回类型为 Organization 列表 + // 调用 organizationServiceImpl 的 getTree 方法,获取组织结构树 + // 并将获取到的树结构作为返回值,@ResponseBody 会将其转换为 JSON 等格式发送给客户端 + return organizationServiceImpl.getTree(); + } + // ---------------------------------------------------------------------------------- + + /** + * 获取岗位 v1.0 zhanghc 2015年9月6日下午2:43:50 + * + * @param orgId + * 机构ID + * @return List + */ + @RequestMapping("/loadPost") // 映射到 "/loadPost" 路径的 HTTP 请求 + @ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 + public List> loadPost(String orgId) { // 定义一个公共方法 loadPost,接收一个组织ID作为参数,返回类型为 Map 列表 + // 调用 organizationServiceImpl 的 getPostList 方法,传入组织ID(orgId),获取该组织下的岗位列表 + // 方法返回的岗位列表是一个 Map 类型的列表,每个 Map 对象代表一个岗位的信息 + // @ResponseBody 注解会自动将返回的列表转换为 JSON 等格式发送给客户端 + return organizationServiceImpl.getPostList(orgId); + } + + + /** + * 获取岗位,带父机构可用的岗位 v1.0 zhanghc 2015年9月7日下午1:48:14 + * + * @param orgId + * @return List> + */ + @RequestMapping("/loadPostWithPOrgPost") // 映射到 "/loadPostWithPOrgPost" 路径的 HTTP 请求 + @ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 + public List> loadPostWithPOrgPost(String orgId) { // 定义一个公共方法 loadPostWithPOrgPost,接收一个组织ID作为参数,返回类型为 List> + // 调用 organizationServiceImpl 的 getPostListWithPOrgPost 方法,传入组织ID(orgId),获取该组织及其父组织下的岗位列表 + // 方法返回的岗位列表是一个 List> 类型的列表,每个 Map 对象代表一个岗位的信息 + // @ResponseBody 注解会自动将返回的列表转换为 JSON 等格式发送给客户端 + return organizationServiceImpl.getPostListWithPOrgPost(orgId); + } + + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/controller/PostController.java b/src/wcp-authority/src/main/java/com/farm/authority/controller/PostController.java new file mode 100644 index 0000000..2c90050 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/controller/PostController.java @@ -0,0 +1,382 @@ +package com.farm.authority.controller; + +import java.util.List; +import java.util.Map; + +import com.farm.authority.domain.Organization; +import com.farm.authority.domain.Post; +import com.farm.authority.service.OrganizationServiceInter; + + + + + +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiTreeNode; +import com.farm.web.easyui.EasyUiUtils; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + + +/* * + *功能:岗位控制层 + *详细: + * + * 版本:v0.1 + * @author zhaonaixia + * @time 2015-6-26 上午10:19:25 + * 说明: + */ +@RequestMapping("/post") // 映射类级别的请求路径,所有该类的请求都以"/post"为前缀 +@Controller // 标识该类是一个Spring MVC的控制器 +public class PostController extends WebUtils { // 定义PostController类,继承自WebUtils类,用于处理与岗位相关的请求 + + private final static Logger log = Logger.getLogger(PostController.class); // 定义日志记录器,用于记录日志信息 + + @Resource // 注解用于自动注入OrganizationServiceInter类型的bean + OrganizationServiceInter organizationServiceImpl; // 声明OrganizationServiceInter接口的实例,用于业务逻辑处理 + + // Getter方法,用于获取organizationServiceImpl对象 + public OrganizationServiceInter getOrganizationServiceImpl() { + return organizationServiceImpl; + } + + // Setter方法,用于设置organizationServiceImpl对象 + public void setOrganizationServiceImpl( + OrganizationServiceInter organizationServiceImpl) { + this.organizationServiceImpl = organizationServiceImpl; + } +} + + + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") // 映射到 "/query" 路径的 HTTP 请求 + @ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 + public Map queryall( // 定义一个公共方法 queryall,用于处理查询请求 + @ModelAttribute("query") DataQuery query, // 通过 @ModelAttribute 注解绑定请求参数到 DataQuery 对象 + HttpServletRequest request, // 请求对象,用于获取请求信息 + String ids) { // 组织ID字符串,用于查询特定组织的岗位信息 + try { + query = EasyUiUtils.formatGridQuery(request, query); // 使用 EasyUiUtils 工具类格式化查询条件 + query.addRule(new DBRule("ORGANIZATIONID", ids, "=")); // 添加数据库查询规则,仅查询指定组织ID的岗位 + DataResult result = organizationServiceImpl.createPostSimpleQuery(query) // 调用服务层方法创建查询并执行 + .search(); // 执行查询 + result.runDictionary("0:否,1:是", "EXTENDIS"); // 对查询结果中的 "EXTENDIS" 字段进行字典转换,将数字转换为文字 + return ViewMode.getInstance() // 获取 ViewMode 实例 + .putAttrs(EasyUiUtils.formatGridData(result)) // 将格式化后的查询结果放入 ViewMode + .returnObjMode(); // 返回封装好的对象模式 + } catch (Exception e) { // 捕获异常 + log.error(e.getMessage()); // 记录错误日志 + return ViewMode.getInstance().setError(e.getMessage()) // 设置错误信息到 ViewMode + .returnObjMode(); // 返回包含错误信息的对象模式 + } + } + +/** + * 进入机构用户页面 + * @param session + * @return + */ +@RequestMapping("/chooseUser") // 映射到 "/chooseUser" 路径的 HTTP 请求 +public ModelAndView chooseUser(HttpSession session) { // 定义一个公共方法 chooseUser,用于处理选择用户的请求 + // 不需要使用 session 参数,但保留以符合方法签名 + // 返回一个 ModelAndView 对象,该对象包含视图名称 "authority/ChooseUserResult" + // 这个视图通常用于展示选择用户的结果或提供一个用户选择界面 + return ViewMode.getInstance() + .returnModelAndView("authority/ChooseUserResult"); +} + + +/** + * 进入机构岗位页面 + * @param session + * @return + */ +@RequestMapping("/postActions") // 映射到 "/postActions" 路径的 HTTP 请求 +public ModelAndView postActions(HttpSession session, String ids) { // 定义一个公共方法 postActions,用于处理岗位动作设置的请求 + // 接收 HttpSession 对象,可能用于获取会话信息,但在此方法中未直接使用 + // 接收一个字符串参数 ids,通常表示岗位的ID或多个ID,用于后续操作 + + // 使用 ViewMode.getInstance() 获取 ViewMode 的实例 + // 调用 putAttr 方法将 ids 参数放入模型中,以便在视图中使用 + // 调用 returnModelAndView 方法返回一个 ModelAndView 对象,包含视图名称 "authority/PostActionsSeting" + // 这个视图通常用于展示和设置岗位相关的动作或权限 + return ViewMode.getInstance() + .putAttr("ids", ids) // 将 ids 参数添加到模型中,以便在视图中可以访问这个值 + .returnModelAndView("authority/PostActionsSeting"); // 指定返回的视图名称 +} + +// 这段代码定义了一个处理岗位动作设置的请求方法 postActions。 +// 方法接收一个 HttpSession 对象和岗位ID字符串(ids),然后将 ids 存入模型中, +// 并返回一个指向 "authority/PostActionsSeting" 视图的 ModelAndView 对象。 +// 这个视图将用于展示和设置与指定岗位ID相关的动作或权限。 + +/** + * 提交修改数据 + * + * @return + */ +@RequestMapping("/edit") // 映射到 "/edit" 路径的 HTTP 请求 +@ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 +public Map editSubmit(Post org, HttpSession session) { // 定义一个公共方法 editSubmit,用于处理编辑岗位信息的提交请求 + // 参数 Post org 包含了从前端传递过来的岗位信息 + // 参数 HttpSession session 用于获取当前用户的会话信息 + + try { + // 调用 organizationServiceImpl 的 editPost 方法来编辑岗位信息 + // 参数包括岗位ID、岗位名称、扩展信息以及当前用户信息 + Post entity = organizationServiceImpl.editPost(org.getId(), org.getName(), + org.getExtendis(), getCurrentUser(session)); + + // 使用 ViewMode.getInstance() 获取 ViewMode 的实例 + // 设置操作类型为 ADD(可能是一个误导,实际应该是 EDIT) + // 将编辑后的岗位实体放入模型中 + // 调用 returnObjMode 方法返回一个包含操作结果和实体信息的 Map 对象 + return ViewMode.getInstance().setOperate(OperateType.ADD) + .putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + // 捕获并打印异常堆栈信息 + e.printStackTrace(); + // 记录错误日志 + log.error(e.getMessage()); + // 返回一个包含错误信息的 ViewMode 对象,操作类型仍为 ADD(应改为 EDIT) + return ViewMode.getInstance().setOperate(OperateType.ADD) + .setError(e.getMessage()).returnObjMode(); + } +} // 方法结束 + +// 这段代码定义了一个处理编辑岗位信息提交的请求方法 editSubmit。 +// 方法尝试更新岗位信息,并在成功时返回更新后的岗位实体和操作结果。 +// 如果在处理过程中发生异常,方法将捕获异常、记录错误日志,并返回一个包含错误信息的 Map 对象。 +// 注意:操作类型使用了 OperateType.ADD,这可能是一个错误,因为实际操作是编辑(EDIT)。 + + +/** + * 提交新增数据 + * + * @return + */ +@RequestMapping("/add") // 映射到 "/add" 路径的 HTTP 请求 +@ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 +public Map addSubmit(Post org, HttpSession session, String ids) { // 定义一个公共方法 addSubmit,用于处理添加岗位信息的提交请求 + // 参数 Post org 包含了从前端传递过来的岗位信息 + // 参数 HttpSession session 用于获取当前用户的会话信息 + // 参数 String ids 可能表示关联的父组织ID或其他标识 + + try { + // 调用 organizationServiceImpl 的 insertPost 方法来添加新的岗位信息 + // 参数包括关联的ID、岗位名称、扩展信息以及当前用户信息 + Post entity = organizationServiceImpl.insertPost(ids, org.getName(), org.getExtendis(), getCurrentUser(session)); + + // 使用 ViewMode.getInstance() 获取 ViewMode 的实例 + // 设置操作类型为 ADD,表示这是一个添加操作 + // 将添加后的岗位实体放入返回的模型中 + // 返回包含操作结果和岗位实体的 Map 对象 + return ViewMode.getInstance().setOperate(OperateType.ADD) + .putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + // 如果在处理过程中发生异常,打印异常堆栈信息 + e.printStackTrace(); + // 记录错误日志 + log.error(e.getMessage()); + // 返回一个包含错误信息的 Map 对象,操作类型仍为 ADD + return ViewMode.getInstance().setOperate(OperateType.ADD) + .setError(e.getMessage()).returnObjMode(); + } +} // 方法结束 + +// 这段代码定义了一个处理添加岗位信息提交的请求方法 addSubmit。 +// 方法尝试添加新的岗位信息,并在成功时返回新添加的岗位实体和操作结果。 +// 如果在处理过程中发生异常,方法将捕获异常、记录错误日志,并返回一个包含错误信息的 Map 对象。 + +/** + * 设置角色权限树 + * + * @return + */ + +@RequestMapping("/ALONEROLEGROUP_SYSBASE_SETTREE") // 映射到 "/ALONEROLEGROUP_SYSBASE_SETTREE" 路径的 HTTP 请求 +@ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 +public ModelAndView roleGroupSetTree(String ids, String id) { // 定义一个公共方法 roleGroupSetTree,用于处理角色组设置树形结构的请求 + // 参数 String ids 可能表示一系列动作或权限的ID,以某种分隔符分隔 + // 参数 String id 可能表示特定的岗位ID或角色组ID + + try { + List actions = parseIds(ids); // 调用 parseIds 方法将字符串 ids 解析为 List,可能按逗号或其他分隔符分割 + organizationServiceImpl.setPostActionTree(actions, id); // 调用 organizationServiceImpl 的 setPostActionTree 方法,设置岗位动作树 + // 参数 actions 是解析后的动作ID列表 + // 参数 id 是岗位或角色组的ID + + return ViewMode.getInstance() // 获取 ViewMode 实例 + .returnModelAndView("authority/PostActionsSeting"); // 设置返回的视图名称为 "authority/PostActionsSeting" 并返回 ModelAndView 对象 + } catch (Exception e) { // 捕获方法中可能抛出的任何异常 + e.printStackTrace(); // 打印异常的堆栈信息 + log.error(e.getMessage()); // 记录异常的错误信息到日志 + return ViewMode.getInstance() // 获取 ViewMode 实例 + .returnModelAndView("authority/PostActionsSeting"); // 即使发生异常,也返回相同的视图名称 "authority/PostActionsSeting" + } +} // 方法结束 + +// 这段代码定义了一个处理角色组设置树形结构的方法 roleGroupSetTree。 +// 方法尝试解析动作ID列表,并调用服务层的方法来设置岗位动作树。 +// 如果操作成功,将返回指定的视图;如果发生异常,将记录错误并返回相同 + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") // 映射到 "/del" 路径的 HTTP 请求,用于处理删除操作 + @ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 + public ModelAndView delSubmit(String ids, HttpSession session) { // 定义一个公共方法 delSubmit,用于处理删除岗位信息的提交请求 + // 参数 String ids 表示要删除的岗位ID,可能是一个或多个ID,以某种分隔符分隔 + // 参数 HttpSession session 用于获取当前用户的会话信息 + + try { + organizationServiceImpl.deletePostEntity(ids, getCurrentUser(session)); // 调用服务层的 deletePostEntity 方法,根据提供的ID删除岗位实体 + // getCurrentUser(session) 方法用于从会话中获取当前登录用户的信息 + return ViewMode.getInstance() // 获取 ViewMode 实例 + .returnModelAndView("authority/PostResult"); // 删除成功后,返回 "authority/PostResult" 视图名称的 ModelAndView 对象 + + } catch (Exception e) { // 捕获处理过程中可能发生的异常 + e.printStackTrace(); // 打印异常的堆栈信息 + log.error(e.getMessage()); // 记录错误日志 + return ViewMode.getInstance() // 获取 ViewMode 实例 + .setError(e.getMessage()) // 设置错误信息 + .returnModelAndView("authority/PostResult"); // 即使发生异常,也返回 "authority/PostResult" 视图名称的 ModelAndView 对象 + } + + } // 方法结束 + +// 这段代码定义了一个处理删除岗位信息的方法 delSubmit。 +// 方法接收要删除的岗位ID和用户会话信息,尝试调用服务层的方法进行删除操作。 +// 如果删除成功,返回相应的视图;如果发生异常,记录错误并返回相同的视图,同时携带错误信息。 + + +/** + * 构造岗位权限树 + * + * @return + */ +@RequestMapping("/ALONEMENU_RULEGROUP_TREENODE") // 映射到 "/ALONEMENU_RULEGROUP_TREENODE" 路径的 HTTP 请求,用于初始化角色组树节点 +@ResponseBody // 表示返回的结果将直接写入 HTTP 响应正文,而不是作为视图名称 +public Object postActionsTreeInit(DataQuery query, String ids) { // 定义一个公共方法 postActionsTreeInit,用于处理初始化角色组树节点的请求 + // 参数 DataQuery query 表示查询条件,用于筛选角色组数据 + // 参数 String ids 可能表示特定的角色组ID或相关标识,用于进一步筛选或定位数据 + + return EasyUiTreeNode.formatAjaxTree(initRoleGruopTreeNode(query, ids), // 调用 initRoleGruopTreeNode 方法初始化角色组树节点,并返回格式化后的树节点数据 + "A_PARENTID", // 父节点ID的字段名 + "A_ID", // 节点ID的字段名 + "A_NAME", // 节点显示名称的字段名 + "C_POSTID", // 可能表示与岗位相关联的ID字段名 + "A_ICON"); // 节点图标的字段名 +} + + +/** + * 查询菜单权限构造树形菜单 + * + * @return + */ +private List> initRoleGruopTreeNode(DataQuery query, String ids) { + // 初始化返回结果对象 + DataResult result = null; + try { + // 初始化查询对象,设置查询的表和连接条件,以及需要选择的字段 + query = DataQuery.init( + query, + "alone_auth_actiontree A LEFT JOIN alone_auth_action B ON A.ACTIONID = B.ID LEFT JOIN (SELECT POSTID, MENUID FROM alone_auth_postaction WHERE POSTID = '" + ids + "') C ON A.id = C.menuid", + "A.NAME,A.DOMAIN,a.ICON,A.ID,A.SORT,A.PARENTID,A.TREECODE,B.AUTHKEY,A.name as B_LABLE,A.TYPE,c.postid"); + // 设置查询结果不重复 + query.setDistinct(true); + // 设置查询的页面大小 + query.setPagesize(100); + // 添加排序条件 + query.addSort(new DBSort("a.DOMAIN,LENGTH(A.TREECODE),a.SORT", "ASC", false)); + // 设置不统计总记录数 + query.setNoCount(); + // 执行查询 + result = query.search(); + // 遍历查询结果,对每个节点进行格式化处理 + for (Map node : result.getResultList()) { + // 在节点名称后添加域名信息,用于显示 + node.put("A_NAME", node.get("A_NAME").toString() + "    " + + (node.get("A_DOMAIN").toString()).toUpperCase() + ""); + } + } catch (Exception e) { + // 捕获异常,设置错误信息到结果对象 + result = DataResult.setMessager(result, e + e.getMessage()); + // 记录错误日志 + log.error(e.getMessage() + e); + } + // 返回查询结果列表 + return result.getResultList(); +} + + +/** + * 显示详细信息(修改或浏览时) + * + * @return + */ +@RequestMapping("/form") // 映射到 "/form" 路径的 HTTP 请求 +public ModelAndView view(RequestMode pageset, String ids) { // 定义一个公共方法 view,接收请求模式和ID字符串作为参数 + // TODO 自动生成代码,修改后请去除本注释 // 提示开发者此部分代码为自动生成,需要手动修改后删除此注释 + try { + switch (pageset.getOperateType()) { // 根据操作类型进行分支处理 + case (1): { // 新增操作 + // 返回新增页面,并传递 pageset 和 ids 参数 + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("ids", ids) + .returnModelAndView("authority/PostForm"); + } + case (0): { // 展示操作 + Post entity = organizationServiceImpl.getPostEntity(ids); // 根据ID获取岗位实体 + // 返回展示页面,并传递 pageset 和 entity 参数 + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", entity) + .returnModelAndView("authority/PostForm"); + } + case (2): { // 修改操作 + Post entity = organizationServiceImpl.getPostEntity(ids); // 根据ID获取岗位实体 + // 返回修改页面,并传递 pageset 和 entity 参数 + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", entity) + .returnModelAndView("authority/PostForm"); + } + default: + break; // 默认情况,不执行任何操作 + } + } catch (Exception e) { // 捕获并处理异常 + e.printStackTrace(); // 打印异常堆栈信息 + log.error(e.getMessage()); // 记录错误日志 + // 返回错误页面,并传递错误信息 + return ViewMode.getInstance().setError(e + e.getMessage()) + .returnModelAndView("authority/OrganizationForm"); + } + // 如果没有匹配的操作类型或发生异常,返回组织机构表单页面 + return ViewMode.getInstance().returnModelAndView("authority/OrganizationForm"); +} + + +private static final long serialVersionUID = 1L; +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/controller/WebUserController.java b/src/wcp-authority/src/main/java/com/farm/authority/controller/WebUserController.java new file mode 100644 index 0000000..0674c95 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/controller/WebUserController.java @@ -0,0 +1,301 @@ +package com.farm.authority.controller; + +import com.farm.authority.domain.Organization; +import com.farm.authority.domain.Post; +import com.farm.authority.domain.User; +import com.farm.authority.service.UserServiceInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; + +/* * + *功能:用户控制层 + *详细: + * + * 版本:v0.1 + * @author zhaonaixia + * @time 2015-6-26 上午10:19:25 + * 说明: + */ +@RequestMapping("/user") +@Controller +public class WebUserController extends WebUtils { + private final static Logger log = Logger.getLogger(WebUserController.class); + @Resource + UserServiceInter userServiceImpl; + + public UserServiceInter getUserServiceImpl() { + return userServiceImpl; + } + + public void setUserServiceImpl(UserServiceInter userServiceImpl) { + this.userServiceImpl = userServiceImpl; + } + + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") + @ResponseBody + public Map queryall( + @ModelAttribute("query") DataQuery query, HttpServletRequest request,HttpSession session) { + try { + query = EasyUiUtils.formatGridQuery(request, query); + if (query.getQueryRule().size() <= 0) { + query.addRule(new DBRule("a.STATE", "1", "=")); + } + DataResult result = userServiceImpl.createUserSimpleQuery(query, getCurrentUser(session)) + .search(); + result.runDictionary("0:禁用,1:可用,2:删除", "STATE"); + result.runDictionary("1:系统用户,2:其他,3:超级用户", "TYPE"); + result.runformatTime("LOGINTIME", "yyyy-MM-dd HH:mm:ss"); + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(result)) + .returnObjMode(); + + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + /**进入用户管理界面 + * @param session + * @return + */ + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance() + .returnModelAndView("authority/UserResult"); + } + + /** + * 跳转到修改密码页面 + * + * @return + */ + @RequestMapping("/updatePassword") + public ModelAndView forSend(HttpSession session) { + return ViewMode.getInstance() + .returnModelAndView("frame/password"); + } + + /** + * 修改密码 + * + * @return + */ + @RequestMapping("LoginUser_PassWordUpdata") + @ResponseBody + public Object editPassword(HttpSession session,String passwordl,String passwordn1) { + try { + if (!userServiceImpl.editLoginPassword(getCurrentUser(session).getLoginname(), + passwordl, passwordn1)) { + throw new RuntimeException("密码修改失败!"); + } + return ViewMode.getInstance() + .returnObjMode(); + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance() + .setError(e.getMessage()) + .returnObjMode(); + } + } + + @RequestMapping("/organization") + public ModelAndView userOrgTree(HttpSession session,String ids) { + return ViewMode.getInstance() + .putAttr("ids", ids) + .returnModelAndView("authority/UserorgChooseTreeWin"); + } + + /** + * 查询组织机构用户结果集合 + * + * @return + */ + @RequestMapping("/orgUserQuery") + @ResponseBody + public Map queryOrgUser( + @ModelAttribute("query") DataQuery query, HttpServletRequest request,String ids) { + try { + query = EasyUiUtils.formatGridQuery(request, query); + query.addRule(new DBRule("ORG.ID", ids, "=")); + DataResult result = userServiceImpl.createUserPostQuery(query).search(); + result.runDictionary("0:禁用,1:可用,2:删除", "USERSTATE"); + result.runDictionary("1:标准岗位,2:临时岗位", "TYPE"); + result.runDictionary("0:禁用,1:可用,2:删除", "a.STATE"); + result.runformatTime("LOGINTIME", "yyyy-MM-dd HH:mm:ss"); + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(result)) + .returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(User user, HttpSession session, String orgId, String postIds) { + try { + User entity = userServiceImpl.insertUserEntity(user, + getCurrentUser(session), orgId, postIds); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .setError(e.getMessage()).returnObjMode(); + } + + + } + + /** + * 提交编辑数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(User user, HttpSession session, String orgId, String postIds) { + try { + User entity = userServiceImpl.editUserEntity(user, + getCurrentUser(session), orgId, postIds); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .setError(e.getMessage()).returnObjMode(); + } + + + } + + /** + * 删除选中单条数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public ModelAndView delSubmit(String ids, HttpSession session) { + try { + userServiceImpl.deleteUserEntity(ids, + getCurrentUser(session)); + return ViewMode.getInstance() + .returnModelAndView("authority/UserResult"); + + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance() + .setError(e.getMessage()) + .returnModelAndView("authority/UserResult"); + } + } + + /** + * 密码初始化 + * + * @return + */ + @RequestMapping("/init") + @ResponseBody + public ModelAndView initPassWord(String ids,HttpSession session) { + try { + userServiceImpl.initDefaultPassWord(ids, getCurrentUser(session)); + return ViewMode.getInstance() + .returnModelAndView("authority/UserResult"); + } catch (Exception e) { + return null; + } + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (1): {// 新增 + return ViewMode.getInstance().putAttr("pageset", pageset) + .returnModelAndView("authority/UserForm"); + } + case (0): {// 展示 + User entity = userServiceImpl.getUserEntity(ids); + List posts = userServiceImpl.getUserPosts(ids); + Organization organization = userServiceImpl + .getUserOrganization(ids); + return ViewMode.getInstance().putAttr("entity", entity) + .putAttr("posts", posts).putAttr("pageset", pageset) + .putAttr("organization", organization) + .returnModelAndView("authority/UserForm"); + } + case (2): {// 修改 + User entity = userServiceImpl.getUserEntity(ids); + Organization org = userServiceImpl.getOrg(entity.getId()); + List postList = userServiceImpl.getPost(entity.getId()); + String postIds = ""; + for(int i = 0; i < postList.size(); i ++){ + postIds += postList.get(i).getId(); + if(i < postList.size() - 1){ + postIds += ","; + } + } + return ViewMode.getInstance() + .putAttr("pageset", pageset) + .putAttr("entity", entity) + .putAttr("orgId", org==null?null:org.getId()) + .putAttr("postIds", postIds) + .returnModelAndView("authority/UserForm"); + } + default: + break; + } + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e + e.getMessage()) + .returnModelAndView("authority/UserForm"); + } + return ViewMode.getInstance().returnModelAndView("authority/UserForm"); + } + + private static final long serialVersionUID = 1L; +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/ActionDaoInter.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/ActionDaoInter.java new file mode 100644 index 0000000..f718ddb --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/ActionDaoInter.java @@ -0,0 +1,113 @@ +package com.farm.authority.dao; + +import com.farm.authority.domain.Action; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/* * + *功能:权限资源数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141119144919 + *说明: + */ +public interface ActionDaoInter { + /** + * 删除一个权限资源实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(Action action); + + /** + * 由权限资源id获得一个权限资源实体 + * + * @param id + * @return + */ + public Action getEntity(String actionid); + + /** + * 插入一条权限资源数据 + * + * @param entity + */ + public Action insertEntity(Action action); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个权限资源记录 + * + * @param entity + */ + public void editEntity(Action action); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条权限资源查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除权限资源实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询权限资源实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改权限资源实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 条件合计权限资源:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); + + /** + * @param authkey + * @return + */ + public Action getEntityByKey(String authkey); + + /** + * @return + */ + public List getAllEntity(); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/ActiontreeDaoInter.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/ActiontreeDaoInter.java new file mode 100644 index 0000000..b323507 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/ActiontreeDaoInter.java @@ -0,0 +1,110 @@ +package com.farm.authority.dao; + +import com.farm.authority.domain.Actiontree; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/* * + *功能:构造权限持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +public interface ActiontreeDaoInter { + /** + * 删除一个构造权限实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(Actiontree actiontree); + + /** + * 由构造权限id获得一个构造权限实体 + * + * @param id + * @return + */ + public Actiontree getEntity(String actiontreeid); + + /** + * 插入一条构造权限数据 + * + * @param entity + */ + public Actiontree insertEntity(Actiontree actiontree); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个构造权限记录 + * + * @param entity + */ + public void editEntity(Actiontree actiontree); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条构造权限查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除构造权限实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询构造权限实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改构造权限实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 条件合计构造权限:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); + + /** + * 获得所有子节点 + * + * @param treeNodeId + * @return + */ + public List getAllSubNodes(String treeNodeId); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/OrganizationDaoInter.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/OrganizationDaoInter.java new file mode 100644 index 0000000..ebe8df8 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/OrganizationDaoInter.java @@ -0,0 +1,110 @@ +package com.farm.authority.dao; + +import com.farm.authority.domain.Organization; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/* * + *功能:组织机构持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +public interface OrganizationDaoInter { + /** + * 删除一个组织机构实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(Organization organization); + + /** + * 由组织机构id获得一个组织机构实体 + * + * @param id + * @return + */ + public Organization getEntity(String organizationid); + + /** + * 插入一条组织机构数据 + * + * @param entity + */ + public Organization insertEntity(Organization organization); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个组织机构记录 + * + * @param entity + */ + public void editEntity(Organization organization); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条组织机构查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除组织机构实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询组织机构实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改组织机构实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 条件合计组织机构:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); + + /** + * 获得所有子节点 + * + * @param orgId + * @return + */ + public List getAllSubNodes(String orgId); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/PostDaoInter.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/PostDaoInter.java new file mode 100644 index 0000000..1513da3 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/PostDaoInter.java @@ -0,0 +1,82 @@ +package com.farm.authority.dao; + +import com.farm.authority.domain.Post; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + + +/* * + *功能:岗位数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141124152033 + *说明: + */ +public interface PostDaoInter { + /** 删除一个岗位实体 + * @param entity 实体 + */ + public void deleteEntity(Post post) ; + /** 由岗位id获得一个岗位实体 + * @param id + * @return + */ + public Post getEntity(String postid) ; + /** 插入一条岗位数据 + * @param entity + */ + public Post insertEntity(Post post); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个岗位记录 + * @param entity + */ + public void editEntity(Post post); + /**获得一个session + */ + public Session getSession(); + /**执行一条岗位查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除岗位实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询岗位实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改岗位实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + /** + * 条件合计岗位:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/PostactionDaoInter.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/PostactionDaoInter.java new file mode 100644 index 0000000..3119b49 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/PostactionDaoInter.java @@ -0,0 +1,82 @@ +package com.farm.authority.dao; + +import com.farm.authority.domain.Postaction; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + + +/* * + *功能:岗位权限数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141204174206 + *说明: + */ +public interface PostactionDaoInter { + /** 删除一个岗位权限实体 + * @param entity 实体 + */ + public void deleteEntity(Postaction postaction) ; + /** 由岗位权限id获得一个岗位权限实体 + * @param id + * @return + */ + public Postaction getEntity(String postactionid) ; + /** 插入一条岗位权限数据 + * @param entity + */ + public Postaction insertEntity(Postaction postaction); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个岗位权限记录 + * @param entity + */ + public void editEntity(Postaction postaction); + /**获得一个session + */ + public Session getSession(); + /**执行一条岗位权限查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除岗位权限实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询岗位权限实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改岗位权限实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + /** + * 条件合计岗位权限:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/UserDaoInter.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/UserDaoInter.java new file mode 100644 index 0000000..2f12d8e --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/UserDaoInter.java @@ -0,0 +1,108 @@ +package com.farm.authority.dao; + +import com.farm.authority.domain.User; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/* * + *功能:用户数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141119144919 + *说明: + */ +public interface UserDaoInter { + /** + * 删除一个用户实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(User user); + + /** + * 由用户id获得一个用户实体 + * + * @param id + * @return + */ + public User getEntity(String userid); + + /** + * 插入一条用户数据 + * + * @param entity + */ + public User insertEntity(User user); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个用户记录 + * + * @param entity + */ + public void editEntity(User user); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条用户查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除用户实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询用户实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改用户实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 条件合计用户:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); + + public List findUserByLoginName(String loginname); + + public List findUserByLoginName(String loginname, String userId); + + public Integer getUsersNum(); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/UserorgDaoInter.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/UserorgDaoInter.java new file mode 100644 index 0000000..611444e --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/UserorgDaoInter.java @@ -0,0 +1,107 @@ +package com.farm.authority.dao; + +import com.farm.authority.domain.Userorg; + +import org.hibernate.Session; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; + +import java.util.List; +import java.util.Map; + +/* * + *功能:置顶文档数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20150707114057 + *说明: + */ +public interface UserorgDaoInter { + /** + * 删除一个置顶文档实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(Userorg userorg); + + /** + * 由置顶文档id获得一个置顶文档实体 + * + * @param id + * @return + */ + public Userorg getEntity(String userorgid); + + /** + * 插入一条置顶文档数据 + * + * @param entity + */ + public Userorg insertEntity(Userorg userorg); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个置顶文档记录 + * + * @param entity + */ + public void editEntity(Userorg userorg); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条置顶文档查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除置顶文档实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询置顶文档实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改置顶文档实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 条件合计置顶文档:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); + + public Userorg getEntityByUserId(String id); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/UserpostDaoInter.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/UserpostDaoInter.java new file mode 100644 index 0000000..9ab4b93 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/UserpostDaoInter.java @@ -0,0 +1,115 @@ +package com.farm.authority.dao; + +import com.farm.authority.domain.Userpost; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/* * + *功能:用户岗位数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141204174206 + *说明: + */ +public interface UserpostDaoInter { + /** + * 删除一个用户岗位实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(Userpost userpost); + + /** + * 由用户岗位id获得一个用户岗位实体 + * + * @param id + * @return + */ + public Userpost getEntity(String userpostid); + + /** + * 插入一条用户岗位数据 + * + * @param entity + */ + public Userpost insertEntity(Userpost userpost); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个用户岗位记录 + * + * @param entity + */ + public void editEntity(Userpost userpost); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条用户岗位查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除用户岗位实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询用户岗位实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改用户岗位实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 条件合计用户岗位:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); + + /** + *获得用户所有的标准岗位 + * + * @param userId + */ + public List getStandardUserPost(String userId); + /** + *获得用户所有的临时岗位 + * + * @param userId + */ + public List getTempUserPost(String userId); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/ActionDaoImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/ActionDaoImpl.java new file mode 100644 index 0000000..934a415 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/ActionDaoImpl.java @@ -0,0 +1,155 @@ +package com.farm.authority.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.Query; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.authority.domain.Action; +import com.farm.authority.dao.ActionDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +/* * + *功能:权限资源持久层实现 + *详细: + * + *版本:v0.1 + *作者:王东 + *日期:20141119144919 + *说明: + */ +@Repository +public class ActionDaoImpl extends HibernateSQLTools implements + ActionDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Action action) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.delete(action); + } + + @Override + public int getAllListNum() { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_code_field"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public Action getEntity(String actionid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + return (Action) session.get(Action.class, actionid); + } + + @Override + public Action insertEntity(Action action) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.save(action); + return action; + } + + @Override + public void editEntity(Action action) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.update(action); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + + @Override + public DataResult runSqlQuery(DataQuery query) { + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + // TODO 自动生成代码,修改后请去除本注释 + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @SuppressWarnings("unchecked") + @Override + public Action getEntityByKey(String authkey) { + Session session = sessionFatory.getCurrentSession(); + Query sqlquery = session.createQuery(" from Action where authkey=?"); + sqlquery.setString(0, authkey); + List list = sqlquery.list(); + if (list.size() > 0) { + return list.get(0); + } + return null; + } + + @SuppressWarnings("unchecked") + @Override + public List getAllEntity() { + Session session = sessionFatory.getCurrentSession(); + Query sqlquery = session.createQuery(" from Action "); + return sqlquery.list(); + } + + @Override + protected Class getTypeClass() { + return Action.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/ActiontreeDaoImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/ActiontreeDaoImpl.java new file mode 100644 index 0000000..093e0e0 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/ActiontreeDaoImpl.java @@ -0,0 +1,144 @@ +package com.farm.authority.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.Query; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.authority.domain.Actiontree; +import com.farm.authority.dao.ActiontreeDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +/* * + *功能:构造权限持久层实现类 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +@Repository +public class ActiontreeDaoImpl extends HibernateSQLTools implements + ActiontreeDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Actiontree actiontree) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.delete(actiontree); + } + + @Override + public int getAllListNum() { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_code_field"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public Actiontree getEntity(String actiontreeid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + return (Actiontree) session.get(Actiontree.class, actiontreeid); + } + + @Override + public Actiontree insertEntity(Actiontree actiontree) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.save(actiontree); + return actiontree; + } + + @Override + public void editEntity(Actiontree actiontree) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.update(actiontree); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + + @Override + public DataResult runSqlQuery(DataQuery query) { + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + // TODO 自动生成代码,修改后请去除本注释 + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @SuppressWarnings("unchecked") + @Override + public List getAllSubNodes(String treeNodeId) { + Session session = sessionFatory.getCurrentSession(); + Query sqlquery = session + .createQuery(" from Actiontree where TREECODE like ? order by ctime "); + sqlquery.setString(0, getEntity(treeNodeId).getTreecode() + "%"); + return sqlquery.list(); + } + + @Override + protected Class getTypeClass() { + return Actiontree.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/OrganizationDaoImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/OrganizationDaoImpl.java new file mode 100644 index 0000000..43b39e0 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/OrganizationDaoImpl.java @@ -0,0 +1,143 @@ +package com.farm.authority.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.Query; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.authority.domain.Organization; +import com.farm.authority.dao.OrganizationDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +/* * + *功能:组织机构持久层实现类 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +@Repository +public class OrganizationDaoImpl extends HibernateSQLTools + implements OrganizationDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Organization organization) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.delete(organization); + } + + @Override + public int getAllListNum() { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_code_field"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public Organization getEntity(String organizationid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + return (Organization) session.get(Organization.class, organizationid); + } + + @Override + public Organization insertEntity(Organization organization) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.save(organization); + return organization; + } + + @Override + public void editEntity(Organization organization) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.update(organization); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + + @Override + public DataResult runSqlQuery(DataQuery query) { + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @SuppressWarnings("unchecked") + @Override + public List getAllSubNodes(String orgId) { + Session session = sessionFatory.getCurrentSession(); + Query sqlquery = session + .createQuery(" from Organization where TREECODE like ? order by ctime "); + sqlquery.setString(0, getEntity(orgId).getTreecode() + "%"); + return sqlquery.list(); + } + + @Override + protected Class getTypeClass() { + return Organization.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/PostDaoImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/PostDaoImpl.java new file mode 100644 index 0000000..f977052 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/PostDaoImpl.java @@ -0,0 +1,133 @@ +package com.farm.authority.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.authority.domain.Post; +import com.farm.authority.dao.PostDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +/* * + *功能:岗位持久层实现 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20141124152033 + *说明: + */ +@Repository +public class PostDaoImpl extends HibernateSQLTools implements + PostDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Post post) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.delete(post); + } + + @Override + public int getAllListNum() { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_code_field"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public Post getEntity(String postid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + return (Post) session.get(Post.class, postid); + } + + @Override + public Post insertEntity(Post post) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.save(post); + return post; + } + + @Override + public void editEntity(Post post) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.update(post); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + + @Override + public DataResult runSqlQuery(DataQuery query) { + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + // TODO 自动生成代码,修改后请去除本注释 + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + protected Class getTypeClass() { + return Post.class; + } + + @Override + protected SessionFactory getSessionFactory() { + // TODO Auto-generated method stub + return sessionFatory; + } +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/PostactionDaoImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/PostactionDaoImpl.java new file mode 100644 index 0000000..b3cd2c3 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/PostactionDaoImpl.java @@ -0,0 +1,134 @@ +package com.farm.authority.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.authority.domain.Postaction; +import com.farm.authority.dao.PostactionDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +/* * + *功能:岗位权限持久层实现 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20141204174206 + *说明: + */ +@Repository +public class PostactionDaoImpl extends HibernateSQLTools implements + PostactionDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Postaction postaction) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.delete(postaction); + } + + @Override + public int getAllListNum() { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_code_field"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public Postaction getEntity(String postactionid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + return (Postaction) session.get(Postaction.class, postactionid); + } + + @Override + public Postaction insertEntity(Postaction postaction) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.save(postaction); + return postaction; + } + + @Override + public void editEntity(Postaction postaction) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.update(postaction); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + + @Override + public DataResult runSqlQuery(DataQuery query) { + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + // TODO 自动生成代码,修改后请去除本注释 + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + protected Class getTypeClass() { + return Postaction.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserDaoImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserDaoImpl.java new file mode 100644 index 0000000..5bfd36d --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserDaoImpl.java @@ -0,0 +1,165 @@ +package com.farm.authority.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.Query; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.authority.domain.User; +import com.farm.authority.dao.UserDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.transaction.Transactional; + +/* * + *功能:用户持久层实现 + *详细: + * + *版本:v0.1 + *作者:王东 + *日期:20141119144919 + *说明: + */ +@Repository +public class UserDaoImpl extends HibernateSQLTools implements UserDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(User user) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.delete(user); + } + + @Override + public int getAllListNum() { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from farm_code_field"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public User getEntity(String userid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + return (User) session.get(User.class, userid); + } + + @Override + public User insertEntity(User user) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.save(user); + return user; + } + + @Override + public void editEntity(User user) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.update(user); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + + @Override + public DataResult runSqlQuery(DataQuery query) { + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + // TODO 自动生成代码,修改后请去除本注释 + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @SuppressWarnings("unchecked") + @Override + @Transactional + public List findUserByLoginName(String loginname) { + String hql = "from User a where a.loginname = ?"; + Session session = sessionFatory.getCurrentSession(); + Query query = session.createQuery(hql); + query.setString(0, loginname); + return query.list(); + } + + @SuppressWarnings("unchecked") + @Override + public List findUserByLoginName(String loginname, String userId) { + String hql = "from User a where a.loginname = ? and a.id!=?"; + Session session = sessionFatory.getCurrentSession(); + Query query = session.createQuery(hql); + query.setString(0, loginname); + query.setString(1, userId); + return query.list(); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + protected Class getTypeClass() { + return User.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + + @Override + public Integer getUsersNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from ALONE_AUTH_USER where STATE=1"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserorgDaoImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserorgDaoImpl.java new file mode 100644 index 0000000..e045601 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserorgDaoImpl.java @@ -0,0 +1,132 @@ +package com.farm.authority.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.Query; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import com.farm.authority.domain.Userorg; +import com.farm.authority.dao.UserorgDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Repository; + +import javax.annotation.Resource; + +/* * + *功能:置顶文档持久层实现 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Repository +public class UserorgDaoImpl extends HibernateSQLTools implements UserorgDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Userorg userorg) { + + Session session=sessionFatory.getCurrentSession(); + session.delete(userorg); + } + @Override + public int getAllListNum(){ + + Session session= sessionFatory.getCurrentSession(); + SQLQuery sqlquery= session.createSQLQuery("select count(*) from farm_code_field"); + BigInteger num=(BigInteger)sqlquery.list().get(0); + return num.intValue() ; + } + @Override + public Userorg getEntity(String userorgid) { + + Session session= sessionFatory.getCurrentSession(); + return (Userorg)session.get(Userorg.class, userorgid); + } + @Override + public Userorg insertEntity(Userorg userorg) { + + Session session= sessionFatory.getCurrentSession(); + session.save(userorg); + return userorg; + } + @Override + public void editEntity(Userorg userorg) { + + Session session= sessionFatory.getCurrentSession(); + session.update(userorg); + } + + @Override + public Session getSession() { + + return sessionFatory.getCurrentSession(); + } + @Override + public DataResult runSqlQuery(DataQuery query){ + + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + @Override + public void deleteEntitys(List rules) { + + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + @Override + protected Class getTypeClass() { + return Userorg.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + @Override + public Userorg getEntityByUserId(String id) { + Query query = getSession().createQuery("from UserOrg t where t.userid = ?"); + query.setString(0, id); + return (Userorg) query.uniqueResult(); + } +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserpostDaoImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserpostDaoImpl.java new file mode 100644 index 0000000..702af9f --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/dao/impl/UserpostDaoImpl.java @@ -0,0 +1,156 @@ +package com.farm.authority.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.authority.domain.Userpost; +import com.farm.authority.dao.UserpostDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.transaction.Transactional; + +/* * + *功能:用户岗位持久层实现 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20141204174206 + *说明: + */ +@Repository +public class UserpostDaoImpl extends HibernateSQLTools implements + UserpostDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Userpost userpost) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.delete(userpost); + } + + @Override + public int getAllListNum() { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_code_field"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public Userpost getEntity(String userpostid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + return (Userpost) session.get(Userpost.class, userpostid); + } + + @Override + public Userpost insertEntity(Userpost userpost) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.save(userpost); + return userpost; + } + + @Override + public void editEntity(Userpost userpost) { + // TODO 自动生成代码,修改后请去除本注释 + Session session = sessionFatory.getCurrentSession(); + session.update(userpost); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + + @Override + public DataResult runSqlQuery(DataQuery query) { + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @SuppressWarnings("unchecked") + @Override + @Deprecated + public List getStandardUserPost(String userId) { +// Session session = sessionFatory.getCurrentSession(); +// SQLQuery sqlquery = session +// .createSQLQuery("SELECT a.USERID as userid,a.ID as id,a.ORGANIZATIONID as organizationid,a.POSTID as postid FROM alone_auth_userorgpost a LEFT JOIN alone_auth_post b ON a.POSTID=b.ID WHERE b.TYPE='1' and a.USERID=?"); +// sqlquery.setString(0, userId); +// sqlquery.addEntity(Userpost.class); +// return sqlquery.list(); + return null; + } + + @SuppressWarnings("unchecked") + @Override + @Transactional + public List getTempUserPost(String userId) { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("SELECT a.USERID as userid,a.ID as id,a.ORGANIZATIONID as organizationid,a.POSTID as postid FROM alone_auth_userorgpost a LEFT JOIN alone_auth_post b ON a.POSTID=b.ID WHERE b.TYPE='2' and a.USERID=?"); + sqlquery.setString(0, userId); + sqlquery.addEntity(Userpost.class); + return sqlquery.list(); + } + + @Override + protected Class getTypeClass() { + return Userpost.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/Action.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/Action.java new file mode 100644 index 0000000..98653cc --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/Action.java @@ -0,0 +1,137 @@ +package com.farm.authority.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/* * + *功能:权限资源类 + *详细: + * + *版本:v0.1 + *作者:王东 + *日期:20141119144919 + *说明: + */ +@Entity(name = "Action") +@Table(name = "alone_auth_action") +public class Action implements java.io.Serializable { + private static final long serialVersionUID = 1L; + @Column(name = "LOGINIS", length = 1, nullable = false) + private String loginis; + @Column(name = "CHECKIS", length = 1, nullable = false) + private String checkis; + @Column(name = "STATE", length = 1, nullable = false) + private String state; + @Column(name = "MUSER", length = 32, nullable = false) + private String muser; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "UTIME", length = 16, nullable = false) + private String utime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "COMMENTS", length = 128) + private String comments; + @Column(name = "NAME", length = 64, nullable = false) + private String name; + @Column(name = "AUTHKEY", length = 128) + private String authkey; + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + + public String getLoginis() { + return this.loginis; + } + + public void setLoginis(String loginis) { + this.loginis = loginis; + } + + public String getCheckis() { + return this.checkis; + } + + public void setCheckis(String checkis) { + this.checkis = checkis; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getMuser() { + return this.muser; + } + + public void setMuser(String muser) { + this.muser = muser; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getUtime() { + return this.utime; + } + + public void setUtime(String utime) { + this.utime = utime; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getComments() { + return this.comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthkey() { + return this.authkey; + } + + public void setAuthkey(String authkey) { + this.authkey = authkey; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/Actiontree.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/Actiontree.java new file mode 100644 index 0000000..70c0741 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/Actiontree.java @@ -0,0 +1,196 @@ +package com.farm.authority.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/* * + *功能:构造权限类 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +@Entity(name = "Actiontree") +@Table(name = "ALONE_AUTH_ACTIONTREE") +public class Actiontree implements java.io.Serializable { + private static final long serialVersionUID = 1L; + @Column(name = "PARAMS", length = 128) + private String params; + @Column(name = "IMGID", length = 32) + private String imgid; + @Column(name = "ICON", length = 64) + private String icon; + @Column(name = "DOMAIN", length = 64) + private String domain; + @Column(name = "ACTIONID", length = 32) + private String actionid; + @Column(name = "STATE", length = 1, nullable = false) + private String state; + @Column(name = "UUSER", length = 32, nullable = false) + private String uuser; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "UTIME", length = 16, nullable = false) + private String utime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "TYPE", length = 1, nullable = false) + private String type; + @Column(name = "COMMENTS", length = 128) + private String comments; + @Column(name = "TREECODE", length = 256) + private String treecode; + @Column(name = "NAME", length = 64, nullable = false) + private String name; + @Column(name = "PARENTID", length = 32, nullable = false) + private String parentid; + private int sort; + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + + public String getParams() { + return this.params; + } + + public void setParams(String params) { + this.params = params; + } + + public String getImgid() { + return this.imgid; + } + + public void setImgid(String imgid) { + this.imgid = imgid; + } + + public String getIcon() { + return this.icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getDomain() { + return this.domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getActionid() { + return this.actionid; + } + + public void setActionid(String actionid) { + this.actionid = actionid; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getUuser() { + return this.uuser; + } + + public void setUuser(String uuser) { + this.uuser = uuser; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getUtime() { + return this.utime; + } + + public void setUtime(String utime) { + this.utime = utime; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public String getComments() { + return this.comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public String getTreecode() { + return this.treecode; + } + + public void setTreecode(String treecode) { + this.treecode = treecode; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getParentid() { + return this.parentid; + } + + public void setParentid(String parentid) { + this.parentid = parentid; + } + + public int getSort() { + return this.sort; + } + + public void setSort(int sort) { + this.sort = sort; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/AuthKeyImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/AuthKeyImpl.java new file mode 100644 index 0000000..5ee6d4e --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/AuthKeyImpl.java @@ -0,0 +1,47 @@ +package com.farm.authority.domain; + +import com.farm.core.auth.domain.AuthKey; + +public class AuthKeyImpl implements AuthKey { + private boolean ischeck; + private boolean islogin; + private boolean isUseAble; + private String title; + + @Override + public boolean isCheck() { + return ischeck; + } + + @Override + public boolean isLogin() { + return islogin; + } + + @Override + public boolean isUseAble() { + return isUseAble; + } + + @Override + public String getTitle() { + return title; + } + + public void setIscheck(boolean ischeck) { + this.ischeck = ischeck; + } + + public void setIslogin(boolean islogin) { + this.islogin = islogin; + } + + public void setUseAble(boolean isUseAble) { + this.isUseAble = isUseAble; + } + + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/AuthMenuImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/AuthMenuImpl.java new file mode 100644 index 0000000..34f573d --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/AuthMenuImpl.java @@ -0,0 +1,55 @@ +package com.farm.authority.domain; + +import java.io.Serializable; + +import com.farm.core.auth.domain.WebMenu; + +public class AuthMenuImpl implements WebMenu,Serializable{ + /** + * + */ + private static final long serialVersionUID = -1595137580049523129L; + private String params; + private String icon; + private String url; + private String name; + private String parentid; + private String id; + public String getParams() { + return params; + } + public void setParams(String params) { + this.params = params; + } + public String getIcon() { + return icon; + } + public void setIcon(String icon) { + this.icon = icon; + } + public String getUrl() { + return url; + } + public void setUrl(String url) { + this.url = url; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getParentid() { + return parentid; + } + public void setParentid(String parentid) { + this.parentid = parentid; + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/Organization.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/Organization.java new file mode 100644 index 0000000..63b4f3c --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/Organization.java @@ -0,0 +1,128 @@ +package com.farm.authority.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + + + +/* * + *功能:组织机构类 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +@Entity(name = "Organization") +@Table(name = "ALONE_AUTH_ORGANIZATION") +public class Organization implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Column(name = "TYPE", length = 1, nullable = false) + private String type; + @Column(name = "SORT", nullable = false) + private int sort; + @Column(name = "PARENTID", length = 32, nullable = false) + private String parentid; + @Column(name = "MUSER", length = 32, nullable = false) + private String muser; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "STATE", length = 1, nullable = false) + private String state; + @Column(name = "UTIME", length = 16, nullable = false) + private String utime; + @Column(name = "CTIME", length = 61, nullable = false) + private String ctime; + @Column(name = "COMMENTS", length = 128) + private String comments; + @Column(name = "NAME", length = 64, nullable = false) + private String name; + @Column(name = "TREECODE", length = 256, nullable = false) + private String treecode; + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + + + public String getType() { + return this.type; + } + public void setType(String type) { + this.type = type; + } + public int getSort() { + return this.sort; + } + public void setSort(int sort) { + this.sort = sort; + } + public String getParentid() { + return this.parentid; + } + public void setParentid(String parentid) { + this.parentid = parentid; + } + public String getMuser() { + return this.muser; + } + public void setMuser(String muser) { + this.muser = muser; + } + public String getCuser() { + return this.cuser; + } + public void setCuser(String cuser) { + this.cuser = cuser; + } + public String getState() { + return this.state; + } + public void setState(String state) { + this.state = state; + } + public String getUtime() { + return this.utime; + } + public void setUtime(String utime) { + this.utime = utime; + } + public String getCtime() { + return this.ctime; + } + public void setCtime(String ctime) { + this.ctime = ctime; + } + public String getComments() { + return this.comments; + } + public void setComments(String comments) { + this.comments = comments; + } + public String getName() { + return this.name; + } + public void setName(String name) { + this.name = name; + } + public String getTreecode() { + return this.treecode; + } + public void setTreecode(String treecode) { + this.treecode = treecode; + } + public String getId() { + return this.id; + } + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/Post.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/Post.java new file mode 100644 index 0000000..ab2c0de --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/Post.java @@ -0,0 +1,141 @@ +package com.farm.authority.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/* * + *功能:岗位类 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20141124152033 + *说明: + */ +@Entity(name = "Post") +@Table(name = "ALONE_AUTH_POST") +public class Post implements java.io.Serializable { + + /** + * + */ + private static final long serialVersionUID = -3393948958969271827L; + @Column(name = "EXTENDIS", length = 2, nullable = false) + private String extendis; + @Column(name = "NAME", length = 64, nullable = false) + private String name; + @Column(name = "ORGANIZATIONID", length = 32, nullable = false) + private String organizationid; + @Column(name = "PSTATE", length = 1, nullable = false) + private String pstate; + @Column(name = "EUSER", length = 32, nullable = false) + private String euser; + @Column(name = "EUSERNAME", length = 64, nullable = false) + private String eusername; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + + public String getExtendis() { + return extendis; + } + + public void setExtendis(String extendis) { + this.extendis = extendis; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOrganizationid() { + return this.organizationid; + } + + public void setOrganizationid(String organizationid) { + this.organizationid = organizationid; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getEuser() { + return this.euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getEusername() { + return this.eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getEtime() { + return this.etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/Postaction.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/Postaction.java new file mode 100644 index 0000000..442bab7 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/Postaction.java @@ -0,0 +1,53 @@ +package com.farm.authority.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/* * + *功能:岗位权限类 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20141204174206 + *说明: + */ +@Entity(name = "Postaction") +@Table(name = "ALONE_AUTH_POSTACTION") +public class Postaction implements java.io.Serializable { + private static final long serialVersionUID = 1L; + @Column(name = "POSTID", length = 32, nullable = false) + private String postid; + @Column(name = "MENUID", length = 32, nullable = false) + private String menuid; + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + + + public String getPostid() { + return this.postid; + } + public void setPostid(String postid) { + this.postid = postid; + } + public String getMenuid() { + return this.menuid; + } + public void setMenuid(String menuid) { + this.menuid = menuid; + } + public String getId() { + return this.id; + } + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/User.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/User.java new file mode 100644 index 0000000..51d5b0e --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/User.java @@ -0,0 +1,159 @@ +package com.farm.authority.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +import com.farm.core.auth.domain.LoginUser; + +/* * + *功能:用户类 + *详细: + * + *版本:v0.1 + *作者:王东 + *日期:20141119144919 + *说明: + */ +@Entity(name = "User") +@Table(name = "ALONE_AUTH_USER") +public class User implements java.io.Serializable, LoginUser { + private static final long serialVersionUID = 1L; + @Column(name = "LOGINTIME", length = 16) + private String logintime; + @Column(name = "LOGINNAME", length = 64, nullable = false) + private String loginname; + @Column(name = "STATE", length = 1, nullable = false) + private String state; + @Column(name = "MUSER", length = 32, nullable = false) + private String muser; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "UTIME", length = 16, nullable = false) + private String utime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "TYPE", length = 1, nullable = false) + private String type; + @Column(name = "PASSWORD", length = 32, nullable = false) + private String password; + @Column(name = "COMMENTS", length = 128) + private String comments; + @Column(name = "NAME", length = 64, nullable = false) + private String name; + @Column(name = "IMGID", length = 32) + private String imgid; + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + + public String getLogintime() { + return this.logintime; + } + + public void setLogintime(String logintime) { + this.logintime = logintime; + } + + public String getLoginname() { + return this.loginname; + } + + public void setLoginname(String loginname) { + this.loginname = loginname; + } + + public String getState() { + return this.state; + } + + public void setState(String state) { + this.state = state; + } + + public String getMuser() { + return this.muser; + } + + public void setMuser(String muser) { + this.muser = muser; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getUtime() { + return this.utime; + } + + public void setUtime(String utime) { + this.utime = utime; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getComments() { + return this.comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImgid() { + return imgid; + } + + public void setImgid(String imgid) { + this.imgid = imgid; + } +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/Userorg.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/Userorg.java new file mode 100644 index 0000000..baa7822 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/Userorg.java @@ -0,0 +1,67 @@ +package com.farm.authority.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/* * + *功能:置顶文档类 + *详细: + * + *版本:v2.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Entity(name = "UserOrg") +@Table(name = "alone_auth_userorg") +public class Userorg implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, nullable = false) + private String id; + @Column(name = "ORGANIZATIONID", length = 32, nullable = false) + private String organizationid; + @Column(name = "USERID", length = 32, nullable = false) + private String userid; + + public Userorg() { + } + public Userorg(String id, String organizationid, String userid) { + super(); + this.id = id; + this.organizationid = organizationid; + this.userid = userid; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getOrganizationid() { + return this.organizationid; + } + + public void setOrganizationid(String organizationid) { + this.organizationid = organizationid; + } + + public String getUserid() { + return this.userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/domain/Userpost.java b/src/wcp-authority/src/main/java/com/farm/authority/domain/Userpost.java new file mode 100644 index 0000000..aa3e472 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/domain/Userpost.java @@ -0,0 +1,60 @@ +package com.farm.authority.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; +/* * + *功能:置顶文档类 + *详细: + * + *版本:v2.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Entity(name = "UserPost") +@Table(name = "alone_auth_userpost") +public class Userpost implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "POSTID", length = 32, nullable = false) + private String postid; + @Column(name = "USERID", length = 32, nullable = false) + private String userid; + + public Userpost() { + } + public Userpost(String id, String postid, String userid) { + super(); + this.id = id; + this.postid = postid; + this.userid = userid; + } + public String getPostid() { + return this.postid; + } + public void setPostid(String postid) { + this.postid = postid; + } + public String getId() { + return this.id; + } + public void setId(String id) { + this.id = id; + } + public String getUserid() { + return this.userid; + } + public void setUserid(String userid) { + this.userid = userid; + } +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/service/ActionServiceInter.java b/src/wcp-authority/src/main/java/com/farm/authority/service/ActionServiceInter.java new file mode 100644 index 0000000..ba8e4d2 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/service/ActionServiceInter.java @@ -0,0 +1,148 @@ +package com.farm.authority.service; + +import java.util.List; + +import com.farm.authority.domain.Action; +import com.farm.authority.domain.Actiontree; +import com.farm.core.auth.domain.AuthKey; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.sql.query.DataQuery; +import com.farm.web.easyui.EasyUiTreeNode; + +/* * + *功能:权限资源服务层接口 + *详细: + * + *版本:v0.1 + *作者:王东 + *日期:20141119144919 + *说明: + */ +public interface ActionServiceInter { + /** + *新增权限定义 + * + * @param entity + */ + public Action insertActionEntity(Action entity, LoginUser user); + + /** + *修改权限定义 + * + * @param entity + */ + public Action editActionEntity(Action entity, LoginUser user); + + /** + *删除权限定义 + * + * @param entity + */ + public void deleteActionEntity(String id, LoginUser user); + + /** + *获得权限定义 + * + * @param id + * @return + */ + public Action getActionEntity(String id); + + /** + * 创建一个基本查询用来查询当前权限定义 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createActionSimpleQuery(DataQuery query); + + /** + *新增构造权限 + * + * @param entity + * @param user + * @param authkey + * 如果不是选择的就用authkey创建一个权限 + * @return + */ + public Actiontree insertActiontreeEntity(Actiontree entity, LoginUser user, + String authkey); + + /** + *修改构造权限 + * + * @param entity + * @param user + * @param authkey + * 如果不是选择的就用authkey创建一个权限 + * @return + */ + public Actiontree editActiontreeEntity(Actiontree entity, LoginUser user, + String authkey); + + /** + *删除构造权限 + * + * @param entity + */ + public void deleteActiontreeEntity(String id, LoginUser user); + + /** + *获得构造权限 + * + * @param id + * @return + */ + public Actiontree getActiontreeEntity(String id); + + /** + * 创建一个基本查询用来查询当前构造权限 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createActiontreeSimpleQuery(DataQuery query); + + /** + * 构造权限异步树 + * + * @return + */ + public List getSyncTree(String parentId, String domain); + + /** + * 移动构造树节点到目标节点下 + * + * @param treeNodeId + * 原来id + * @param targetTreeNodeId + * 目标id + */ + public void moveActionTreeNode(String treeNodeId, String targetTreeNodeId); + + /** + * 获得缓存的权限属性 + * + * @param key + * @return + */ + public AuthKey getCacheAction(String key); + + /** + * 获得全部可用菜单 + * + * @return + */ + public List getAllMenus(); + + /** + * 获得全部权限 + * + * @return + */ + public List getAllActions(); + +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/service/OrganizationServiceInter.java b/src/wcp-authority/src/main/java/com/farm/authority/service/OrganizationServiceInter.java new file mode 100644 index 0000000..aee4c4d --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/service/OrganizationServiceInter.java @@ -0,0 +1,185 @@ +package com.farm.authority.service; + +import java.util.List; +import java.util.Map; + +import com.farm.authority.domain.Organization; +import com.farm.authority.domain.Post; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DataQuery; +import com.farm.web.easyui.EasyUiTreeNode; + +/* * + *功能:组织机构服务类接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +public interface OrganizationServiceInter { + /** + * 新增实体管理实体 + * + * @param entity + */ + public Organization insertOrganizationEntity(Organization entity, LoginUser user); + + /** + * 修改实体管理实体 + * + * @param entity + */ + public Organization editOrganizationEntity(Organization entity, LoginUser user); + + /** + * 删除实体管理实体 + * + * @param entity + */ + public void deleteOrganizationEntity(String id, LoginUser user); + + /** + * 获得实体管理实体 + * + * @param id + * @return + */ + public Organization getOrganizationEntity(String id); + + /** + * 创建一个基本查询用来查询当前实体管理实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createOrganizationSimpleQuery(DataQuery query); + + /** + * 新增岗位 + * + * @param orgId + * @param postname + * @param extendis + * @param user + * @return + */ + public Post insertPost(String orgId, String postname, String extendis, LoginUser user); + + /** + * 修改岗位 + * + * @param postId + * @param postname + * @param posttype + * @param user + * @return + */ + public Post editPost(String postId, String postname, String extendis, LoginUser user); + + /** + * 获得所有父亲组织机构 + * + * @return + */ + public List getParentOrgs(String orgid); + + /** + * 删除实体管理实体 + * + * @param entity + */ + public void deletePostEntity(String id, LoginUser user); + + /** + * 获得实体管理实体 + * + * @param id + * @return + */ + public Post getPostEntity(String id); + + /** + * 创建一个基本查询用来查询当前实体管理实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createPostSimpleQuery(DataQuery query); + + /** + * 移动组织机构 + * + * @param orgId + * @param targetOrgId + */ + public void moveOrgTreeNode(String orgId, String targetOrgId); + + /** + * 加载岗位树 + * + * @param ids + * @return + */ + public List loadPostTree(String ids); + + /** + * 为用户添加岗位(如果是标准岗则替换掉用户已有标准岗,如果是临时岗则添加给用户) + * + * @param userId + * @param postId + */ + public void addUserPost(String userId, String postId, LoginUser currentUser); + + /** + * 移除组织机构的用户 + * + * @param postId + * @param Userid + * @param currentUser + */ + public void removePostUsers(String postId, String userid, LoginUser currentUser); + + /** + * 设置岗位权限 + * + * @param actionTreeIds + * @param postId + */ + public void setPostActionTree(List actionTreeIds, String postId); + + /** + * 获取机构列表 + * + * @return List + */ + public List getTree(); + + /** + * 获取岗位 + * + * @param orgId + * @return List + */ + public List> getPostList(String orgId); + + /** + * 获取岗位,带父机构的岗位 + * + * @param orgId + * @return List + */ + public List> getPostListWithPOrgPost(String orgId); + + /** + * 获得组织机构下的所有人 + * + * @param orgid + * @return + */ + public List getOrgUsers(String orgid); + +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/service/UserServiceInter.java b/src/wcp-authority/src/main/java/com/farm/authority/service/UserServiceInter.java new file mode 100644 index 0000000..757c7f6 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/service/UserServiceInter.java @@ -0,0 +1,249 @@ +package com.farm.authority.service; + +import java.util.List; + +import com.farm.authority.domain.Action; +import com.farm.authority.domain.Organization; +import com.farm.authority.domain.Post; +import com.farm.authority.domain.User; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.sql.query.DataQuery; + +/* * + *功能:用户服务层接口 + *详细: + * + *版本:v0.1 + *作者:王东 + *日期:20141119144919 + *说明: + */ +public interface UserServiceInter { + /** + * 新增实体管理实体(密码为空时,系统取默认密码) + * + * @param entity + */ + public User insertUserEntity(User entity, LoginUser user, String orgId, String postIds); + + /** + * 新增实体管理实体(密码为空时,系统取默认密码) + * + * @param entity + * 用户实例 + * @param user + * 操作人 + * @return + */ + public User insertUserEntity(User entity, LoginUser user); + + /** + * 修改实体管理实体 + * + * @param entity + */ + public User editUserEntity(User entity, LoginUser user, String orgId, String postIds); + + /** + * 删除实体管理实体 + * + * @param entity + */ + public void deleteUserEntity(String id, LoginUser user); + + /** + * 获得实体管理实体 + * + * @param id + * @return + */ + public User getUserEntity(String id); + + /** + * 创建一个基本查询用来查询当前实体管理实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createUserSimpleQuery(DataQuery query, LoginUser currentUser); + + /** + * 验证登录名是否重复 + * + * @param loginname + * 登录名 + * @param userId + * 用户id(修改时判断是不是本用户的登录名,是自己的不算重复) + * @return + */ + public boolean validateIsRepeatLoginName(String loginname, String userId); + + /** + * 初始化用户密码 + * + * @param userid + * @param currentUser + */ + public void initDefaultPassWord(String userid, LoginUser currentUser); + + /** + * 获得用户 + * + * @param loginName + * @return + */ + public User getUserByLoginName(String loginName); + + /** + * 设置用户登录时间 + * + * @param userId + */ + public void setLoginTime(String userId); + + /** + * 查询岗位用户 + * + * @param query + * @return + */ + public DataQuery createUserPostQuery(DataQuery query); + + /** + * 获得用户所有的权限 + * + * @param userId + * @return + */ + public List getUserActions(String userId); + + /** + * 获得用户菜单 + * + * @param userId + * @return + */ + public List getUserMenus(String userId); + + /** + * 获得用户岗位序列 + * + * @param userId + * @return + */ + public List getUserPostIds(String userId); + + /** + * 获得用户岗位序列 + * + * @param userId + * @return + */ + public List getUserPosts(String userId); + + /** + * 修改密码 + * + * @param loginname + * @param oldPassword + * @param newPassword + * @return + */ + public boolean editLoginPassword(String loginname, String oldPassword, String newPassword); + + /** + * 获得用户的组织机构 + * + * @param userId + * @return + */ + public Organization getUserOrganization(String userId); + + /** + * 用户注册(请) + * + * @param user + * @param orgid + * @return + */ + public User registUser(User user, String orgid); + + /** + * 用户注册 + * + * @param user + * @return + */ + public User registUser(User user); + + /** + * 获取组织机构 + * + * @param id + * @return Organization + */ + public Organization getOrg(String id); + + /** + * 获取岗位 + * + * @param id + * @return List + */ + public List getPost(String id); + + /** + * 获取机构下的用户 + * + * @param query + * @return DataQuery + */ + public DataQuery createOrgUserQuery(DataQuery query); + + /** + * 更新当前登录用户信息 + * + * @param id + * @param name + * @param photoid + * @param orgid + * void + */ + public void editCurrentUser(String id, String name, String photoid, String orgid); + + /** + * 更新当前登录用户信息 + * + * @param id + * @param name + * @param photoid + * void + */ + public void editCurrentUser(String id, String name, String photoid); + + /** + * 编辑当前登录用户密码 + * + * @param id + * @param password + * @param newPassword + * void + */ + public void editCurrentUserPwdCommit(String id, String password, String newPassword); + + /** + * 校验当前登录用户密码是否有效 + * + * @param id + * @param password + * @return boolean + */ + public boolean validCurrentUserPwd(String id, String password); + + /**系统当前可用用户数 + * @return + */ + public Integer getUsersNum(); +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/service/impl/ActionServiceImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/service/impl/ActionServiceImpl.java new file mode 100644 index 0000000..a6bd02b --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/service/impl/ActionServiceImpl.java @@ -0,0 +1,396 @@ +package com.farm.authority.service.impl; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.authority.domain.Action; +import com.farm.authority.domain.Actiontree; +import com.farm.authority.domain.AuthKeyImpl; +import com.farm.authority.domain.AuthMenuImpl; +import com.farm.core.time.TimeTool; +import com.farm.authority.dao.ActionDaoInter; +import com.farm.authority.dao.ActiontreeDaoInter; +import com.farm.authority.service.ActionServiceInter; +import com.farm.core.auth.domain.AuthKey; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.web.easyui.EasyUiTreeNode; + +/* * + *功能:权限资源服务层实现类 + *详细: + * + *版本:v0.1 + *作者:王东 + *日期:20141119144919 + *说明: + */ +@Service +public class ActionServiceImpl implements ActionServiceInter { + @Resource + private ActionDaoInter actionDaoImpl; + @Resource + private ActiontreeDaoInter actiontreeDaoImpl; + /** + * 系统所用权限缓存 + */ + private Map keyMap = new HashMap(); + + @Override + @Transactional + public Action insertActionEntity(Action entity, LoginUser user) { + entity.setCuser(user.getId()); + entity.setCtime(TimeTool.getTimeDate14()); + entity.setMuser(user.getId()); + entity.setUtime(TimeTool.getTimeDate14()); + if (actionDaoImpl.getEntityByKey(entity.getAuthkey()) != null) { + throw new RuntimeException("key已经存在!"); + } + keyMap.clear(); + return actionDaoImpl.insertEntity(entity); + } + + @Override + @Transactional + public Action editActionEntity(Action entity, LoginUser user) { + Action entity2 = actionDaoImpl.getEntity(entity.getId()); + entity2.setMuser(user.getId()); + entity2.setUtime(TimeTool.getTimeDate14()); + entity2.setLoginis(entity.getLoginis()); + entity2.setCheckis(entity.getCheckis()); + entity2.setState(entity.getState()); + entity2.setComments(entity.getComments()); + entity2.setName(entity.getName()); + entity2.setAuthkey(entity.getAuthkey()); + actionDaoImpl.editEntity(entity2); + Action keyAction = actionDaoImpl.getEntityByKey(entity.getAuthkey()); + if (keyAction != null && !keyAction.getId().equals(entity2.getId())) { + throw new RuntimeException("key已经存在!"); + } + keyMap.clear(); + return entity2; + } + + @Override + @Transactional + public void deleteActionEntity(String id, LoginUser user) { + actionDaoImpl.deleteEntity(actionDaoImpl.getEntity(id)); + } + + @Override + @Transactional + public Action getActionEntity(String id) { + if (id == null) { + return null; + } + return actionDaoImpl.getEntity(id); + } + + @Override + @Transactional + public DataQuery createActionSimpleQuery(DataQuery query) { + DataQuery dbQuery = DataQuery + .init(query, "ALONE_AUTH_ACTION", + "ID,LOGINIS,CHECKIS,STATE,MUSER,CUSER,UTIME,CTIME,COMMENTS,NAME,AUTHKEY"); + return dbQuery; + } + + @Override + @Transactional + public Actiontree insertActiontreeEntity(Actiontree entity, LoginUser user, + String authkey) { + entity.setCuser(user.getId()); + entity.setCtime(TimeTool.getTimeDate14()); + entity.setUuser(user.getId()); + entity.setUtime(TimeTool.getTimeDate14()); + entity.setState("1"); + if (entity.getParentid() == null) { + entity.setParentid("NONE"); + } + // 类型为结构菜单则不设置权限 + if (entity.getType().equals("1")) { + entity.setActionid(null); + } else { + // 如果传入了id标准用户选择了一个已有的权限 + if (entity.getActionid() == null + || entity.getActionid().trim().length() <= 0) { + // 如果没有id则为手填的 + // 新建立action + Action action = new Action(); + action.setAuthkey(authkey); + String actionName = ""; + if (!entity.getParentid().equals("NONE")) { + actionName = actiontreeDaoImpl.getEntity( + entity.getParentid()).getName() + + '_' + entity.getName(); + } else { + actionName = entity.getName(); + } + action.setName(actionName); + action.setCheckis("1"); + action.setLoginis("1"); + action.setState("1"); + entity.setActionid(insertActionEntity(action, user).getId()); + } + } + entity.setTreecode("NONE"); + entity = actiontreeDaoImpl.insertEntity(entity); + initTreeCode(entity.getId()); + return entity; + } + + @Override + @Transactional + public Actiontree editActiontreeEntity(Actiontree entity, LoginUser user, + String authkey) { + Actiontree entity2 = actiontreeDaoImpl.getEntity(entity.getId()); + entity2.setUuser(user.getId()); + entity2.setUtime(TimeTool.getTimeDate14()); + entity2.setParams(entity.getParams()); + entity2.setImgid(entity.getImgid()); + entity2.setIcon(entity.getIcon()); + entity2.setActionid(entity.getActionid()); + entity2.setState(entity.getState()); + entity2.setType(entity.getType()); + entity2.setComments(entity.getComments()); + entity2.setName(entity.getName()); + entity2.setSort(entity.getSort()); + // 类型为结构菜单则不设置权限 + if (entity.getType().equals("1")) { + entity.setActionid(null); + } else { + // 如果传入了id标准用户选择了一个已有的权限 + if (entity.getActionid() == null + || entity.getActionid().trim().length() <= 0) { + // 如果没有id则为手填的 + // 新建立action + Action action = new Action(); + action.setAuthkey(authkey); + String actionName = ""; + if (!entity.getParentid().equals("NONE")) { + actionName = actiontreeDaoImpl.getEntity( + entity.getParentid()).getName() + + '_' + entity.getName(); + } else { + actionName = entity.getName(); + } + action.setName(actionName); + action.setCheckis("1"); + action.setLoginis("1"); + entity.setActionid(insertActionEntity(action, user).getId()); + } + } + actiontreeDaoImpl.editEntity(entity2); + return entity2; + } + + @Override + @Transactional + public void deleteActiontreeEntity(String id, LoginUser user) { + // TODO 自动生成代码,修改后请去除本注释 + if (actiontreeDaoImpl.selectEntitys( + DBRule.addRule(new ArrayList(), "parentid", id, "=")) + .size() > 0) { + throw new RuntimeException("不能删除该节点,请先删除其子节点"); + } + actiontreeDaoImpl.deleteEntity(actiontreeDaoImpl.getEntity(id)); + } + + @Override + @Transactional + public Actiontree getActiontreeEntity(String id) { + // TODO 自动生成代码,修改后请去除本注释 + if (id == null) { + return null; + } + return actiontreeDaoImpl.getEntity(id); + } + + @Override + @Transactional + public DataQuery createActiontreeSimpleQuery(DataQuery query) { + // TODO 自动生成代码,修改后请去除本注释 + DataQuery dbQuery = DataQuery + .init(query, + "ALONE_AUTH_ACTIONTREE", + "ID,PARAMS,IMGID,ICON,DOMAIN,ACTIONID,STATE,UUSER,CUSER,UTIME,CTIME,TYPE,COMMENTS,TREECODE,NAME,PARENTID,SORT"); + return dbQuery; + } + + @Override + @Transactional + public List getSyncTree(String parentId, String domain) { + if (parentId == null) { + parentId = "NONE"; + } + if (domain == null) { + domain = "alone"; + } + return EasyUiTreeNode + .formatAsyncAjaxTree( + EasyUiTreeNode + .queryTreeNodeOne( + parentId, + "SORT", + "(SELECT c.NAME AS NAME,SORT,c.ID AS ID,PARENTID,ICON,b.AUTHKEY as URL,c.PARAMS as PARAM,domain FROM alone_auth_actiontree c LEFT JOIN alone_auth_action b ON c.ACTIONID=b.ID)", + "ID", "PARENTID", "NAME", "ICON", + "and a.DOMAIN='" + domain + "'", + "URL,PARAM").getResultList(), + EasyUiTreeNode + .queryTreeNodeTow(parentId, "SORT", + "alone_auth_actiontree", "ID", + "PARENTID", "NAME", "ICON", + "and a.DOMAIN='" + domain + "'") + .getResultList(), "PARENTID", "ID", "NAME", + "ICON"); + } + + @Override + @Transactional + public void moveActionTreeNode(String treeNodeId, String targetTreeNodeId) { + // 移动节点 + Actiontree node = getActiontreeEntity(treeNodeId); + if (node.getParentid().equals("NONE")) { + throw new RuntimeException("不能够移动根节点!"); + } + Actiontree target = getActiontreeEntity(targetTreeNodeId); + if (target.getTreecode().indexOf(node.getTreecode()) >= 0) { + throw new RuntimeException("不能够移动到其子节点下!"); + } + node.setParentid(targetTreeNodeId); + actiontreeDaoImpl.editEntity(node); + // 构造所有树TREECODE + List list = actiontreeDaoImpl.getAllSubNodes(treeNodeId); + for (Actiontree action : list) { + action.setDomain(target.getDomain()); + actiontreeDaoImpl.editEntity(action); + initTreeCode(action.getId()); + } + } + + private void initTreeCode(String treeNodeId) { + Actiontree node = getActiontreeEntity(treeNodeId); + if (node.getParentid().equals("NONE")) { + node.setTreecode(node.getId()); + } else { + node.setTreecode(actiontreeDaoImpl.getEntity(node.getParentid()) + .getTreecode() + node.getId()); + } + actiontreeDaoImpl.editEntity(node); + } + + @Override + @Transactional + public AuthKey getCacheAction(String key) { + if (keyMap.size() <= 0) { + List list = actionDaoImpl.getAllEntity(); + for (Action node : list) { + AuthKeyImpl authkey = new AuthKeyImpl(); + authkey.setIscheck(node.getCheckis().equals("1")); + authkey.setIslogin(node.getLoginis().equals("1")); + authkey.setUseAble(node.getState().equals("1")); + authkey.setTitle(node.getName()); + keyMap.put(node.getAuthkey(), authkey); + } + } + return keyMap.get(key); + } + + @Override + @Transactional + public List getAllMenus() { + DataQuery query = DataQuery + .getInstance( + 1, + "SORT,ID,PARENTID,NAME,TYPE,STATE,ICON,IMGID,PARAMS,AUTHKEY", + "(SELECT c.SORT,c.ID,c.PARENTID,c.NAME,c.TYPE,c.STATE,c.ICON,c.IMGID,c.PARAMS,d.AUTHKEY FROM alone_auth_actiontree c LEFT JOIN alone_auth_action d ON d.ID=c.ACTIONID WHERE (d.STATE = '1' or d.STATE IS NULL) and c.type!='3' order by LENGTH(c.TREECODE),c.SORT asc) e"); + List menus = new ArrayList(); + query.setPagesize(1000); + query.setNoCount(); + query.setDistinct(true); + try { + for (Map map : query.search().getResultList()) { + AuthMenuImpl node = new AuthMenuImpl(); + node.setIcon(map.get("ICON") != null ? map.get("ICON") + .toString() : null); + node.setId(map.get("ID") != null ? map.get("ID").toString() + : null); + node.setName(map.get("NAME") != null ? map.get("NAME") + .toString() : null); + node.setParams(map.get("PARAMS") != null ? map.get("PARAMS") + .toString() : null); + node.setParentid(map.get("PARENTID") != null ? map.get( + "PARENTID").toString() : null); + node.setUrl(map.get("AUTHKEY") != null ? map.get("AUTHKEY") + .toString() : null); + menus.add(node); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + return menus; + } + + @Override + @Transactional + public List getAllActions() { + DataQuery dbQuery = DataQuery.getInstance(1, + "d.id,d.AUTHKEY,d.NAME,d.COMMENTS,d.STATE,d.CHECKIS,d.LOGINIS", + " alone_auth_action d "); + dbQuery.addRule(new DBRule("d.STATE", "1", "=")); + dbQuery.setDistinct(true); + dbQuery.setNoCount(); + dbQuery.setPagesize(5000); + List list = new ArrayList(); + try { + for (Map node : dbQuery.search().getResultList()) { + Action action = new Action(); + action.setAuthkey(node.get("D_AUTHKEY") != null ? node.get( + "D_AUTHKEY").toString() : null); + action.setId(node.get("D_ID") != null ? node.get("D_ID") + .toString() : null); + action.setName(node.get("D_NAME") != null ? node.get("D_NAME") + .toString() : null); + action.setComments(node.get("D_COMMENTS") != null ? node.get( + "D_COMMENTS").toString() : null); + action.setState(node.get("D_STATE") != null ? node.get( + "D_STATE").toString() : null); + action.setCheckis(node.get("D_CHECKIS") != null ? node.get( + "D_CHECKIS").toString() : null); + action.setLoginis(node.get("D_LOGINIS") != null ? node.get( + "D_LOGINIS").toString() : null); + list.add(action); + } + } catch (SQLException e) { + throw new RuntimeException(); + } + return list; + } + + public ActionDaoInter getActionDaoImpl() { + return actionDaoImpl; + } + + public void setActionDaoImpl(ActionDaoInter actionDaoImpl) { + this.actionDaoImpl = actionDaoImpl; + } + + public ActiontreeDaoInter getActiontreeDaoImpl() { + return actiontreeDaoImpl; + } + + public void setActiontreeDaoImpl(ActiontreeDaoInter actiontreeDaoImpl) { + this.actiontreeDaoImpl = actiontreeDaoImpl; + } + +} diff --git a/src/wcp-authority/src/main/java/com/farm/authority/service/impl/OrganizationServiceImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/service/impl/OrganizationServiceImpl.java new file mode 100644 index 0000000..53def4a --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/service/impl/OrganizationServiceImpl.java @@ -0,0 +1,457 @@ +package com.farm.authority.service.impl; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.transaction.Transactional; + +import org.springframework.stereotype.Service; + +import com.farm.authority.dao.OrganizationDaoInter; +import com.farm.authority.dao.PostDaoInter; +import com.farm.authority.dao.PostactionDaoInter; +import com.farm.authority.dao.UserDaoInter; +import com.farm.authority.dao.UserpostDaoInter; +import com.farm.authority.domain.Organization; +import com.farm.authority.domain.Post; +import com.farm.authority.domain.Postaction; +import com.farm.authority.service.OrganizationServiceInter; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.time.TimeTool; +import com.farm.web.easyui.EasyUiTreeNode; + +/* * + *功能:组织机构服务实现类 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20141122211253 + *说明: + */ +@Service +public class OrganizationServiceImpl implements OrganizationServiceInter { + @Resource + private OrganizationDaoInter organizationDao; + @Resource + private PostDaoInter postDao; + @Resource + private UserpostDaoInter userpostDao; + @Resource + private PostactionDaoInter postactionDao; + @Resource + private UserDaoInter userDao; + + @Override + @Transactional + public Organization insertOrganizationEntity(Organization entity, LoginUser user) { + entity.setCuser(user.getId()); + entity.setCtime(TimeTool.getTimeDate14()); + entity.setMuser(user.getId()); + entity.setUtime(TimeTool.getTimeDate14()); + entity.setState("1"); + if (entity.getParentid() == null) { + entity.setParentid("NONE"); + } + entity.setTreecode("NONE"); + entity = organizationDao.insertEntity(entity); + initTreeCode(entity.getId()); + return entity; + } + + @Override + @Transactional + public Organization editOrganizationEntity(Organization entity, LoginUser user) { + Organization entity2 = organizationDao.getEntity(entity.getId()); + entity2.setMuser(user.getId()); + entity2.setUtime(TimeTool.getTimeDate14()); + entity2.setType(entity.getType()); + entity2.setSort(entity.getSort()); + entity2.setState(entity.getState()); + entity2.setComments(entity.getComments()); + entity2.setName(entity.getName()); + organizationDao.editEntity(entity2); + return entity2; + } + + @Override + @Transactional + public void deleteOrganizationEntity(String id, LoginUser user) { + if (organizationDao.selectEntitys(DBRule.addRule(new ArrayList(), "parentid", id, "=")).size() > 0) { + throw new RuntimeException("不能删除该节点,请先删除其子节点"); + } + // 删除岗位 + for (Post post : postDao.selectEntitys(new DBRule("ORGANIZATIONID", id, "=").getDBRules())) { + deletePostEntity(post.getId(), user); + } + // 删除组织机构 + organizationDao.deleteEntity(organizationDao.getEntity(id)); + } + + @Override + @Transactional + public Organization getOrganizationEntity(String id) { + if (id == null) { + return null; + } + return organizationDao.getEntity(id); + } + + @Override + @Transactional + public DataQuery createOrganizationSimpleQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, "ALONE_AUTH_ORGANIZATION", + "ID,TYPE,SORT,PARENTID,MUSER,CUSER,STATE,UTIME,CTIME,COMMENTS,NAME,TREECODE"); + return dbQuery; + } + + @Override + @Transactional + public void deletePostEntity(String id, LoginUser user) { + String[] ids = id.split(","); + for (String id1 : ids) { + // 同时删除岗位用户 + userpostDao.deleteEntitys(new DBRule("POSTID", id1, "=").getDBRules()); + // 同时删除岗位权限 + postactionDao.deleteEntitys(new DBRule("POSTID", id1, "=").getDBRules()); + postDao.deleteEntity(postDao.getEntity(id1)); + } + } + + @Override + @Transactional + public Post getPostEntity(String id) { + if (id == null) { + return null; + } + return postDao.getEntity(id); + } + + @Override + @Transactional + public DataQuery createPostSimpleQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, "ALONE_AUTH_POST", + "ID,EXTENDIS,NAME,ORGANIZATIONID,PSTATE,EUSER,EUSERNAME,CUSER,CUSERNAME,ETIME,CTIME"); + return dbQuery; + } + + @Override + @Transactional + public void moveOrgTreeNode(String orgId, String targetOrgId) { + String[] orgIds = orgId.split(","); + for (int i = 0; i < orgIds.length; i++) { + // 移动节点 + Organization node = getOrganizationEntity(orgIds[i]); + // if (node.getParentid().equals("NONE")) { + // throw new RuntimeException("不能够移动根节点!"); + // } + Organization target = getOrganizationEntity(targetOrgId); + if (target.getTreecode().indexOf(node.getTreecode()) >= 0) { + throw new RuntimeException("不能够移动到其子节点下!"); + } + node.setParentid(targetOrgId); + organizationDao.editEntity(node); + // 构造所有树TREECODE + List list = organizationDao.getAllSubNodes(orgIds[i]); + for (Organization org : list) { + initTreeCode(org.getId()); + } + } + } + + private void initTreeCode(String treeNodeId) { + Organization node = getOrganizationEntity(treeNodeId); + if (node.getParentid().equals("NONE")) { + node.setTreecode(node.getId()); + } else { + node.setTreecode(organizationDao.getEntity(node.getParentid()).getTreecode() + node.getId()); + } + organizationDao.editEntity(node); + } + + @Override + @Transactional + public Post editPost(String postId, String postname, String extendis, LoginUser user) { + // 更新岗位 + Post post = postDao.getEntity(postId); + post.setName(postname); + post.setExtendis(extendis); + post.setEtime(TimeTool.getTimeDate14()); + post.setEuser(user.getId()); + post.setEusername(user.getName()); + postDao.editEntity(post); + + // 如果子机构设为不可用,则删除用户和该岗位的关系 + userpostDao.deleteEntitys(new DBRule("POSTID", post.getId(), "=").getDBRules()); + return post; + } + + @Override + @Transactional + public Post insertPost(String orgId, String postname, String extendis, LoginUser user) { + Post post = new Post(); + post.setName(postname); + post.setExtendis(extendis); + post.setCtime(TimeTool.getTimeDate14()); + post.setCuser(user.getId()); + post.setCusername(user.getName()); + post.setEtime(TimeTool.getTimeDate14()); + post.setEuser(user.getId()); + post.setEusername(user.getName()); + post.setOrganizationid(orgId); + post.setPstate("1"); + return postDao.insertEntity(post); + } + + @Override + @Transactional + public List loadPostTree(String ids) { + if (ids == null || ids.trim().length() <= 0) { + ids = "NONE"; + } + DataQuery query = DataQuery.getInstance("1", "NAME,PARENTID,ID,UTYPE", + "(SELECT NAME,PARENTID,ID,'11' AS UTYPE,SORT FROM alone_auth_organization UNION SELECT NAME,ORGANIZATIONID AS PARENTID,ID,TYPE AS UTYPE,1000 as SORT FROM alone_auth_post ) a "); + query.setPagesize(1000); + query.addRule(new DBRule("PARENTID", ids, "=")); + query.setNoCount(); + query.addSort(new DBSort("UTYPE", "asc")); + query.addSort(new DBSort("SORT", "asc")); + DataQuery query2 = DataQuery.getInstance("1", + "a.NAME as NAME,a.PARENTID as PARENTID,a.ID as ID,a.UTYPE as UTYPE", + "alone_auth_organization b LEFT JOIN (SELECT NAME,PARENTID,ID,'0' AS UTYPE FROM alone_auth_organization UNION SELECT NAME,ORGANIZATIONID AS PARENTID,ID,TYPE AS UTYPE FROM alone_auth_post ) a ON a.PARENTID=b.ID"); + query2.setPagesize(1000); + query2.addRule(new DBRule("b.PARENTID", ids, "=")); + query2.setNoCount(); + List list = null; + try { + List> listOne = query.search().getResultList(); + for (Map node : listOne) { + if (node.get("UTYPE").equals("1")) { + node.put("UTYPE", "icon-suppliers"); + } + if (node.get("UTYPE").equals("2")) { + node.put("UTYPE", "icon-user_medical"); + } + } + list = EasyUiTreeNode.formatAsyncAjaxTree(listOne, query2.search().getResultList(), "PARENTID", "ID", + "NAME", "UTYPE"); + } catch (SQLException e) { + throw new RuntimeException(e); + } + return list; + } + + @Override + @Transactional + public void addUserPost(String userId, String postId, LoginUser currentUser) { + // User user = userDao.getEntity(userId); + // if (user.getState().equals("2")) { + // throw new RuntimeException("该用户已经删除"); + // } + // Post post = postDao.getEntity(postId); + // if (post == null) { + // throw new RuntimeException("请选择正确的岗位"); + // } + // // 先判断岗位是否标准岗1:标准2:临时 + // if (post.getType().equals("1")) { + // // 标准,清理掉用户其他的标准岗 + // for (Userpost userpost : userpostDao.getStandardUserPost(userId)) { + // userpostDao.deleteEntity(userpost); + // } + // } + // for (Userpost userpost : userpostDao.getTempUserPost(userId)) { + // if (userpost.getUserid().equals(userId) && + // userpost.getPostid().equals(postId)) { + // return; + // } + // } + // // 添加岗位 + // Userpost userpost = new Userpost(); + // userpost.setOrganizationid(post.getOrganizationid()); + // userpost.setPostid(postId); + // userpost.setUserid(userId); + // userpostDao.insertEntity(userpost); + } + + // ---------------------------------------------------------------------------------- + public OrganizationDaoInter getOrganizationDao() { + return organizationDao; + } + + public void setOrganizationDao(OrganizationDaoInter dao) { + this.organizationDao = dao; + } + + public PostDaoInter getPostDao() { + return postDao; + } + + public PostactionDaoInter getPostactionDao() { + return postactionDao; + } + + public void setPostactionDao(PostactionDaoInter postactionDao) { + this.postactionDao = postactionDao; + } + + public void setPostDao(PostDaoInter postDao) { + this.postDao = postDao; + } + + public UserpostDaoInter getUserpostDao() { + return userpostDao; + } + + public void setUserpostDao(UserpostDaoInter userpostDao) { + this.userpostDao = userpostDao; + } + + public UserDaoInter getUserDao() { + return userDao; + } + + public void setUserDao(UserDaoInter userDao) { + this.userDao = userDao; + } + + @Override + @Transactional + public void removePostUsers(String postId, String userid, LoginUser currentUser) { + String[] userIds = userid.split(","); + for (String userId : userIds) { + userpostDao.deleteEntitys(new DBRule("USERID", userId, "=").addRule("POSTID", postId, "=").getDBRules()); + } + } + + @Override + @Transactional + public void setPostActionTree(List actionTreeIds, String postId) { + if (postId == null || postId.trim().length() <= 0) { + throw new IllegalArgumentException("请选择一个岗位"); + } + // 删除之前的菜单 + postactionDao.deleteEntitys(new DBRule("POSTID", postId, "=").getDBRules()); + for (String nodeId : actionTreeIds) { + Postaction postaction = new Postaction(); + postaction.setMenuid(nodeId); + postaction.setPostid(postId); + postactionDao.insertEntity(postaction); + } + } + + @Override + @Transactional + public List getTree() { + return organizationDao.selectEntitys(new DBRule("1", "1", "=").getDBRules()); + } + + @Override + public List> getPostList(String orgId) { + try { + DataQuery query = DataQuery.getInstance(1, + "POST.ID AS POSTID, POST.NAME AS POSTNAME, ORG.ID AS ORGID, ORG.NAME AS ORGNAME ", + "ALONE_AUTH_POST POST " + "INNER JOIN ALONE_AUTH_ORGANIZATION ORG ON POST.ORGANIZATIONID = ORG.ID"); + query.setNoCount(); + query.addRule(new DBRule("POST.ORGANIZATIONID", orgId, "=")); + DataResult result = query.search(); + List> list = result.getResultList(); + return list; + + } catch (SQLException e) { + e.printStackTrace(); + } + + return null; + } + + @Override + @Transactional + public List> getPostListWithPOrgPost(String orgId) { + if (orgId == null || orgId.isEmpty()) { + return new ArrayList>(); + } + + Organization entity = organizationDao.getEntity(orgId); + String treecode = entity.getTreecode(); + String pOrgIds = ""; + for (int i = 1; i <= (treecode.length() - 32) / 32; i++) { + pOrgIds += "'" + treecode.substring((i - 1) * 32, i * 32) + "'"; + if (i <= (treecode.length() - 64) / 32) { + pOrgIds += ","; + } + } + if (pOrgIds.isEmpty()) { + pOrgIds = "''"; + } + + try { + DataQuery query = DataQuery.getInstance(1, + "a.POSTID AS POSTID, a.POSTNAME AS POSTNAME, a.ORGID AS ORGID, a.ORGNAME AS ORGNAME ", + "(SELECT PPOST.ID AS POSTID, PPOST.NAME AS POSTNAME, PORG.ID AS ORGID, PORG.NAME AS ORGNAME " + + "FROM ALONE_AUTH_ORGANIZATION PORG " + + "LEFT JOIN ALONE_AUTH_POST PPOST ON PORG.ID = PPOST.ORGANIZATIONID " + + "WHERE PPOST.EXTENDIS = '1' AND PORG.ID IN (" + pOrgIds + ") /* 查找父机构可用的岗位 */" + + "UNION ALL " + + "SELECT POST.ID AS POSTID, POST.NAME AS POSTNAME, ORG.ID AS ORGID, ORG.NAME AS ORGNAME " + + "FROM ALONE_AUTH_ORGANIZATION ORG " + + "LEFT JOIN ALONE_AUTH_POST POST ON ORG.ID = POST.ORGANIZATIONID " + "WHERE ORG.ID = '" + + orgId + "' /* 查找当前机构所有的岗位 */) a "); + query.setNoCount(); + query.setPagesize(1000); + DataResult result = query.search(); + List> list = result.getResultList(); + return list; + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + @Override + @Transactional + public List getParentOrgs(String orgid) { + String id = orgid; + List orgs = new ArrayList(); + while (id != null) { + Organization centity = getOrganizationEntity(id); + if (centity == null || centity.getParentid() == null || centity.getParentid().trim().length() <= 0) { + id = null; + } else { + id = centity.getParentid(); + } + if (centity != null) { + orgs.add(centity); + } + } + Collections.reverse(orgs); + return orgs; + } + + @Override + public List getOrgUsers(String orgid) { + DataQuery query = DataQuery.getInstance(1, "a.id as id ,a.name as name", + "ALONE_AUTH_USER a left join ALONE_AUTH_USERORG b on b.USERID=a.id left join ALONE_AUTH_ORGANIZATION c on c.ID=b.ORGANIZATIONID"); + query.setPagesize(1000); + Organization org = getOrganizationEntity(orgid); + query.addSqlRule(" and c.TREECODE like '" + org.getTreecode() + "%'"); + List list = new ArrayList<>(); + try { + for (Map node : query.search().getResultList()) { + list.add((String) node.get("ID")); + } + } catch (SQLException e) { + e.printStackTrace(); + return list; + } + return list; + } + +} \ No newline at end of file diff --git a/src/wcp-authority/src/main/java/com/farm/authority/service/impl/UserServiceImpl.java b/src/wcp-authority/src/main/java/com/farm/authority/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..1d20627 --- /dev/null +++ b/src/wcp-authority/src/main/java/com/farm/authority/service/impl/UserServiceImpl.java @@ -0,0 +1,518 @@ +package com.farm.authority.service.impl; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.transaction.Transactional; + +import org.springframework.stereotype.Service; + +import com.farm.authority.dao.OrganizationDaoInter; +import com.farm.authority.dao.PostDaoInter; +import com.farm.authority.dao.UserDaoInter; +import com.farm.authority.dao.UserorgDaoInter; +import com.farm.authority.dao.UserpostDaoInter; +import com.farm.authority.domain.Action; +import com.farm.authority.domain.AuthMenuImpl; +import com.farm.authority.domain.Organization; +import com.farm.authority.domain.Post; +import com.farm.authority.domain.User; +import com.farm.authority.domain.Userorg; +import com.farm.authority.domain.Userpost; +import com.farm.authority.service.OrganizationServiceInter; +import com.farm.authority.service.UserServiceInter; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.auth.domain.WebMenu; +import com.farm.core.auth.util.AuthenticateInter; +import com.farm.core.auth.util.AuthenticateProvider; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.time.TimeTool; +import com.farm.parameter.FarmParameterService; +import com.farm.util.validate.ValidUtils; + +/* * + *功能:用户服务层实现类 + *详细: + * + *版本:v0.1 + *作者:王东 + *日期:20141119144919 + *说明: + */ +@Service +public class UserServiceImpl implements UserServiceInter { + @Resource + private UserDaoInter userDaoImpl; + @Resource + private UserpostDaoInter userpostDaoImpl; + @Resource + private PostDaoInter postDaoImpl; + @Resource + private OrganizationDaoInter organizationDao; + @Resource + private OrganizationServiceInter organizationServiceImpl; + @Resource + private UserorgDaoInter userorgDaoImpl; + private AuthenticateInter authUtil = AuthenticateProvider.getInstance(); + + // private static final Logger log = + // Logger.getLogger(UserServiceImpl.class); + + @Override + @Transactional + public User insertUserEntity(User entity, LoginUser user, String orgId, String postIds) { + entity.setCuser(user.getId()); + entity.setCtime(TimeTool.getTimeDate14()); + entity.setMuser(user.getId()); + entity.setUtime(TimeTool.getTimeDate14()); + if (validateIsRepeatLoginName(entity.getLoginname(), null)) { + throw new RuntimeException("登录名已经存在!"); + } + entity.setPassword(authUtil.encodeLoginPasswordOnMd5( + FarmParameterService.getInstance().getParameter("config.default.password"), entity.getLoginname())); + userDaoImpl.insertEntity(entity); + + // 保存用户机构关系 + userorgDaoImpl.insertEntity(new Userorg("", orgId, entity.getId())); + + // 保存用户岗位关系 + String[] postIdArr = postIds.split(","); + for (String postId : postIdArr) { + userpostDaoImpl.insertEntity(new Userpost("", postId, entity.getId())); + } + return entity; + } + + @Override + @Transactional + public User insertUserEntity(User entity, LoginUser user) { + entity.setCuser(user.getId()); + entity.setCtime(TimeTool.getTimeDate14()); + entity.setMuser(user.getId()); + entity.setUtime(TimeTool.getTimeDate14()); + if (validateIsRepeatLoginName(entity.getLoginname(), null)) { + throw new RuntimeException("登录名已经存在!"); + } + if (entity.getPassword() == null || entity.getPassword().isEmpty()) { + entity.setPassword(FarmParameterService.getInstance().getParameter("config.default.password")); + } + entity.setPassword(authUtil.encodeLoginPasswordOnMd5(entity.getPassword(), entity.getLoginname())); + return userDaoImpl.insertEntity(entity); + } + + @Override + @Transactional + public User editUserEntity(User entity, LoginUser user, String orgId, String postIds) { + User entity2 = userDaoImpl.getEntity(entity.getId()); + if (validateIsRepeatLoginName(entity.getLoginname(), entity2.getId())) { + throw new RuntimeException("登录名已经存在!"); + } + if (entity2.getState().equals("2")) { + throw new RuntimeException("该用户已被删除,无法修改"); + } + entity2.setMuser(user.getId()); + entity2.setUtime(TimeTool.getTimeDate14()); + if (!ValidUtils.isEmptyString(entity.getLoginname())) { + entity2.setLoginname(entity.getLoginname()); + } + if (!ValidUtils.isEmptyString(entity.getState())) { + entity2.setState(entity.getState()); + } + if (!ValidUtils.isEmptyString(entity.getType())) { + entity2.setType(entity.getType()); + } + if (!ValidUtils.isEmptyString(entity.getImgid())) { + entity2.setImgid(entity.getImgid()); + } + if (!ValidUtils.isEmptyString(entity.getComments())) { + entity2.setComments(entity.getComments()); + } + if (!ValidUtils.isEmptyString(entity.getName())) { + entity2.setName(entity.getName()); + } + + userDaoImpl.editEntity(entity2); + + // 更新用户机构关系 + userorgDaoImpl.deleteEntitys(new DBRule("USERID", entity.getId(), "=").getDBRules()); + userorgDaoImpl.insertEntity(new Userorg("", orgId, entity.getId())); + + // 更新用户岗位关系 + userpostDaoImpl.deleteEntitys(new DBRule("USERID", entity.getId(), "=").getDBRules()); + String[] postIdArr = postIds.split(","); + for (String postId : postIdArr) { + userpostDaoImpl.insertEntity(new Userpost("", postId, entity.getId())); + } + return entity2; + } + + @Override + @Transactional + public boolean validateIsRepeatLoginName(String loginname, String userId) { + List list = null; + if (userId == null || userId.trim().equals("")) { + list = userDaoImpl.findUserByLoginName(loginname.trim()); + } else { + list = userDaoImpl.findUserByLoginName(loginname.trim(), userId); + } + return list.size() > 0; + } + + @Override + @Transactional + public void deleteUserEntity(String id, LoginUser user) { + String[] idArr = id.split(","); + for (int i = 0; i < idArr.length; i++) { + User entity2 = userDaoImpl.getEntity(idArr[i]); + entity2.setMuser(user.getId()); + entity2.setUtime(TimeTool.getTimeDate14()); + entity2.setState("2"); + entity2.setLoginname(entity2.getId()); + userDaoImpl.editEntity(entity2); + } + } + + @Override + @Transactional + public User getUserEntity(String id) { + if (id == null) { + return null; + } + return userDaoImpl.getEntity(id); + } + + @Override + @Transactional + public DataQuery createUserSimpleQuery(DataQuery query, LoginUser currentUser) { + DataQuery dbQuery = DataQuery.init(query, + "ALONE_AUTH_USER A " + "LEFT JOIN ALONE_AUTH_USERORG B ON A.ID = B.USERID " + + "LEFT JOIN ALONE_AUTH_ORGANIZATION A3 ON B.ORGANIZATIONID = A3.ID", + "A.ID AS ID,A.LOGINTIME AS LOGINTIME,A.LOGINNAME AS LOGINNAME,A.STATE AS STATE," + + "A.TYPE AS TYPE,A.COMMENTS AS COMMENTS,A.NAME AS NAME,A3.NAME AS ORGNAME"); + + User entity = userDaoImpl.getEntity(currentUser.getId()); + + if (entity.getType() != null && (!entity.getType().equals("3"))) { + dbQuery.addRule(new DBRule("A.TYPE", 3, "!=")); + } + return dbQuery; + } + + // ---------------------------------------------------------------------------------- + + @Override + @Transactional + public void initDefaultPassWord(String userid, LoginUser currentUser) { + User entity2 = userDaoImpl.getEntity(userid); + entity2.setMuser(currentUser.getId()); + entity2.setUtime(TimeTool.getTimeDate14()); + entity2.setPassword(authUtil.encodeLoginPasswordOnMd5( + FarmParameterService.getInstance().getParameter("config.default.password"), entity2.getLoginname())); + userDaoImpl.editEntity(entity2); + } + + @Override + @Transactional + public User getUserByLoginName(String loginName) { + List users = userDaoImpl.findUserByLoginName(loginName); + if (users.size() <= 0) { + return null; + } + if (users.size() > 1) { + throw new RuntimeException("该登录名返回了多个用户!"); + } + return users.get(0); + } + + @Override + @Transactional + public void setLoginTime(String userId) { + User entity2 = userDaoImpl.getEntity(userId); + entity2.setLogintime(TimeTool.getTimeDate14()); + userDaoImpl.editEntity(entity2); + } + + @Override + @Transactional + public DataQuery createUserPostQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, + "ALONE_AUTH_ORGANIZATION ORG " + + "INNER JOIN ALONE_AUTH_USERORG USERORG ON ORG.ID = USERORG.ORGANIZATIONID " + + "INNER JOIN ALONE_AUTH_USER USER ON USERORG.USERID = USER.ID", + "USER.ID AS USERID,USER.LOGINTIME AS LOGINTIME,USER.NAME AS USERNAME,USER.STATE AS USERSTATE"); + dbQuery.addRule(new DBRule("USER.STATE", "1", "=")); + return dbQuery; + } + + @Override + @Transactional + public List getUserActions(String userId) { + DataQuery dbQuery = DataQuery.getInstance(1, "d.id,d.AUTHKEY,d.NAME,d.COMMENTS,d.STATE,d.CHECKIS,d.LOGINIS", + "alone_auth_userpost a LEFT JOIN alone_auth_postaction b ON a.POSTID =b.POSTID LEFT JOIN alone_auth_actiontree c ON b.MENUID=c.ID LEFT JOIN alone_auth_action d ON d.ID=c.ACTIONID"); + dbQuery.addRule(new DBRule("d.STATE", "1", "=")); + dbQuery.addRule(new DBRule("a.USERID", userId, "=")); + dbQuery.setDistinct(true); + dbQuery.setPagesize(5000); + List list = new ArrayList(); + try { + for (Map node : dbQuery.search().getResultList()) { + Action action = new Action(); + action.setAuthkey(node.get("D_AUTHKEY") != null ? node.get("D_AUTHKEY").toString() : null); + action.setId(node.get("D_ID") != null ? node.get("D_ID").toString() : null); + action.setName(node.get("D_NAME") != null ? node.get("D_NAME").toString() : null); + action.setComments(node.get("D_COMMENTS") != null ? node.get("D_COMMENTS").toString() : null); + action.setState(node.get("D_STATE") != null ? node.get("D_STATE").toString() : null); + action.setCheckis(node.get("D_CHECKIS") != null ? node.get("D_CHECKIS").toString() : null); + action.setLoginis(node.get("D_LOGINIS") != null ? node.get("D_LOGINIS").toString() : null); + list.add(action); + } + } catch (SQLException e) { + throw new RuntimeException(); + } + return list; + } + + @Override + @Transactional + public List getUserMenus(String userId) { + DataQuery query = DataQuery.getInstance(1, "SORT,ID,PARENTID,NAME,TYPE,STATE,ICON,IMGID,PARAMS,AUTHKEY", + "(SELECT c.SORT,c.ID,c.PARENTID,c.NAME,c.TYPE,c.STATE,c.ICON,c.IMGID,c.PARAMS,d.AUTHKEY FROM alone_auth_userpost a LEFT JOIN alone_auth_postaction b ON a.POSTID =b.POSTID LEFT JOIN alone_auth_actiontree c ON b.MENUID=c.ID LEFT JOIN alone_auth_action d ON d.ID=c.ACTIONID WHERE (d.STATE = '1'||d.STATE IS NULL) and a.userid='" + + userId + "' and c.type!='3' order by LENGTH(c.TREECODE),c.SORT asc) e"); + List menus = new ArrayList(); + query.setPagesize(1000); + query.setNoCount(); + query.setDistinct(true); + try { + for (Map map : query.search().getResultList()) { + AuthMenuImpl node = new AuthMenuImpl(); + node.setIcon(map.get("ICON") != null ? map.get("ICON").toString() : null); + node.setId(map.get("ID") != null ? map.get("ID").toString() : null); + node.setName(map.get("NAME") != null ? map.get("NAME").toString() : null); + node.setParams(map.get("PARAMS") != null ? map.get("PARAMS").toString() : null); + node.setParentid(map.get("PARENTID") != null ? map.get("PARENTID").toString() : null); + node.setUrl(map.get("AUTHKEY") != null ? map.get("AUTHKEY").toString() : null); + menus.add(node); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + return menus; + } + + @Override + @Transactional + public List getUserPosts(String userId) { + List userposts = userpostDaoImpl.selectEntitys(new DBRule("USERID", userId, "=").getDBRules()); + List list = new ArrayList(); + for (Userpost userPost : userposts) { + list.add(postDaoImpl.getEntity(userPost.getPostid())); + } + return list; + } + + @Override + @Transactional + public boolean editLoginPassword(String loginname, String oldPassword, String newPassword) { + User user = getUserByLoginName(loginname); + if (user == null) { + throw new RuntimeException("不存在该用户!"); + } + if (authUtil.encodeLoginPasswordOnMd5(oldPassword, loginname).equals(user.getPassword())) { + // 验证成功,修改密码 + user.setPassword(authUtil.encodeLoginPasswordOnMd5(newPassword, loginname)); + userDaoImpl.editEntity(user); + return true; + } else { + throw new RuntimeException("原密码错误!"); + } + } + + @Override + @Transactional + public List getUserPostIds(String userId) { + List userposts = userpostDaoImpl.selectEntitys(new DBRule("USERID", userId, "=").getDBRules()); + List list = new ArrayList(); + for (Userpost userPost : userposts) { + list.add(userPost.getPostid()); + } + return list; + } + + @Override + @Transactional + public Organization getUserOrganization(String userId) { + return getOrg(userId); + } + + @Override + @Transactional + public User registUser(final User user) { + LoginUser noneuser = new LoginUser() { + @Override + public String getName() { + return user.getName(); + } + + @Override + public String getLoginname() { + return user.getLoginname(); + } + + @Override + public String getId() { + return user.getLoginname(); + } + }; + String defaultOrg = FarmParameterService.getInstance().getParameter("config.user.org.default.id"); + String defaultpost = FarmParameterService.getInstance().getParameter("config.user.post.default.id"); + return insertUserEntity(user, noneuser, defaultOrg, defaultpost); + } + + @Override + @Transactional + public User registUser(final User user, String orgid) { + // 保存新增用户 + LoginUser noneuser = new LoginUser() { + @Override + public String getName() { + return user.getName(); + } + + @Override + public String getLoginname() { + return user.getLoginname(); + } + + @Override + public String getId() { + return user.getLoginname(); + } + }; + + String defaultOrg = ""; + String showOrg = FarmParameterService.getInstance().getParameter("config.regist.showOrg"); + if (showOrg != null && !showOrg.isEmpty() && showOrg.equals("true") && orgid != null && !orgid.isEmpty()) { + defaultOrg = orgid; + } else { + defaultOrg = FarmParameterService.getInstance().getParameter("config.user.org.default.id"); + } + + String defaultpost = FarmParameterService.getInstance().getParameter("config.user.post.default.id"); + User user2 = insertUserEntity(user, noneuser, defaultOrg, defaultpost); + return user2; + } + + @Override + public Organization getOrg(String id) { + try { + DataQuery query = DataQuery.getInstance(1, + "ORG.ID as ID,ORG.TYPE as TYPE,ORG.SORT as SORT,ORG.PARENTID as PARENTID,ORG.MUSER as MUSER," + + "ORG.CUSER as CUSER,ORG.STATE as STATE,ORG.UTIME as UTIME,ORG.CTIME as CTIME," + + "ORG.COMMENTS as COMMENTS,ORG.NAME as NAME,ORG.TREECODE as TREECODE", + "ALONE_AUTH_USERORG USERORG " + + "INNER JOIN ALONE_AUTH_ORGANIZATION ORG ON USERORG.ORGANIZATIONID = ORG.ID"); + query.addRule(new DBRule("USERORG.USERID", id, "=")); + query.setPagesize(1000); + query.setNoCount(); + DataResult result = query.search(); + List orgList = result.getObjectList(Organization.class); + if (orgList.size() > 0) { + return (Organization) orgList.get(0); + } + return null; + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public List getPost(String id) { + // ID,EXTENDIS,NAME,ORGANIZATIONID,PSTATE,EUSER,EUSERNAME,CUSER,CUSERNAME,ETIME,CTIME + try { + DataQuery query = DataQuery.getInstance(1, + "POST.ID AS ID,POST.EXTENDIS AS EXTENDIS,POST.NAME AS NAME,POST.ORGANIZATIONID AS ORGANIZATIONID,POST.PSTATE AS PSTATE,POST.EUSER AS EUSER,POST.EUSERNAME AS EUSERNAME,POST.CUSER AS CUSER,POST.CUSERNAME AS CUSERNAME,POST.ETIME AS ETIME,POST.CTIME AS CTIME", + "ALONE_AUTH_USERPOST USERPOST " + "LEFT JOIN ALONE_AUTH_POST POST ON USERPOST.POSTID = POST.ID"); + query.addRule(new DBRule("USERPOST.USERID", id, "=")); + DataResult result = query.search(); + result.getObjectList(Post.class); + return result.getObjectList(Post.class); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public DataQuery createOrgUserQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, + "ALONE_AUTH_ORGANIZATION ORG " + + "INNER JOIN ALONE_AUTH_USERORG USERORG ON ORG.ID = USERORG.ORGANIZATIONID " + + "INNER JOIN ALONE_AUTH_USER USER ON USERORG.USERID = USER.ID", + "USER.ID AS USERID,USER.LOGINTIME AS LOGINTIME,USER.NAME AS USERNAME,USER.STATE AS USERSTATE"); + dbQuery.addRule(new DBRule("USER.STATE", "1", "=")); + return dbQuery; + } + + @Override + @Transactional + public void editCurrentUser(String id, String name, String photoid, String orgid) { + // 更新用户 + User user = userDaoImpl.getEntity(id); + user.setName(name); + user.setImgid(photoid); + + // 更新机构 + String showOrg = FarmParameterService.getInstance().getParameter("config.regist.showOrg"); + if (showOrg != null && !showOrg.isEmpty() && showOrg.equals("true") && orgid != null && !orgid.isEmpty()) { + Userorg userorg = userorgDaoImpl.getEntityByUserId(user.getId()); + userorg.setOrganizationid(orgid); + + // 删除岗位(岗位暂时无用,wd说的) + userpostDaoImpl.deleteEntitys(new DBRule("userid", id, "=").getDBRules()); + } + } + + @Override + @Transactional + public void editCurrentUserPwdCommit(String id, String password, String newPassword) { + User user = userDaoImpl.getEntity(id); + String oldPwd = authUtil.encodeLoginPasswordOnMd5(password, user.getLoginname()); + if (!user.getPassword().equals(oldPwd)) { + throw new RuntimeException("旧密码错误!"); + } + + String newPwd = authUtil.encodeLoginPasswordOnMd5(newPassword, user.getLoginname()); + user.setPassword(newPwd); + userDaoImpl.editEntity(user); + } + + @Override + @Transactional + public boolean validCurrentUserPwd(String id, String password) { + User user = userDaoImpl.getEntity(id); + String pwdForMd5 = authUtil.encodeLoginPasswordOnMd5(password, user.getLoginname()); + if (!user.getPassword().equals(pwdForMd5)) { + return false; + } + return true; + } + + @Override + @Transactional + public void editCurrentUser(String id, String name, String photoid) { + User user = userDaoImpl.getEntity(id); + user.setName(name); + user.setImgid(photoid); + } + + @Override + public Integer getUsersNum() { + return userDaoImpl.getUsersNum(); + } +} diff --git a/src/wcp-doc-so/pom.xml b/src/wcp-doc-so/pom.xml new file mode 100644 index 0000000..78d8867 --- /dev/null +++ b/src/wcp-doc-so/pom.xml @@ -0,0 +1,97 @@ + + 4.0.0 + com.farm.wcp + wcp-doc-so + ${wcp.version} + 知识库增量开源版实现 + + 3.2.0 + + UTF-8 + UTF-8 + + UTF-8 + + + + com.farm + farm-core + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + com.farm + wcp-quartz + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + com.farm + wcp-parameter + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + com.farm + wcp-lucene + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + com.farm + wcp-authority + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + org.jsoup + jsoup + 1.7.3 + + + + + commons-fileupload + commons-fileupload + 1.3.1 + + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + + 开源版引入 + \ No newline at end of file diff --git a/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/FarmTypePopServerInter.java b/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/FarmTypePopServerInter.java new file mode 100644 index 0000000..f5b2661 --- /dev/null +++ b/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/FarmTypePopServerInter.java @@ -0,0 +1,24 @@ +package com.farm.doc.server.plus; + +import java.util.List; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.doc.server.plus.domain.DocAudit; +import com.farm.doc.server.plus.domain.Doctypepop; + +public interface FarmTypePopServerInter { + public DocAudit auditHandleForDocCreate(String docid, String textid, LoginUser user); + + public String getMessageForNeedAudit(String title); + + public String getMessageTitleForNeedAudit(String title); + + public DocAudit auditHandleForDocEdit(String docid, String textid, LoginUser user); + + public void delAuditInfo(String docid); + + public void getTypePopsHandle(List poplist, String typereadpop, String typewritepop, String auditpop, + String typeid); + + public void delTypePop(String typeId); +} diff --git a/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/domain/DocAudit.java b/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/domain/DocAudit.java new file mode 100644 index 0000000..a283ae3 --- /dev/null +++ b/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/domain/DocAudit.java @@ -0,0 +1,91 @@ +package com.farm.doc.server.plus.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; +@Entity(name = "DocAudit") +@Table(name = "farm_doc_audit") +public class DocAudit implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "DOCID", length = 32, nullable = false) + private String docid; + @Column(name = "TEXTID", length = 32, nullable = false) + private String textid; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + + public String getDocid() { + return this.docid; + } + public void setDocid(String docid) { + this.docid = docid; + } + public String getTextid() { + return this.textid; + } + public void setTextid(String textid) { + this.textid = textid; + } + public String getId() { + return this.id; + } + public void setId(String id) { + this.id = id; + } + public String getPcontent() { + return this.pcontent; + } + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + public String getPstate() { + return this.pstate; + } + public void setPstate(String pstate) { + this.pstate = pstate; + } + public String getCuser() { + return this.cuser; + } + public void setCuser(String cuser) { + this.cuser = cuser; + } + public String getCusername() { + return this.cusername; + } + public void setCusername(String cusername) { + this.cusername = cusername; + } + public String getEtime() { + return this.etime; + } + public void setEtime(String etime) { + this.etime = etime; + } + public String getCtime() { + return this.ctime; + } + public void setCtime(String ctime) { + this.ctime = ctime; + } +} \ No newline at end of file diff --git a/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/domain/Doctypepop.java b/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/domain/Doctypepop.java new file mode 100644 index 0000000..7bc1c87 --- /dev/null +++ b/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/domain/Doctypepop.java @@ -0,0 +1,78 @@ +package com.farm.doc.server.plus.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +@Entity(name = "DocTypePop") +@Table(name = "farm_doctype_pop") +public class Doctypepop implements java.io.Serializable { + private static final long serialVersionUID = 1L; + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "TYPEID", length = 32, nullable = false) + private String typeid; + @Column(name = "ONAME", length = 64, nullable = false) + private String oname; + @Column(name = "POPTYPE", length = 1, nullable = false) + private String poptype; + @Column(name = "FUNTYPE", length = 1, nullable = false) + private String funtype; + @Column(name = "OID", length = 32, nullable = false) + private String oid; + + public String getTypeid() { + return this.typeid; + } + + public void setTypeid(String typeid) { + this.typeid = typeid; + } + + public String getOname() { + return this.oname; + } + + public void setOname(String oname) { + this.oname = oname; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPoptype() { + return this.poptype; + } + + public void setPoptype(String poptype) { + this.poptype = poptype; + } + + public String getFuntype() { + return this.funtype; + } + + public void setFuntype(String funtype) { + this.funtype = funtype; + } + + public String getOid() { + return this.oid; + } + + public void setOid(String oid) { + this.oid = oid; + } +} \ No newline at end of file diff --git a/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/impl/FarmTypePopServerImpl.java b/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/impl/FarmTypePopServerImpl.java new file mode 100644 index 0000000..a65ab04 --- /dev/null +++ b/src/wcp-doc-so/src/main/java/com/farm/doc/server/plus/impl/FarmTypePopServerImpl.java @@ -0,0 +1,47 @@ +package com.farm.doc.server.plus.impl; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.doc.server.plus.FarmTypePopServerInter; +import com.farm.doc.server.plus.domain.DocAudit; +import com.farm.doc.server.plus.domain.Doctypepop; + +@Service +public class FarmTypePopServerImpl implements FarmTypePopServerInter { + @Override + public DocAudit auditHandleForDocCreate(String docid, String textid, LoginUser user) { + return new DocAudit(); + } + + @Override + public String getMessageForNeedAudit(String title) { + return new String(); + } + + @Override + public String getMessageTitleForNeedAudit(String title) { + return new String(); + } + + @Override + public DocAudit auditHandleForDocEdit(String docid, String textid, LoginUser user) { + return new DocAudit(); + } + + @Override + public void delAuditInfo(String docid) { + } + + @Override + public void getTypePopsHandle(List poplist, String typereadpop, String typewritepop, String auditpop, + String typeid) { + } + + @Override + public void delTypePop(String typeId) { + } + +} diff --git a/src/wcp-doc/pom.xml b/src/wcp-doc/pom.xml new file mode 100644 index 0000000..83767f6 --- /dev/null +++ b/src/wcp-doc/pom.xml @@ -0,0 +1,107 @@ + + 4.0.0 + com.farm + wcp-doc + ${wcp.version} + 文档系统 + + 3.2.0 + + UTF-8 + UTF-8 + + UTF-8 + + + + javax.mail + javax.mail-api + 1.5.5 + + + com.sun.mail + javax.mail + 1.5.5 + + + com.farm.wcp + wcp-doc-so + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + com.farm + wcp-quartz + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + com.farm + farm-core + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + com.farm + wcp-lucene + ${wcp.version} + + + javax.servlet.jsp + jsp-api + + + + + org.jsoup + jsoup + 1.7.3 + + + + commons-fileupload + commons-fileupload + 1.3.1 + + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.1 + + + + true + true + + + + + + + \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocIndexQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocIndexQuery.java new file mode 100644 index 0000000..8b32c79 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocIndexQuery.java @@ -0,0 +1,62 @@ +package com.farm.doc.controller; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.server.FarmDocManagerInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; + +/** + * 全文索引 + * + * @author zhanghc + * + */ +@RequestMapping("/docIndex") +@Controller +public class ActionFarmDocIndexQuery extends WebUtils { + @Resource + private FarmDocManagerInter farmDocManagerImpl; + private static final Logger log = Logger.getLogger(ActionFarmDocIndexQuery.class); + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance().returnModelAndView("doc/DocIndexLayout"); + } + + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, HttpServletRequest request) { + try { + query = EasyUiUtils.formatGridQuery(request, query); + DataResult result = farmDocManagerImpl.createSimpleDocQuery(query).search(); + result.runDictionary("1:开放,0:禁用,2:待审核", "STATE"); + result.runDictionary("1:HTML,2:TXT", "DOMTYPE"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "WRITEPOP"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "READPOP"); + result.runformatTime("PUBTIME", "yyyy-MM-dd HH:mm:ss"); + return ViewMode.getInstance().putAttrs(EasyUiUtils.formatGridData(result)).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocQuery.java new file mode 100644 index 0000000..dd355a7 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocQuery.java @@ -0,0 +1,310 @@ +package com.farm.doc.controller; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.time.TimeTool; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDoctext; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.doc.server.FarmDocManagerInter; +import com.farm.doc.server.FarmDocOperateRightInter; +import com.farm.doc.server.FarmDocOperateRightInter.POP_TYPE; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; + +/** + * 文档管理 + * + * @author autoCode + * + */ +@RequestMapping("/doc") +@Controller +public class ActionFarmDocQuery extends WebUtils { + @Resource + private FarmDocManagerInter farmDocManagerImpl; + @Resource + private FarmDocOperateRightInter farmDocOperateRightImpl; + @Resource + private FarmDocgroupManagerInter farmDocgroupManagerImpl; + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + + private static final Logger log = Logger.getLogger(ActionFarmDocQuery.class); + + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, HttpServletRequest request) { + try { + query = EasyUiUtils.formatGridQuery(request, query); + DataResult result = farmDocManagerImpl.createSimpleDocQuery(query).search(); + result.runDictionary("1:开放,0:禁用,2:待审核", "STATE"); + result.runDictionary("1:HTML,2:TXT,3:html站点,4:小组首页,5:资源文件", "DOMTYPE"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "WRITEPOP"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "READPOP"); + result.runformatTime("PUBTIME", "yyyy-MM-dd HH:mm:ss"); + return ViewMode.getInstance().putAttrs(EasyUiUtils.formatGridData(result)).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance().returnModelAndView("doc/DocTResult"); + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(Doc entity, HttpSession session, String content) { + try { + DocEntire doc = new DocEntire(entity); + Doc dbdoc = farmDocManagerImpl.getDocOnlyBean(entity.getId()); + doc.getDoc().setCuser(dbdoc.getCuser()); + doc.getDoc().setCusername(dbdoc.getCusername()); + doc.setTexts(new FarmDoctext(content, TimeTool.getTimeDate14(), TimeTool.getTimeDate14(), + getCurrentUser(session).getName(), getCurrentUser(session).getId(), + getCurrentUser(session).getName(), getCurrentUser(session).getId(), "1")); + //doc = farmDocManagerImpl.editDoc(doc, "系统管理员修改", getCurrentUser(session)); + //返回新的doc页面会使得连接丢失,不知道是不是对象太大导致无法获得连接 + farmDocManagerImpl.editDoc(doc, "系统管理员修改", getCurrentUser(session)); + return ViewMode.getInstance().setOperate(OperateType.ADD).putAttr("entity", doc).returnObjMode(); + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD).setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/FarmDocRighteditCommit") + @ResponseBody + public Map rightEditCommit(Doc entity, HttpSession session, String ids) { + try { + for (String id : parseIds(ids)) { + entity = farmDocOperateRightImpl.editDocRight(id, POP_TYPE.getEnum(entity.getReadpop()), + POP_TYPE.getEnum(entity.getWritepop()), getCurrentUser(session)); + } + return ViewMode.getInstance().setOperate(OperateType.ADD).returnObjMode(); + + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD).setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(Doc entity, HttpSession session, String content, String doctypeId) { + try { + DocEntire doc = new DocEntire(entity); + // 构造文档text + doc.setTexts(new FarmDoctext(content, TimeTool.getTimeDate14(), TimeTool.getTimeDate14(), + getCurrentUser(session).getName(), getCurrentUser(session).getId(), + getCurrentUser(session).getName(), getCurrentUser(session).getId(), "1")); + // 构造分类 + if (doctypeId != null && !doctypeId.isEmpty()) { + doc.setType(farmDocTypeManagerImpl.getType(doctypeId)); + } + + if ("".equals(doc.getDoc().getImgid())) { + doc.getDoc().setImgid(null); + } + doc = farmDocManagerImpl.createDoc(doc, getCurrentUser(session)); + return ViewMode.getInstance().putAttr("entity", doc).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + farmDocManagerImpl.deleteDocNoPop(id, getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + e.printStackTrace(); + log.error(e.toString()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * (修改文档权限) + * + * @return + */ + @RequestMapping("/FarmDocRightedit") + public ModelAndView rightEdit(FarmDoctype doctype, String ids) { + try { + if (doctype != null && doctype.getId() != null && doctype.getId().trim().length() > 0) { + } + @SuppressWarnings("deprecation") + DocEntire entity = farmDocManagerImpl.getDoc(ids); + doctype = entity.getType(); + RequestMode pageset = new RequestMode(); + pageset.setOperateType(2); + + return ViewMode.getInstance().putAttr("entity", entity).putAttr("doctype", doctype) + .putAttr("pageset", pageset).returnModelAndView("doc/DocTRightSetPage"); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnModelAndView("doc/DocTRightSetPage"); + } + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @SuppressWarnings("deprecation") + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, HttpServletRequest request, DataQuery query, HttpSession session, + FarmDoctype doctype, String ids) { + try { + query = EasyUiUtils.formatGridQuery(request, query); + query.setPagesize(100); + query.addRule(new DBRule("b.userid", getCurrentUser(session).getId(), "=")); + DataResult result = farmDocgroupManagerImpl.createFarmDocgroupQueryJoinUser(query).search(); + String typeid = null; + if (doctype != null && doctype.getId() != null && doctype.getId().trim().length() > 0) { + typeid = doctype.getId(); + } + switch (pageset.getOperateType()) { + case (1): {// 新增 + doctype = farmDocTypeManagerImpl.getType(typeid); + DocEntire entity = new DocEntire(new Doc()); + entity.getDoc() + .setPubtime(TimeTool.getFormatTimeDate12(TimeTool.getTimeDate14(), "yyyy-MM-dd HH:mm:ss")); + entity.getDoc().setAuthor(getCurrentUser(session).getName()); + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("entity", entity) + .putAttr("doctype", doctype).putAttr("result", result).returnModelAndView("doc/DocTForm"); + } + case (0): {// 展示 + DocEntire entity = farmDocManagerImpl.getDoc(ids); + if (entity.getDoc().getPubtime() != null && entity.getDoc().getPubtime().trim().length() > 0) { + entity.getDoc().setPubtime( + TimeTool.getFormatTimeDate12(entity.getDoc().getPubtime(), "yyyy-MM-dd HH:mm:ss")); + } + doctype = entity.getType(); + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", farmDocManagerImpl.getDoc(ids)).putAttr("result", result) + .putAttr("doctype", doctype).returnModelAndView("doc/DocTForm"); + } + case (2): {// 修改 + DocEntire entity = farmDocManagerImpl.getDoc(ids); + if (entity.getDoc().getPubtime() != null && entity.getDoc().getPubtime().trim().length() > 0) { + entity.getDoc().setPubtime( + TimeTool.getFormatTimeDate12(entity.getDoc().getPubtime(), "yyyy-MM-dd HH:mm:ss")); + } + doctype = entity.getType(); + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", farmDocManagerImpl.getDoc(ids)).putAttr("result", result) + .putAttr("doctype", doctype).returnModelAndView("doc/DocTForm"); + } + default: + break; + } + } catch (Exception e) { + e.printStackTrace(); + return ViewMode.getInstance().setError(e + e.getMessage()).returnModelAndView("doc/DocTForm"); + } + return ViewMode.getInstance().returnModelAndView("doc/DocTForm"); + } + + @RequestMapping("/toKindEditor") + public ModelAndView toKindEditor(HttpSession session) { + return ViewMode.getInstance().returnModelAndView("doc/DocTkindeditor"); + } + + @RequestMapping("/toManagerDocMsg") + public ModelAndView toManagerDocMsg(HttpSession session, String ids) { + return ViewMode.getInstance().putAttr("ids", ids).returnModelAndView("doc/DocTCommentSetPage"); + } + + /** + * 删除附件 + * @return Map + */ + @RequestMapping("/delImg") + @ResponseBody + public Map delImg(String imgid) { + try { + farmDocManagerImpl.delImg(imgid); + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.toString()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 移动文档到指定分类 + * @param imgid + * @return + * Map + */ + @RequestMapping("/move2Type") + @ResponseBody + public Map move2Type(String docIds, String typeId) { + try { + farmDocManagerImpl.move2Type(docIds, typeId); + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.toString()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocfileQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocfileQuery.java new file mode 100644 index 0000000..0ccc6dd --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocfileQuery.java @@ -0,0 +1,156 @@ +package com.farm.doc.controller; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDocfile; +import com.farm.doc.server.FarmFileManagerInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; + +/** + * 文件 + * + * @author autoCode + * + */ +@RequestMapping("/docfile") +@Controller +public class ActionFarmDocfileQuery extends WebUtils { + private static final Logger log = Logger.getLogger(ActionFarmDocfileQuery.class); + @Resource + private FarmFileManagerInter farmFileManagerImpl; + + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, HttpServletRequest request) { + query = EasyUiUtils.formatGridQuery(request, query); + try { + query = EasyUiUtils.formatGridQuery(request, query); + DataQuery dbQuery = DataQuery.init(query, "farm_docfile", + "id,DIR,TYPE,NAME,EXNAME,LEN,FILENAME,PSTATE,PCONTENT"); + DataResult result = dbQuery.search(); + result.runDictionary("1:使用,0:临时", "PSTATE"); + result.runDictionary("1:图片,2:资源,3:压缩,0:其他", "TYPE"); + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(result)) + .returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance() + .returnModelAndView("doc/DocfileResult"); + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(FarmDocfile entity, HttpSession session) { + try { + return ViewMode.getInstance().setOperate(OperateType.ADD).returnObjMode(); + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance() + .setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(HttpSession session) { + try { + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + farmFileManagerImpl.delFile(id, + getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (1): {// 新增 + return ViewMode.getInstance().putAttr("pageset", pageset) + .returnModelAndView("doc/DocfileForm"); + } + case (0): {// 展示 + FarmDocfile entity = farmFileManagerImpl.getFile(ids); + entity.setUrl(farmFileManagerImpl.getFileURL(ids)); + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", entity) + .returnModelAndView("doc/DocfileForm"); + } + case (2): {// 修改 + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", farmFileManagerImpl.getFile(ids)) + .returnModelAndView("doc/DocfileForm"); + } + default: + break; + } + } catch (Exception e) { + return ViewMode.getInstance().setError(e + e.getMessage()) + .returnModelAndView("doc/DocfileForm"); + } + return ViewMode.getInstance().returnModelAndView( + "parameter/DocfileForm.jsp"); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocgroupQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocgroupQuery.java new file mode 100644 index 0000000..987e4f1 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocgroupQuery.java @@ -0,0 +1,159 @@ +package com.farm.doc.controller; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDocgroup; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.doc.server.FarmFileManagerInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; + +/** + * 工作小组 + * + * @author autoCode + * + */ +@RequestMapping("/docgroup") +@Controller +public class ActionFarmDocgroupQuery extends WebUtils { + private static final Logger log = Logger.getLogger(ActionFarmDocgroupQuery.class); + @Resource + private FarmDocgroupManagerInter farmDocgroupManagerImpl; + @Resource + private FarmFileManagerInter farmFileManagerImpl; + + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, HttpServletRequest request) { + query = EasyUiUtils.formatGridQuery(request, query); + try { + query = EasyUiUtils.formatGridQuery(request, query); + DataResult result = farmDocgroupManagerImpl.createFarmDocgroupQuery(query).search(); + result.runDictionary("1:是,0:否", "JOINCHECK"); + result.runDictionary("1:可用,0:禁用", "PSTATE"); + return ViewMode.getInstance().putAttrs(EasyUiUtils.formatGridData(result)).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance().returnModelAndView("doc/DocgroupResult"); + } + + // + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(FarmDocgroup entity, HttpSession session) { + try { + entity = farmDocgroupManagerImpl.editDocGroup(entity.getId(), entity.getGroupname(), entity.getGrouptag(), + entity.getGroupimg(), entity.getJoincheck().equals("1"), entity.getGroupnote(), + getCurrentUser(session)); + + return ViewMode.getInstance().setOperate(OperateType.ADD).putAttr("entity", entity).returnObjMode(); + + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD).setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(FarmDocgroup entity, HttpSession session) { + try { + entity = farmDocgroupManagerImpl.creatDocGroup(entity.getGroupname(), entity.getGrouptag(), + entity.getGroupimg(), entity.getJoincheck().equals("1"), entity.getGroupnote(), + getCurrentUser(session)); + return ViewMode.getInstance().putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + farmDocgroupManagerImpl.deleteFarmDocgroupEntity(id, getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (1): {// 新增 + return ViewMode.getInstance().putAttr("pageset", pageset).returnModelAndView("doc/DocgroupForm"); + } + case (0): {// 展示 + FarmDocgroup entity = farmDocgroupManagerImpl.getFarmDocgroupEntity(ids); + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("entity", entity) + .putAttr("imgurl", farmFileManagerImpl.getFileURL(entity.getGroupimg())) + .returnModelAndView("doc/DocgroupForm"); + } + case (2): {// 修改 + FarmDocgroup entity = farmDocgroupManagerImpl.getFarmDocgroupEntity(ids); + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("entity", entity) + .putAttr("imgurl", farmFileManagerImpl.getFileURL(entity.getGroupimg())) + .returnModelAndView("doc/DocgroupForm"); + } + case (3): {// 查看小组 + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("ids", ids) + .returnModelAndView("doc/DocgroupuserGrid"); + } + default: + break; + } + } catch (Exception e) { + return ViewMode.getInstance().setError(e + e.getMessage()).returnModelAndView("doc/DocgroupForm"); + } + return ViewMode.getInstance().returnModelAndView("doc/DocgroupForm"); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocgroupUserQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocgroupUserQuery.java new file mode 100644 index 0000000..00edc69 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocgroupUserQuery.java @@ -0,0 +1,205 @@ +package com.farm.doc.controller; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDocgroupUser; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; + +/** + * 工作小组成员 + * + * @author autoCode + * + */ +@RequestMapping("/docgroupUser") +@Controller +public class ActionFarmDocgroupUserQuery extends WebUtils { + private static final Logger log = Logger.getLogger(ActionFarmDocgroupUserQuery.class); + @Resource + private FarmDocgroupManagerInter farmDocgroupManagerImpl; + + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, HttpServletRequest request, String ids) { + query = EasyUiUtils.formatGridQuery(request, query); + try { + query = EasyUiUtils.formatGridQuery(request, query); + if (ids != null) { + query.addRule(new DBRule("GROUPID", ids, "=")); + } + DataResult result = farmDocgroupManagerImpl.createFarmDocgroupUserSimpleQuery(query).search(); + result.runDictionary("1:是,0:否", "LEADIS"); + result.runDictionary("1:是,0:否", "EDITIS"); + result.runDictionary("1:在用,0:邀请,2:删除,3:申请", "PSTATE"); + return ViewMode.getInstance().putAttrs(EasyUiUtils.formatGridData(result)).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance().returnModelAndView("doc/DocgroupUserResult"); + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(FarmDocgroupUser entity, HttpSession session) { + try { + entity = farmDocgroupManagerImpl.editMinFarmDocgroupUserEntity(entity, getCurrentUser(session)); + + return ViewMode.getInstance().setOperate(OperateType.ADD).putAttr("entity", entity).returnObjMode(); + + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD).setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(String userids, String ids, HttpSession session) { + try { + for (String uerId : parseIds(userids)) { + if (!farmDocgroupManagerImpl.isJoinGroupByUser(ids, uerId)) { + FarmDocgroupUser groupUser = farmDocgroupManagerImpl.applyGroup(ids, uerId, "系统管理员操作", + getCurrentUser(session)); + farmDocgroupManagerImpl.agreeJoinApply(groupUser.getId(), getCurrentUser(session)); + farmDocgroupManagerImpl.setEditorForGroup(groupUser.getId(), getCurrentUser(session)); + } + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 设置管理员 + * + * @return + */ + @RequestMapping("/FarmDocgroupUserSetAdmin") + @ResponseBody + public Map adminSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + farmDocgroupManagerImpl.setAdminForGroup(id, getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 取消管理员 + * + * @return + */ + @RequestMapping("/FarmDocgroupUserResetAdmin") + @ResponseBody + public Map reAdminSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + FarmDocgroupUser groupUser = farmDocgroupManagerImpl.getFarmDocgroupUserEntity(id); + if (groupUser.getUserid().equals(getCurrentUser(session).getId())) { + throw new RuntimeException("不能取消自己为管理员!"); + } + farmDocgroupManagerImpl.wipeAdminFromGroup(id, getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + FarmDocgroupUser groupUser = farmDocgroupManagerImpl.getFarmDocgroupUserEntity(id); + if (groupUser.getUserid().equals(getCurrentUser(session).getId())) { + throw new RuntimeException("不能删除自己!"); + } + farmDocgroupManagerImpl.deleteFarmDocgroupUserEntity(id, getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (1): {// 新增 + return ViewMode.getInstance().putAttr("pageset", pageset) + .returnModelAndView("parameter/pAloneApplogEntity"); + } + case (0): {// 展示 + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", farmDocgroupManagerImpl.getFarmDocgroupUserEntity(ids)) + .returnModelAndView("parameter/pAloneApplogEntity"); + } + case (2): {// 修改 + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", farmDocgroupManagerImpl.getFarmDocgroupUserEntity(ids)) + .returnModelAndView("parameter/pAloneApplogEntity"); + } + default: + break; + } + } catch (Exception e) { + return ViewMode.getInstance().setError(e + e.getMessage()) + .returnModelAndView("parameter/pAloneApplogEntity"); + } + return ViewMode.getInstance().returnModelAndView("parameter/pAloneParameterEntity"); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocmessageQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocmessageQuery.java new file mode 100644 index 0000000..f6e4a4a --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDocmessageQuery.java @@ -0,0 +1,158 @@ +package com.farm.doc.controller; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDocmessage; +import com.farm.doc.server.FarmDocmessageManagerInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; + +/** + * 留言板 + * + * @author autoCode + * + */ +@RequestMapping("/docmessage") +@Controller +public class ActionFarmDocmessageQuery extends WebUtils { + private static final Logger log = Logger.getLogger(ActionFarmDocmessageQuery.class); + @Resource + private FarmDocmessageManagerInter farmDocmessageManagerImpl; + + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, + HttpServletRequest request, String ids) { + query = EasyUiUtils.formatGridQuery(request, query); + try { + query = EasyUiUtils.formatGridQuery(request, query); + query.addRule(new DBRule("APPID", ids, "=")); + DataResult result = farmDocmessageManagerImpl.createMessageQuery(query) + .search(); + result.runformatTime("CTIME", "yyyy-MM-dd HH:mm:ss"); + result.runDictionary("1:已读,0:未读", "READSTATE"); + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(result)) + .returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance() + .returnModelAndView("doc/docmessageResult"); + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(FarmDocmessage entity, HttpSession session) { + try { + return ViewMode.getInstance().setOperate(OperateType.ADD) + .putAttr("entity", entity).returnObjMode(); + + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(FarmDocmessage entity, HttpSession session) { + try { + farmDocmessageManagerImpl.sendMessage(entity.getReaduserid(), entity.getContent(), entity.getTitle(), "私人消息", getCurrentUser(session)); + return ViewMode.getInstance().putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + farmDocmessageManagerImpl.deleteMessage(id, getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (1): {// 新增 + return ViewMode.getInstance().putAttr("pageset", pageset) + .returnModelAndView("parameter/pAloneApplogEntity"); + } + case (0): {// 展示 + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", farmDocmessageManagerImpl.getMessage(ids)) + .returnModelAndView("parameter/pAloneApplogEntity"); + } + case (2): {// 修改 + return ViewMode.getInstance().putAttr("pageset", pageset) + .putAttr("entity", farmDocmessageManagerImpl.getMessage(ids)) + .returnModelAndView("parameter/pAloneApplogEntity"); + } + default: + break; + } + } catch (Exception e) { + return ViewMode.getInstance().setError(e + e.getMessage()) + .returnModelAndView("parameter/pAloneApplogEntity"); + } + return ViewMode.getInstance().returnModelAndView( + "parameter/pAloneParameterEntity"); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDoctypeQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDoctypeQuery.java new file mode 100644 index 0000000..a2a328c --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmDoctypeQuery.java @@ -0,0 +1,200 @@ +package com.farm.doc.controller; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.OperateType; +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.server.FarmDocManagerInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.parameter.FarmParameterService; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiTreeNode; +import com.farm.web.easyui.EasyUiUtils; + +/** + * 文档分类 + * + * @author autoCode + * + */ +@RequestMapping("/doctype") +@Controller +public class ActionFarmDoctypeQuery extends WebUtils { + private static final Logger log = Logger.getLogger(ActionFarmDoctypeQuery.class); + @Resource + private FarmDocManagerInter farmDocManagerImpl; + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, HttpServletRequest request) { + try { + query = EasyUiUtils.formatGridQuery(request, query); + if (query.getQueryRule().size() <= 0) { + query.addRule(new DBRule("A.PARENTID", "NONE", "=")); + } + query.addDefaultSort(new DBSort("SORT", "asc")); + DataResult result = farmDocManagerImpl.createSimpleTypeQuery(query).search() + .runDictionary(FarmParameterService.getInstance().getDictionary("FARM_DOCTYE_TYPEMOD"), "TYPEMOD") + .runDictionary(FarmParameterService.getInstance().getDictionary("FARM_DOCTYE_DOCMOD"), "CONTENTMOD") + .runDictionary("1:结构,2:建设,3:知识,4:链接,5:单页", "TYPE").runDictionary("1:可用,0:禁用", "PSTATE") + .runDictionary("1:限制,0:所有人,2:继承", "READPOP").runDictionary("1:限制,0:所有人,2:继承", "WRITEPOP") + .runDictionary("1:需要审核,0:不审核,2:继承", "AUDITPOP"); + return ViewMode.getInstance().putAttrs(EasyUiUtils.formatGridData(result)).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + String isOpen = FarmParameterService.getInstance().getParameter("config.sys.opensource"); + if (isOpen.equals("true")) { + return ViewMode.getInstance().returnModelAndView("doc/DoctypeResultopen"); + } else { + return ViewMode.getInstance().returnModelAndView("doc/DoctypeResult"); + } + } + + @RequestMapping("/FarmDoctypeLoadTreeNode") + @ResponseBody + public Map loadTreeNode(DataQuery query, HttpServletRequest request, String id) { + query = EasyUiUtils.formatGridQuery(request, query); + try { + List treeNodes = EasyUiTreeNode.formatAsyncAjaxTree( + EasyUiTreeNode.queryTreeNodeOne(id, "SORT", "FARM_DOCTYPE", "ID", "PARENTID", "NAME", "CTIME") + .getResultList(), + EasyUiTreeNode.queryTreeNodeTow(id, "SORT", "FARM_DOCTYPE", "ID", "PARENTID", "NAME", "CTIME") + .getResultList(), + "PARENTID", "ID", "NAME", "CTIME"); + return ViewMode.getInstance().putAttr("treeNodes", treeNodes).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(FarmDoctype entity, HttpSession session) { + try { + entity = farmDocTypeManagerImpl.editType(entity, getCurrentUser(session)); + + return ViewMode.getInstance().setOperate(OperateType.ADD).putAttr("entity", entity).returnObjMode(); + + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD).setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(FarmDoctype entity, HttpSession session) { + try { + entity = farmDocTypeManagerImpl.insertType(entity, getCurrentUser(session)); + return ViewMode.getInstance().putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + farmDocTypeManagerImpl.deleteType(id, getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (1): {// 新增 + FarmDoctype parent = farmDocTypeManagerImpl.getType(ids); + + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("parent", parent) + .returnModelAndView("doc/DoctypeForm"); + } + case (0): {// 展示 + FarmDoctype entity = farmDocTypeManagerImpl.getType(ids); + FarmDoctype parent = null; + if (entity.getParentid() != null && !entity.getParentid().isEmpty()) { + parent = farmDocTypeManagerImpl.getType(entity.getParentid()); + } + + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("entity", entity) + .putAttr("parent", parent).returnModelAndView("doc/DoctypeForm"); + } + case (2): {// 修改 + FarmDoctype entity = farmDocTypeManagerImpl.getType(ids); + + FarmDoctype parent = null; + if (entity.getParentid() != null && !entity.getParentid().isEmpty()) { + parent = farmDocTypeManagerImpl.getType(entity.getParentid()); + } + + return ViewMode.getInstance().putAttr("pageset", pageset).putAttr("entity", entity) + .putAttr("parent", parent).returnModelAndView("doc/DoctypeForm"); + } + case (3): {// 到达选择分类页面 + return ViewMode.getInstance().returnModelAndView("doc/DoctypeChooseTreeWin"); + } + default: + break; + } + } catch (Exception e) { + return ViewMode.getInstance().setError(e + e.getMessage()).returnModelAndView("doc/DoctypeForm"); + } + return ViewMode.getInstance().returnModelAndView("doc/DoctypeForm"); + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmLuceneQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmLuceneQuery.java new file mode 100644 index 0000000..86b4a1b --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionFarmLuceneQuery.java @@ -0,0 +1,136 @@ +package com.farm.doc.controller; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.RequestMode; +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDocgroup; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.doc.domain.ex.TypeBrief; +import com.farm.doc.server.FarmDocIndexInter; +import com.farm.doc.server.FarmDocManagerInter; +import com.farm.doc.server.FarmDocOperateRightInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.web.WebUtils; + +/** + * 文档管理 + * + * @author autoCode + * + */ +@RequestMapping("/lucene") +@Controller +public class ActionFarmLuceneQuery extends WebUtils { + @Resource + private FarmDocManagerInter farmDocManagerImpl; + @Resource + private FarmDocOperateRightInter farmDocOperateRightImpl; + @Resource + private FarmDocgroupManagerInter farmDocgroupManagerImpl; + @Resource + private FarmDocIndexInter farmDocIndexManagerImpl; + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + private int doNum; + + /** + * 重做索引 + * + * @return + */ + @SuppressWarnings("deprecation") + @RequestMapping("/reIndex") + @ResponseBody + public Map reIndex(DataQuery query, HttpServletRequest request) { + DataResult result; + query = farmDocManagerImpl.createSimpleDocQuery(query); + query.setCurrentPage(1); + int i = 1; + doNum = 0; + while (true) { + try { + query.setPagesize(100); + query.setCurrentPage(i++); + result = query.search(); + if (result.getResultList().size() <= 0) { + break; + } + for (Map node : result.getResultList()) { + doNum++; + DocEntire doc = farmDocManagerImpl.getDoc(node.get("ID").toString()); + farmDocIndexManagerImpl.reLuceneIndex(doc, doc); + } + } catch (SQLException e1) { + e1.printStackTrace(); + break; + } + } + return ViewMode.getInstance().putAttr("num", 0).returnObjMode(); + } + + /** + * 删除索引表单 + * + * @return + */ + @RequestMapping("/delForm") + public ModelAndView delForm(RequestMode pageset, String ids) { + return ViewMode.getInstance().putAttr("pageset", pageset).returnModelAndView("doc/DocIndexForm"); + } + + /** + * 提交删除索引 + * + * @return + */ + @RequestMapping("/delCommit") + @ResponseBody + public Map delCommit(HttpSession session, String indexid) { + try { + // 在所有分类和小组中删除该知识 + List types = farmDocTypeManagerImpl.getPubTypes(); + List types_str = new ArrayList<>(); + for (TypeBrief type : types) { + types_str.add(type.getId()); + } + List groups = farmDocgroupManagerImpl.getAllGroup(); + List groups_str = new ArrayList<>(); + for (FarmDocgroup group : groups) { + groups_str.add(group.getId()); + } + farmDocIndexManagerImpl.delLuceneIndex(indexid, types_str, groups_str); + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + e.printStackTrace(); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 获取当前索引状态 + * + * @return + */ + @RequestMapping("/indexPersont") + @ResponseBody + public Map loadIndexStatr() { + return ViewMode.getInstance().putAttr("cdocs", doNum).returnObjMode(); + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionImgQuery.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionImgQuery.java new file mode 100644 index 0000000..1c96967 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/ActionImgQuery.java @@ -0,0 +1,235 @@ +package com.farm.doc.controller; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.fileupload.disk.DiskFileItem; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; + +import com.farm.core.page.ViewMode; +import com.farm.doc.domain.FarmDocfile; +import com.farm.doc.server.FarmFileManagerInter; +import com.farm.doc.server.FarmFileManagerInter.FILE_TYPE; +import com.farm.parameter.FarmParameterService; +import com.farm.web.WebUtils; + +/** + * 文档管理 + * + * @author autoCode + * + */ +@RequestMapping("/actionImg") +@Controller +public class ActionImgQuery extends WebUtils { + private static final Logger log = Logger.getLogger(ActionImgQuery.class); + + @Resource + private FarmFileManagerInter farmFileManagerImpl; + + /** + * 上传附件文件 + * + * @return + */ + @RequestMapping(value = "/PubFPupload.do") + @ResponseBody + public Map upload(@RequestParam(value = "imgFile", required = false) MultipartFile file, + HttpServletRequest request, ModelMap model, HttpSession session) { + int error; + String message; + String url = null; + String id = null; + String fileName = ""; + try { + String fileid = null; + // 验证大小 + String maxLength = FarmParameterService.getInstance().getParameter("config.doc.upload.length.max"); + if (file.getSize() > Integer.valueOf(maxLength)) { + throw new Exception("文件不能超过" + Integer.valueOf(maxLength) / 1024 + "kb"); + } + CommonsMultipartFile cmFile = (CommonsMultipartFile) file; + DiskFileItem item = (DiskFileItem) cmFile.getFileItem(); + {// 小于8k不生成到临时文件,临时解决办法。zhanghc20150919 + if (!item.getStoreLocation().exists()) { + item.write(item.getStoreLocation()); + } + } + + fileName = URLEncoder.encode(item.getName(), "utf-8"); + // 验证类型 + List types = parseIds(FarmParameterService.getInstance().getParameter("config.doc.upload.types") + .toUpperCase().replaceAll(",", ",")); + if (!types.contains(file.getOriginalFilename() + .substring(file.getOriginalFilename().lastIndexOf(".") + 1, file.getOriginalFilename().length()) + .toUpperCase())) { + throw new Exception("文件类型错误,允许的类型为:" + FarmParameterService.getInstance() + .getParameter("config.doc.upload.types").toUpperCase().replaceAll(",", ",")); + } + fileid = farmFileManagerImpl.saveFile(item.getStoreLocation(), FILE_TYPE.HTML_INNER_IMG, + file.getOriginalFilename(), getCurrentUser(session)); + error = 0; + url = farmFileManagerImpl.getFileURL(fileid); + message = ""; + id = fileid; + } catch (Exception e) { + e.printStackTrace(); + error = 1; + message = e.getMessage(); + } + return ViewMode.getInstance().putAttr("error", error).putAttr("url", url).putAttr("message", message) + .putAttr("id", id).putAttr("fileName", fileName).returnObjMode(); + } + + /** + * 上传图片文件 + * + * @return + */ + @RequestMapping(value = "/PubFPuploadImg.do") + @ResponseBody + public Map PubFPuploadImg(@RequestParam(value = "imgFile", required = false) MultipartFile file, + HttpServletRequest request, ModelMap model, HttpSession session) { + int error; + String message; + String url = null; + String id = null; + String fileName = ""; + try { + String fileid = null; + // 验证大小 + String maxLength = FarmParameterService.getInstance().getParameter("config.doc.upload.length.max"); + if (file.getSize() > Integer.valueOf(maxLength)) { + throw new Exception("文件不能超过" + Integer.valueOf(maxLength) / 1024 + "kb"); + } + CommonsMultipartFile cmFile = (CommonsMultipartFile) file; + DiskFileItem item = (DiskFileItem) cmFile.getFileItem(); + {// 小于8k不生成到临时文件,临时解决办法。zhanghc20150919 + if (!item.getStoreLocation().exists()) { + item.write(item.getStoreLocation()); + } + } + + fileName = URLEncoder.encode(item.getName(), "utf-8"); + // 验证类型 + List types = parseIds(FarmParameterService.getInstance().getParameter("config.doc.img.upload.types") + .toUpperCase().replaceAll(",", ",")); + if (!types.contains(file.getOriginalFilename() + .substring(file.getOriginalFilename().lastIndexOf(".") + 1, file.getOriginalFilename().length()) + .toUpperCase())) { + throw new Exception("文件类型错误,允许的类型为:" + FarmParameterService.getInstance() + .getParameter("config.doc.img.upload.types").toUpperCase().replaceAll(",", ",")); + } + fileid = farmFileManagerImpl.saveFile(item.getStoreLocation(), FILE_TYPE.HTML_INNER_IMG, + file.getOriginalFilename(), getCurrentUser(session)); + error = 0; + url = farmFileManagerImpl.getFileURL(fileid); + message = ""; + id = fileid; + } catch (Exception e) { + //e.printStackTrace(); + error = 1; + message = e.getMessage(); + } + return ViewMode.getInstance().putAttr("error", error).putAttr("url", url).putAttr("message", message) + .putAttr("id", id).putAttr("fileName", fileName).returnObjMode(); + } + + /** + * 下载文件 + * + * @return + */ + @RequestMapping("/Publoadfile") + public void download(String id, HttpServletRequest request, HttpServletResponse response) { + FarmDocfile file = null; + try { + file = farmFileManagerImpl.getFile(id); + } catch (Exception e) { + file = null; + } + if (file == null || file.getFile() == null || !file.getFile().exists()) { + file = new FarmDocfile(); + file.setFile(farmFileManagerImpl.getNoneImg()); + file.setName("none"); + } + response.setCharacterEncoding("utf-8"); + response.setContentType("multipart/form-data"); + try { + response.setHeader("Content-Disposition", + "attachment;fileName=" + new String(file.getName().getBytes("gbk"), "iso-8859-1")); + } catch (UnsupportedEncodingException e2) { + e2.printStackTrace(); + } + + InputStream is = null; + OutputStream os = null; + try { + is = new FileInputStream(file.getFile()); + os = response.getOutputStream(); + byte[] b = new byte[2048]; + int length; + while ((length = is.read(b)) > 0) { + os.write(b, 0, length); + } + } catch (FileNotFoundException e) { + InputStream is1 = null; + OutputStream os1 = null; + try { + String webPath = FarmParameterService.getInstance().getParameter("farm.constant.webroot.path"); + String filePath = "/WEB-FACE/img/style/nullImg.png".replaceAll("/", + File.separator.equals("/") ? "/" : "\\\\"); + File nullFile = new File(webPath + filePath); + is1 = new FileInputStream(nullFile); + os1 = response.getOutputStream(); + byte[] b = new byte[2048]; + int length; + while ((length = is1.read(b)) > 0) { + os1.write(b, 0, length); + } + + } catch (Exception e1) { + log.error(e.getMessage()); + } finally { + try { + is1.close(); + os1.close(); + } catch (IOException e1) { + log.error(e.getMessage()); + } + } + log.error(e.getMessage()); + } catch (IOException e) { + log.error(e.getMessage()); + } finally { + // 这里主要关闭。 + try { + is.close(); + os.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + log.error(e.getMessage()); + } + } + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/FarmReleaseRankingController.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/FarmReleaseRankingController.java new file mode 100644 index 0000000..533f335 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/FarmReleaseRankingController.java @@ -0,0 +1,68 @@ +package com.farm.doc.controller; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.farm.core.page.ViewMode; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.server.FarmDocManagerInter; +import com.farm.doc.server.FarmDocRunInfoInter; +import com.farm.web.WebUtils; +import com.farm.web.easyui.EasyUiUtils; + +/* * + *功能:文档发布排名控制层 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@RequestMapping("/farmReleaseRanking") +@Controller +public class FarmReleaseRankingController extends WebUtils { + private final static Logger log = Logger.getLogger(FarmReleaseRankingController.class); + + @Resource + private FarmDocManagerInter farmDocManagerImpl; + @Resource + private FarmDocRunInfoInter farmDocRunInfoImpl; + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, HttpServletRequest request) { + try { + query = EasyUiUtils.formatGridQuery(request, query); + query.addSort(new DBSort("B.GOODRATE", "DESC")); + DataResult result = farmDocRunInfoImpl.createReleaseRankingSimpleQuery(query).search(); + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(result)) + .returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance().returnModelAndView("doc/FarmReleaseRankingResult"); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/FarmtopController.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/FarmtopController.java new file mode 100644 index 0000000..1cedd5e --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/FarmtopController.java @@ -0,0 +1,242 @@ +package com.farm.doc.controller; + +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.Farmtop; +import com.farm.doc.server.FarmDocManagerInter; +import com.farm.doc.server.FarmtopServiceInter; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.annotation.Resource; + +import com.farm.web.easyui.EasyUiUtils; + +import java.util.Map; + +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpSession; + +import com.farm.core.page.RequestMode; +import com.farm.core.page.OperateType; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.page.ViewMode; +import com.farm.web.WebUtils; + +/* * + *功能:置顶文档控制层 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@RequestMapping("/farmtop") +@Controller +public class FarmtopController extends WebUtils { + private final static Logger log = Logger.getLogger(FarmtopController.class); + @Resource + FarmtopServiceInter farmTopServiceImpl; + @Resource + private FarmDocManagerInter farmDocManagerImpl; + + public FarmtopServiceInter getFarmtopServiceImpl() { + return farmTopServiceImpl; + } + + public void setFarmtopServiceImpl(FarmtopServiceInter farmTopServiceImpl) { + this.farmTopServiceImpl = farmTopServiceImpl; + } + + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, + HttpServletRequest request) { + // TODO 自动生成代码,修改后请去除本注释 + try { + query = EasyUiUtils.formatGridQuery(request, query); + query.addSort(new DBSort("TOP.SORT", "DESC")); + DataResult result = farmTopServiceImpl.createFarmtopSimpleQuery(query).search(); + result.runDictionary("1:开放,0:禁用,2:待审核", "STATE"); + result.runDictionary("1:HTML,2:TXT", "DOMTYPE"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "WRITEPOP"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "READPOP"); + result.runformatTime("PUBTIME", "yyyy-MM-dd HH:mm:ss"); + + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(result)) + .returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(Farmtop entity, HttpSession session) { + // TODO 自动生成代码,修改后请去除本注释 + try { + entity = farmTopServiceImpl.editFarmtopEntity(entity, + getCurrentUser(session)); + return ViewMode.getInstance().setOperate(OperateType.UPDATE) + .putAttr("entity", entity).returnObjMode(); + + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.UPDATE) + .setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(Farmtop entity, HttpSession session) { + // TODO 自动生成代码,修改后请去除本注释 + try { + entity = farmTopServiceImpl.insertFarmtopEntity(entity, + getCurrentUser(session)); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + farmTopServiceImpl.deleteFarmtopEntity(id, + getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance().returnModelAndView("doc/FarmtopResult"); + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (0): {// 查看 + Farmtop entity = farmTopServiceImpl.getFarmtopEntity(ids); + Doc doc = farmDocManagerImpl.getDocOnlyBean(entity.getDocid()); + + return ViewMode + .getInstance() + .putAttr("pageset", pageset) + .putAttr("entity", farmTopServiceImpl.getFarmtopEntity(ids)) + .putAttr("doctitle", doc.getTitle()) + .returnModelAndView("doc/FarmtopForm"); + } + case (1): {// 新增 + return ViewMode.getInstance().putAttr("pageset", pageset) + .returnModelAndView("doc/FarmtopForm"); + } + case (2): {// 修改 + Farmtop entity = farmTopServiceImpl.getFarmtopEntity(ids); + Doc doc = farmDocManagerImpl.getDocOnlyBean(entity.getDocid()); + + return ViewMode + .getInstance() + .putAttr("pageset", pageset) + .putAttr("entity", entity) + .putAttr("doctitle", doc.getTitle()) + .returnModelAndView("doc/FarmtopForm"); + } + case (3): {//达到选择文档页面 + return ViewMode .getInstance().returnModelAndView("doc/DocCommonSelectPageForDoc"); + } + default: + break; + } + return ViewMode.getInstance().returnModelAndView("doc/FarmtopForm"); + } catch (Exception e) { + return ViewMode.getInstance().setError(e + e.getMessage()) + .returnModelAndView("doc/FarmtopForm"); + } + } + + /** + * 达到文档置顶选择文档页面 + * v1.0 zhanghc 2015年9月5日下午12:59:45 + * @return ModelAndView + */ + @RequestMapping("/toDocTopChooseDoc") + public ModelAndView toDocTopChooseDoc() { + return ViewMode.getInstance().returnModelAndView("doc/DocTopChooseDoc"); + } + + /** + * 文档置顶选择文档列表数据,只要读权限是公开的数据 + * v1.0 zhanghc 2015年9月5日下午1:03:03 + * @param query + * @param request + * @return Map + */ + @RequestMapping("/docTopChooseDocList") + @ResponseBody + public Map docTopChooseDocList(DataQuery query, HttpServletRequest request) { + try { + query = EasyUiUtils.formatGridQuery(request, query); + query.getAndRemoveRule("READPOP"); + query.addRule(new DBRule("a.READPOP", "1", "=")); + DataResult result = farmTopServiceImpl.docTopChooseDocList(query).search(); + result.runDictionary("1:开放,0:禁用,2:待审核", "STATE"); + result.runDictionary("1:HTML,2:TXT", "DOMTYPE"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "WRITEPOP"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "READPOP"); + result.runformatTime("PUBTIME", "yyyy-MM-dd HH:mm:ss"); + return ViewMode.getInstance().putAttrs(EasyUiUtils.formatGridData(result)).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/UsermessageController.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/UsermessageController.java new file mode 100644 index 0000000..854ea67 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/UsermessageController.java @@ -0,0 +1,195 @@ +package com.farm.doc.controller; + +import com.farm.doc.domain.Usermessage; +import com.farm.doc.server.UsermessageServiceInter; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.annotation.Resource; + +import com.farm.web.easyui.EasyUiUtils; + +import java.util.Map; + +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpSession; + +import com.farm.authority.service.UserServiceInter; +import com.farm.core.page.RequestMode; +import com.farm.core.page.OperateType; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.page.ViewMode; +import com.farm.web.WebUtils; + +/* * + *功能:用户消息控制层 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@RequestMapping("/usermessage") +@Controller +public class UsermessageController extends WebUtils { + private final static Logger log = Logger + .getLogger(UsermessageController.class); + @Resource + private UsermessageServiceInter usermessageServiceImpl; + @Resource + private UserServiceInter userServiceImpl; + + public UsermessageServiceInter getUsermessageServiceImpl() { + return usermessageServiceImpl; + } + + public void setUsermessageServiceImpl( + UsermessageServiceInter usermessageServiceImpl) { + this.usermessageServiceImpl = usermessageServiceImpl; + } + + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, + HttpServletRequest request) { + + try { + query = EasyUiUtils.formatGridQuery(request, query); + DataResult result = usermessageServiceImpl + .createUsermessageSimpleQuery(query).search(); + result.runDictionary("0:未读,1:已读", "READSTATE"); + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(result)) + .returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(Usermessage entity, + HttpSession session) { + + try { + entity = usermessageServiceImpl.editUsermessageEntity(entity, + getCurrentUser(session)); + return ViewMode.getInstance().setOperate(OperateType.UPDATE) + .putAttr("entity", entity).returnObjMode(); + + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.UPDATE) + .setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(Usermessage entity, HttpSession session) { + try { + entity = usermessageServiceImpl.insertUsermessageEntity(entity, + getCurrentUser(session)); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + usermessageServiceImpl.deleteUsermessageEntity(id, + getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance().returnModelAndView( + "doc/UsermessageResult"); + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (0): {// 查看 + Usermessage entity = usermessageServiceImpl.getUsermessageEntity(ids); + + return ViewMode + .getInstance() + .putAttr("pageset", pageset) + .putAttr("entity", entity) + .putAttr("readusername", userServiceImpl.getUserEntity(entity.getReaduserid()).getName()) + .returnModelAndView("doc/UsermessageForm"); + } + case (1): {// 新增 + return ViewMode.getInstance().putAttr("pageset", pageset) + .returnModelAndView("doc/UsermessageForm"); + } + case (2): {// 修改 + Usermessage entity = usermessageServiceImpl.getUsermessageEntity(ids); + return ViewMode + .getInstance() + .putAttr("pageset", pageset) + .putAttr("entity", entity) + .putAttr("readusername", userServiceImpl.getUserEntity(entity.getReaduserid()).getName()) + .returnModelAndView("doc/UsermessageForm"); + } + default: + break; + } + return ViewMode.getInstance().returnModelAndView( + "doc/UsermessageForm"); + } catch (Exception e) { + return ViewMode.getInstance().setError(e + e.getMessage()) + .returnModelAndView("doc/UsermessageForm"); + } + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/controller/WeburlController.java b/src/wcp-doc/src/main/java/com/farm/doc/controller/WeburlController.java new file mode 100644 index 0000000..95aa582 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/controller/WeburlController.java @@ -0,0 +1,207 @@ +package com.farm.doc.controller; + +import com.farm.doc.domain.Weburl; +import com.farm.doc.server.WeburlServiceInter; +import com.farm.doc.server.commons.DocumentConfig; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.annotation.Resource; + +import com.farm.web.easyui.EasyUiUtils; + +import java.util.Map; + +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpSession; + +import com.farm.core.page.RequestMode; +import com.farm.core.page.OperateType; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.page.ViewMode; +import com.farm.web.WebUtils; + +/* * + *功能:推荐服务控制层 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@RequestMapping("/weburl") +@Controller +public class WeburlController extends WebUtils { + private final static Logger log = Logger.getLogger(WeburlController.class); + @Resource + WeburlServiceInter weburlServiceImpl; + + public WeburlServiceInter getWeburlServiceImpl() { + return weburlServiceImpl; + } + + public void setWeburlServiceImpl(WeburlServiceInter weburlServiceImpl) { + this.weburlServiceImpl = weburlServiceImpl; + } + + /** + * 查询结果集合 + * + * @return + */ + @RequestMapping("/query") + @ResponseBody + public Map queryall(DataQuery query, + HttpServletRequest request) { + + try { + query = EasyUiUtils.formatGridQuery(request, query); + DataResult result = weburlServiceImpl + .createWeburlSimpleQuery(query).search(); + return ViewMode.getInstance() + .putAttrs(EasyUiUtils.formatGridData(result)) + .returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + /** + * 提交修改数据 + * + * @return + */ + @RequestMapping("/edit") + @ResponseBody + public Map editSubmit(Weburl entity, HttpSession session) { + + try { + entity = weburlServiceImpl.editWeburlEntity(entity, + getCurrentUser(session)); + return ViewMode.getInstance().setOperate(OperateType.UPDATE) + .putAttr("entity", entity).returnObjMode(); + + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.UPDATE) + .setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 提交新增数据 + * + * @return + */ + @RequestMapping("/add") + @ResponseBody + public Map addSubmit(Weburl entity, HttpSession session) { + + try { + entity = weburlServiceImpl.insertWeburlEntity(entity, + getCurrentUser(session)); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .putAttr("entity", entity).returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setOperate(OperateType.ADD) + .setError(e.getMessage()).returnObjMode(); + } + } + + /** + * 删除数据 + * + * @return + */ + @RequestMapping("/del") + @ResponseBody + public Map delSubmit(String ids, HttpSession session) { + try { + for (String id : parseIds(ids)) { + weburlServiceImpl.deleteWeburlEntity(id, + getCurrentUser(session)); + } + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.getMessage()); + return ViewMode.getInstance().setError(e.getMessage()) + .returnObjMode(); + } + } + + @RequestMapping("/list") + public ModelAndView index(HttpSession session) { + return ViewMode.getInstance().returnModelAndView("doc/WeburlResult"); + } + + /** + * 显示详细信息(修改或浏览时) + * + * @return + */ + @RequestMapping("/form") + public ModelAndView view(RequestMode pageset, String ids) { + try { + switch (pageset.getOperateType()) { + case (0): {// 查看 + Weburl entity = weburlServiceImpl.getWeburlEntity(ids); + String imgUrl = DocumentConfig.getString("config.doc.download.url") + entity.getFileid(); + return ViewMode + .getInstance() + .putAttr("pageset", pageset) + .putAttr("entity", entity) + .putAttr("imgUrl", imgUrl) + .returnModelAndView("doc/WeburlForm"); + } + case (1): {// 新增 + return ViewMode.getInstance().putAttr("pageset", pageset) + .returnModelAndView("doc/WeburlForm"); + } + case (2): {// 修改 + Weburl entity = weburlServiceImpl.getWeburlEntity(ids); + String imgUrl = null; + if(entity.getFileid() != null && !entity.getFileid().isEmpty()){ + imgUrl = DocumentConfig.getString("config.doc.download.url") + entity.getFileid(); + } + return ViewMode.getInstance() + .putAttr("pageset", pageset) + .putAttr("entity", entity) + .putAttr("imgUrl", imgUrl) + .returnModelAndView("doc/WeburlForm"); + } + default: + break; + } + return ViewMode.getInstance().returnModelAndView("doc/WeburlForm"); + } catch (Exception e) { + return ViewMode.getInstance().setError(e + e.getMessage()) + .returnModelAndView("doc/WeburlForm"); + } + } + + /** + * 删除附件 + * @return Map + */ + @RequestMapping("/delImg") + @ResponseBody + public Map delImg(String imgid) { + try { + weburlServiceImpl.delImg(imgid); + return ViewMode.getInstance().returnObjMode(); + } catch (Exception e) { + log.error(e.toString()); + return ViewMode.getInstance().setError(e.getMessage()).returnObjMode(); + } + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocDaoInter.java new file mode 100644 index 0000000..b41b9d0 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocDaoInter.java @@ -0,0 +1,69 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.Doc; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/**文档管理 + * @author MAC_wd + * + */ +public interface FarmDocDaoInter { + /** 删除一个实体 + * @param entity 实体 + */ + public void deleteEntity(Doc entity) ; + /** 由id获得一个实体 + * @param id + * @return + */ + public Doc getEntity(String id) ; + /** 插入一条数据 + * @param entity + */ + public Doc insertEntity(Doc entity); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个记录 + * @param entity + */ + public void editEntity(Doc entity); + /**获得一个session + */ + public Session getSession(); + /**执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocenjoyDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocenjoyDaoInter.java new file mode 100644 index 0000000..a781c19 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocenjoyDaoInter.java @@ -0,0 +1,69 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDocenjoy; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/**关注 + * @author MAC_wd + * + */ +public interface FarmDocenjoyDaoInter { + /** 删除一个实体 + * @param entity 实体 + */ + public void deleteEntity(FarmDocenjoy entity) ; + /** 由id获得一个实体 + * @param id + * @return + */ + public FarmDocenjoy getEntity(String id) ; + /** 插入一条数据 + * @param entity + */ + public FarmDocenjoy insertEntity(FarmDocenjoy entity); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个记录 + * @param entity + */ + public void editEntity(FarmDocenjoy entity); + /**获得一个session + */ + public Session getSession(); + /**执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocfileDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocfileDaoInter.java new file mode 100644 index 0000000..b3099dd --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocfileDaoInter.java @@ -0,0 +1,111 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDocfile; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/** + * 文档附件 + * + * @author MAC_wd + * + */ +public interface FarmDocfileDaoInter { + /** + * 删除一个实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(FarmDocfile entity); + + /** + * 由id获得一个实体 + * + * @param id + * @return + */ + public FarmDocfile getEntity(String id); + + /** + * 插入一条数据 + * + * @param entity + */ + public FarmDocfile insertEntity(FarmDocfile entity); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个记录 + * + * @param entity + */ + public void editEntity(FarmDocfile entity); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 获得文档的附件 + * + * @param id + * 文档id + * @return + */ + public List getEntityByDocId(String id); + + /** + * 获得文档的附件依据扩展名 + * + * @param docid + * @param exname + * 扩展名如.doc + * @return + */ + public List getEntityByDocIdAndExName(String docid, + String exname); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocgroupDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocgroupDaoInter.java new file mode 100644 index 0000000..4b2438b --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocgroupDaoInter.java @@ -0,0 +1,77 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDocgroup; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/**工作小组 + * @author MAC_wd + * + */ +public interface FarmDocgroupDaoInter { + /** 删除一个实体 + * @param entity 实体 + */ + public void deleteEntity(FarmDocgroup entity) ; + /** 由id获得一个实体 + * @param id + * @return + */ + public FarmDocgroup getEntity(String id) ; + /** 插入一条数据 + * @param entity + */ + public FarmDocgroup insertEntity(FarmDocgroup entity); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个记录 + * @param entity + */ + public void editEntity(FarmDocgroup entity); + /**获得一个session + */ + public Session getSession(); + /**执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + /** + * 获得小组文档的数量 + * + * @param groupId + * 小组ID + * @return + */ + public int getGroupDocNum(String groupId); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocgroupUserDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocgroupUserDaoInter.java new file mode 100644 index 0000000..da016e9 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocgroupUserDaoInter.java @@ -0,0 +1,69 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDocgroupUser; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/**工作小组成员 + * @author MAC_wd + * + */ +public interface FarmDocgroupUserDaoInter { + /** 删除一个实体 + * @param entity 实体 + */ + public void deleteEntity(FarmDocgroupUser entity) ; + /** 由id获得一个实体 + * @param id + * @return + */ + public FarmDocgroupUser getEntity(String id) ; + /** 插入一条数据 + * @param entity + */ + public FarmDocgroupUser insertEntity(FarmDocgroupUser entity); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个记录 + * @param entity + */ + public void editEntity(FarmDocgroupUser entity); + /**获得一个session + */ + public Session getSession(); + /**执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocmessageDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocmessageDaoInter.java new file mode 100644 index 0000000..268646e --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocmessageDaoInter.java @@ -0,0 +1,105 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDocmessage; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/** + * 留言板 + * + * @author MAC_wd + * + */ +public interface FarmDocmessageDaoInter { + /** + * 删除一个实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(FarmDocmessage entity); + + /** + * 由id获得一个实体 + * + * @param id + * @return + */ + public FarmDocmessage getEntity(String id); + + /** + * 插入一条数据 + * + * @param entity + */ + public FarmDocmessage insertEntity(FarmDocmessage entity); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个记录 + * + * @param entity + */ + public void editEntity(FarmDocmessage entity); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 获得用户没有读的消息数量 + * + * @param userId 用户id + * @return + */ + public int getNoReadMessageNum(String userId); + + /**获得对应到某业务id的留言数 + * @param appid + * @return + */ + public int getAppMessageNum(String appid); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocruninfoDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocruninfoDaoInter.java new file mode 100644 index 0000000..05f592e --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocruninfoDaoInter.java @@ -0,0 +1,112 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDocruninfo; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/** + * 实体管理 + * + * @author MAC_wd + * + */ +public interface FarmDocruninfoDaoInter { + /** + * 删除一个实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(FarmDocruninfo entity); + + /** + * 由id获得一个实体 + * + * @param id + * @return + */ + public FarmDocruninfo getEntity(String id); + + /** + * 插入一条数据 + * + * @param entity + */ + public FarmDocruninfo insertEntity(FarmDocruninfo entity); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个记录 + * + * @param entity + */ + public void editEntity(FarmDocruninfo entity); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 系统知识总数 + * + * @return + */ + public Integer getKnowsNum(); + + /** + * 系统好评知识总数 + * + * @return + */ + public Integer getGoodKnowsNum(); + + /** + * 系统差评知识总数 + * + * @return + */ + public Integer getBadKnowsNum(); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocruninfoDetailDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocruninfoDetailDaoInter.java new file mode 100644 index 0000000..2437417 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDocruninfoDetailDaoInter.java @@ -0,0 +1,77 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDocruninfoDetail; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/**用户用量明细 + * @author MAC_wd + * + */ +public interface FarmDocruninfoDetailDaoInter { + /** 删除一个实体 + * @param entity 实体 + */ + public void deleteEntity(FarmDocruninfoDetail entity) ; + /** 由id获得一个实体 + * @param id + * @return + */ + public FarmDocruninfoDetail getEntity(String id) ; + /** 插入一条数据 + * @param entity + */ + public FarmDocruninfoDetail insertEntity(FarmDocruninfoDetail entity); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个记录 + * @param entity + */ + public void editEntity(FarmDocruninfoDetail entity); + /**获得一个session + */ + public Session getSession(); + /**执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件统计,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public int countEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDoctextDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDoctextDaoInter.java new file mode 100644 index 0000000..e2e607c --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDoctextDaoInter.java @@ -0,0 +1,69 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDoctext; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/**文档内容 + * @author MAC_wd + * + */ +public interface FarmDoctextDaoInter { + /** 删除一个实体 + * @param entity 实体 + */ + public void deleteEntity(FarmDoctext entity) ; + /** 由id获得一个实体 + * @param id + * @return + */ + public FarmDoctext getEntity(String id) ; + /** 插入一条数据 + * @param entity + */ + public FarmDoctext insertEntity(FarmDoctext entity); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个记录 + * @param entity + */ + public void editEntity(FarmDoctext entity); + /**获得一个session + */ + public Session getSession(); + /**执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDoctypeDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDoctypeDaoInter.java new file mode 100644 index 0000000..f618f4c --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmDoctypeDaoInter.java @@ -0,0 +1,98 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDoctype; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/** + * 文档分类 + * + * @author MAC_wd + * + */ +public interface FarmDoctypeDaoInter { + /** + * 删除一个实体 + * + * @param entity + * 实体 + */ + public void deleteEntity(FarmDoctype entity); + + /** + * 由id获得一个实体 + * + * @param id + * @return + */ + public FarmDoctype getEntity(String id); + + /** + * 插入一条数据 + * + * @param entity + */ + public FarmDoctype insertEntity(FarmDoctype entity); + + /** + * 获得记录数量 + * + * @return + */ + public int getAllListNum(); + + /** + * 修改一个记录 + * + * @param entity + */ + public void editEntity(FarmDoctype entity); + + /** + * 获得一个session + */ + public Session getSession(); + + /** + * 执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /** + * 系统分类数 + * + * @return + */ + public Integer getTypesNum(); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmRfDoctextfileDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmRfDoctextfileDaoInter.java new file mode 100644 index 0000000..faa6ca3 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmRfDoctextfileDaoInter.java @@ -0,0 +1,69 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmRfDoctextfile; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/**中间表-内容-附件 + * @author MAC_wd + * + */ +public interface FarmRfDoctextfileDaoInter { + /** 删除一个实体 + * @param entity 实体 + */ + public void deleteEntity(FarmRfDoctextfile entity) ; + /** 由id获得一个实体 + * @param id + * @return + */ + public FarmRfDoctextfile getEntity(String id) ; + /** 插入一条数据 + * @param entity + */ + public FarmRfDoctextfile insertEntity(FarmRfDoctextfile entity); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个记录 + * @param entity + */ + public void editEntity(FarmRfDoctextfile entity); + /**获得一个session + */ + public Session getSession(); + /**执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmRfDoctypeDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmRfDoctypeDaoInter.java new file mode 100644 index 0000000..cf02ee0 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmRfDoctypeDaoInter.java @@ -0,0 +1,81 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.domain.FarmRfDoctype; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + +/**中间表-分类文档 + * @author MAC_wd + * + */ +public interface FarmRfDoctypeDaoInter { + /** 删除一个实体 + * @param entity 实体 + */ + public void deleteEntity(FarmRfDoctype entity) ; + /** 由id获得一个实体 + * @param id + * @return + */ + public FarmRfDoctype getEntity(String id) ; + /** 插入一条数据 + * @param entity + */ + public FarmRfDoctype insertEntity(FarmRfDoctype entity); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个记录 + * @param entity + */ + public void editEntity(FarmRfDoctype entity); + /**获得一个session + */ + public Session getSession(); + /**执行一条查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + + /**获得文档的分类 + * @param docId 文档分类 + * @return + */ + public List getDocTypes(String docId); + /**获得文档的分类 + * @param docId 文档分类 + * @return + */ + public FarmDoctype getDocType(String docId); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmtopDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmtopDaoInter.java new file mode 100644 index 0000000..5460ab3 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/FarmtopDaoInter.java @@ -0,0 +1,82 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.Farmtop; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + + +/* * + *功能:置顶文档数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20150707114057 + *说明: + */ +public interface FarmtopDaoInter { + /** 删除一个置顶文档实体 + * @param entity 实体 + */ + public void deleteEntity(Farmtop farmtop) ; + /** 由置顶文档id获得一个置顶文档实体 + * @param id + * @return + */ + public Farmtop getEntity(String farmtopid) ; + /** 插入一条置顶文档数据 + * @param entity + */ + public Farmtop insertEntity(Farmtop farmtop); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个置顶文档记录 + * @param entity + */ + public void editEntity(Farmtop farmtop); + /**获得一个session + */ + public Session getSession(); + /**执行一条置顶文档查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除置顶文档实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询置顶文档实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改置顶文档实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + /** + * 条件合计置顶文档:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/UsermessageDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/UsermessageDaoInter.java new file mode 100644 index 0000000..04f1b84 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/UsermessageDaoInter.java @@ -0,0 +1,82 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.Usermessage; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + + +/* * + *功能:用户消息数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20150707114057 + *说明: + */ +public interface UsermessageDaoInter { + /** 删除一个用户消息实体 + * @param entity 实体 + */ + public void deleteEntity(Usermessage usermessage) ; + /** 由用户消息id获得一个用户消息实体 + * @param id + * @return + */ + public Usermessage getEntity(String usermessageid) ; + /** 插入一条用户消息数据 + * @param entity + */ + public Usermessage insertEntity(Usermessage usermessage); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个用户消息记录 + * @param entity + */ + public void editEntity(Usermessage usermessage); + /**获得一个session + */ + public Session getSession(); + /**执行一条用户消息查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除用户消息实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询用户消息实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改用户消息实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + /** + * 条件合计用户消息:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/WeburlDaoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/WeburlDaoInter.java new file mode 100644 index 0000000..b893da0 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/WeburlDaoInter.java @@ -0,0 +1,82 @@ +package com.farm.doc.dao; + +import com.farm.doc.domain.Weburl; +import org.hibernate.Session; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import java.util.List; +import java.util.Map; + + +/* * + *功能:推荐服务数据库持久层接口 + *详细: + * + *版本:v0.1 + *作者:Farm代码工程自动生成 + *日期:20150707114057 + *说明: + */ +public interface WeburlDaoInter { + /** 删除一个推荐服务实体 + * @param entity 实体 + */ + public void deleteEntity(Weburl weburl) ; + /** 由推荐服务id获得一个推荐服务实体 + * @param id + * @return + */ + public Weburl getEntity(String weburlid) ; + /** 插入一条推荐服务数据 + * @param entity + */ + public Weburl insertEntity(Weburl weburl); + /** 获得记录数量 + * @return + */ + public int getAllListNum(); + /**修改一个推荐服务记录 + * @param entity + */ + public void editEntity(Weburl weburl); + /**获得一个session + */ + public Session getSession(); + /**执行一条推荐服务查询语句 + */ + public DataResult runSqlQuery(DataQuery query); + /** + * 条件删除推荐服务实体,依据对象字段值(一般不建议使用该方法) + * + * @param rules + * 删除条件 + */ + public void deleteEntitys(List rules); + + /** + * 条件查询推荐服务实体,依据对象字段值,当rules为空时查询全部(一般不建议使用该方法) + * + * @param rules + * 查询条件 + * @return + */ + public List selectEntitys(List rules); + + /** + * 条件修改推荐服务实体,依据对象字段值(一般不建议使用该方法) + * + * @param values + * 被修改的键值对 + * @param rules + * 修改条件 + */ + public void updataEntitys(Map values, List rules); + /** + * 条件合计推荐服务:count(*) + * + * @param rules + * 统计条件 + */ + public int countEntitys(List rules); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/Article.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/Article.java new file mode 100644 index 0000000..8fc9458 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/Article.java @@ -0,0 +1,53 @@ +package com.example.fulltextsearch.model; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +//创建一个简单的实体类,用于存储和检索数据 +@Document(indexName = "articles") +public class Article { + + @Id + private String id; + + @Field(type = FieldType.Text, analyzer = "standard") + private String title; + + @Field(type = FieldType.Text, analyzer = "standard") + private String content; + + // Constructors, getters and setters + public Article() {} + + public Article(String id, String title, String content) { + this.id = id; + this.title = title; + this.content = content; + } + + // Getters and setters + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocDao.java new file mode 100644 index 0000000..293680a --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocDao.java @@ -0,0 +1,103 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.doc.dao.FarmDocDaoInter; +import com.farm.doc.domain.Doc; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.transaction.Transactional; + +/**文档管理 + * @author MAC_wd + * + */ +@Repository +public class FarmDocDao extends HibernateSQLTools implements FarmDocDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(Doc entity) { + Session session=sessionFatory.getCurrentSession(); + session.delete(entity); + } + public int getAllListNum(){ + Session session= sessionFatory.getCurrentSession(); + SQLQuery sqlquery= session.createSQLQuery("select count(*) from farm_doc"); + BigInteger num=(BigInteger)sqlquery.list().get(0); + return num.intValue() ; + } + public Doc getEntity(String id) { + Session session= sessionFatory.getCurrentSession(); + return (Doc)session.get(Doc.class, id); + } + @Transactional + public Doc insertEntity(Doc entity) { + Session session= sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + public void editEntity(Doc entity) { + Session session= sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + public DataResult runSqlQuery(DataQuery query){ + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction( + sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), + values, rules); + } + + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + @Override + protected Class getTypeClass() { + return Doc.class; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocenjoyDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocenjoyDao.java new file mode 100644 index 0000000..5c99946 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocenjoyDao.java @@ -0,0 +1,110 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.doc.dao.FarmDocenjoyDaoInter; +import com.farm.doc.domain.FarmDocenjoy; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +/** + * 关注 + * + * @author MAC_wd + * + */ +@Repository +public class FarmDocenjoyDao extends HibernateSQLTools implements + FarmDocenjoyDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDocenjoy entity) { + Session session = sessionFatory.getCurrentSession(); + session.delete(entity); + } + + public int getAllListNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_docenjoy"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + public FarmDocenjoy getEntity(String id) { + Session session = sessionFatory.getCurrentSession(); + return (FarmDocenjoy) session.get(FarmDocenjoy.class, id); + } + + public FarmDocenjoy insertEntity(FarmDocenjoy entity) { + Session session = sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + + public void editEntity(FarmDocenjoy entity) { + Session session = sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + + public DataResult runSqlQuery(DataQuery query) { + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction( + sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), + values, rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + + @Override + protected Class getTypeClass() { + return FarmDocenjoy.class; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocfileDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocfileDao.java new file mode 100644 index 0000000..10eb5e7 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocfileDao.java @@ -0,0 +1,132 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmDocfileDaoInter; +import com.farm.doc.domain.FarmDocfile; + +/** + * 文档附件 + * + * @author MAC_wd + * + */ +@Repository +public class FarmDocfileDao extends HibernateSQLTools implements FarmDocfileDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDocfile entity) { + Session session = sessionFatory.getCurrentSession(); + session.delete(entity); + } + + public int getAllListNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_docfile"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Transactional + public FarmDocfile getEntity(String id) { + Session session = sessionFatory.getCurrentSession(); + return (FarmDocfile) session.get(FarmDocfile.class, id); + } + + public FarmDocfile insertEntity(FarmDocfile entity) { + Session session = sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + + public void editEntity(FarmDocfile entity) { + Session session = sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + + public DataResult runSqlQuery(DataQuery query) { + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), + values, rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @SuppressWarnings("unchecked") + @Override + public List getEntityByDocId(String id) { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("SELECT DISTINCT b.* FROM farm_rf_doctextfile a LEFT JOIN farm_docfile b ON a.FILEID=b.ID WHERE PSTATE='1' AND a.DOCID=? order by b.etime desc"); + sqlquery.setString(0, id); + sqlquery.addEntity(FarmDocfile.class); + return sqlquery.list(); + } + + @SuppressWarnings("unchecked") + @Override + public List getEntityByDocIdAndExName(String docid, + String exname) { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("SELECT DISTINCT b.* FROM farm_rf_doctextfile a LEFT JOIN farm_docfile b ON a.FILEID=b.ID WHERE PSTATE='1' AND a.DOCID=? AND b.EXNAME=? order by b.etime desc"); + sqlquery.setString(0, docid); + sqlquery.setString(1, exname); + sqlquery.addEntity(FarmDocfile.class); + return sqlquery.list(); + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + @Override + protected Class getTypeClass() { + return FarmDocfile.class; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocgroupDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocgroupDao.java new file mode 100644 index 0000000..1c35d39 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocgroupDao.java @@ -0,0 +1,114 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmDocgroupDaoInter; +import com.farm.doc.domain.FarmDocgroup; + +/** + * 工作小组 + * + * @author MAC_wd + * + */ +@Repository +public class FarmDocgroupDao extends HibernateSQLToolsimplements FarmDocgroupDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDocgroup entity) { + Session session = sessionFatory.getCurrentSession(); + session.delete(entity); + } + + public int getAllListNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from farm_docgroup"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + public FarmDocgroup getEntity(String id) { + Session session = sessionFatory.getCurrentSession(); + return (FarmDocgroup) session.get(FarmDocgroup.class, id); + } + + public FarmDocgroup insertEntity(FarmDocgroup entity) { + Session session = sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + + public void editEntity(FarmDocgroup entity) { + Session session = sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + + public DataResult runSqlQuery(DataQuery query) { + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + public int getGroupDocNum(String groupId) { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from FARM_DOC where STATE='1' and DOCGROUPID=?"); + sqlquery.setString(0, groupId); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + + @Override + protected Class getTypeClass() { + return FarmDocgroup.class; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocgroupUserDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocgroupUserDao.java new file mode 100644 index 0000000..ec246e1 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocgroupUserDao.java @@ -0,0 +1,98 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmDocgroupUserDaoInter; +import com.farm.doc.domain.FarmDocgroupUser; + +/**工作小组成员 + * @author MAC_wd + * + */ +@Repository +public class FarmDocgroupUserDao extends HibernateSQLTools implements FarmDocgroupUserDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDocgroupUser entity) { + Session session=sessionFatory.getCurrentSession(); + session.delete(entity); + } + public int getAllListNum(){ + Session session= sessionFatory.getCurrentSession(); + SQLQuery sqlquery= session.createSQLQuery("select count(*) from farm_docgroup_user"); + BigInteger num=(BigInteger)sqlquery.list().get(0); + return num.intValue() ; + } + public FarmDocgroupUser getEntity(String id) { + Session session= sessionFatory.getCurrentSession(); + return (FarmDocgroupUser)session.get(FarmDocgroupUser.class, id); + } + public FarmDocgroupUser insertEntity(FarmDocgroupUser entity) { + Session session= sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + public void editEntity(FarmDocgroupUser entity) { + Session session= sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + public DataResult runSqlQuery(DataQuery query){ + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), + values, rules); + } + + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + @Override + protected Class getTypeClass() { + return FarmDocgroupUser.class; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocmessageDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocmessageDao.java new file mode 100644 index 0000000..d005b55 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocmessageDao.java @@ -0,0 +1,127 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmDocmessageDaoInter; +import com.farm.doc.domain.FarmDocmessage; + +/** + * 留言板 + * + * @author MAC_wd + * + */ +@Repository +public class FarmDocmessageDao extends HibernateSQLTools implements FarmDocmessageDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDocmessage entity) { + Session session = sessionFatory.getCurrentSession(); + session.delete(entity); + } + + public int getAllListNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_docmessage"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + public FarmDocmessage getEntity(String id) { + Session session = sessionFatory.getCurrentSession(); + return (FarmDocmessage) session.get(FarmDocmessage.class, id); + } + + public FarmDocmessage insertEntity(FarmDocmessage entity) { + Session session = sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + + public void editEntity(FarmDocmessage entity) { + Session session = sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + + public DataResult runSqlQuery(DataQuery query) { + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction( + sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), + values, rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + public int getNoReadMessageNum(String userId) { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_docmessage where READUSERID=? and READSTATE='0'"); + sqlquery.setString(0, userId); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public int getAppMessageNum(String appid) { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_docmessage where APPID=?"); + sqlquery.setString(0, appid); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + @Override + protected Class getTypeClass() { + return FarmDocmessage.class; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocruninfoDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocruninfoDao.java new file mode 100644 index 0000000..29d36f4 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocruninfoDao.java @@ -0,0 +1,131 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmDocruninfoDaoInter; +import com.farm.doc.domain.FarmDocruninfo; + +/** + * 实体管理 + * + * @author MAC_wd + * + */ +@Repository +public class FarmDocruninfoDao extends HibernateSQLTools implements FarmDocruninfoDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDocruninfo entity) { + Session session = sessionFatory.getCurrentSession(); + session.delete(entity); + } + + public int getAllListNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from farm_docruninfo"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + public FarmDocruninfo getEntity(String id) { + Session session = sessionFatory.getCurrentSession(); + return (FarmDocruninfo) session.get(FarmDocruninfo.class, id); + } + + public FarmDocruninfo insertEntity(FarmDocruninfo entity) { + Session session = sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + + public void editEntity(FarmDocruninfo entity) { + Session session = sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + + public DataResult runSqlQuery(DataQuery query) { + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + + @Override + protected Class getTypeClass() { + return FarmDocruninfo.class; + } + + @Override + public Integer getKnowsNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from FARM_DOC where STATE=1 and DOMTYPE!=4"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public Integer getGoodKnowsNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery( + "select count(*) from FARM_DOC a left join FARM_DOCRUNINFO b on a.RUNINFOID=b.ID where a.STATE=1 and a.DOMTYPE!=4 and b.EVALUATE>=0"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Override + public Integer getBadKnowsNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery( + "select count(*) from FARM_DOC a left join FARM_DOCRUNINFO b on a.RUNINFOID=b.ID where a.STATE=1 and a.DOMTYPE!=4 and b.EVALUATE<0"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocruninfoDetailDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocruninfoDetailDao.java new file mode 100644 index 0000000..0552f13 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDocruninfoDetailDao.java @@ -0,0 +1,115 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmDocruninfoDetailDaoInter; +import com.farm.doc.domain.FarmDocruninfoDetail; + +/** + * 用户用量明细 + * + * @author MAC_wd + * + */ +@Repository +public class FarmDocruninfoDetailDao extends HibernateSQLTools implements FarmDocruninfoDetailDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDocruninfoDetail entity) { + Session session = sessionFatory.getCurrentSession(); + session.delete(entity); + } + + public int getAllListNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session + .createSQLQuery("select count(*) from farm_docruninfo_detail"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + public FarmDocruninfoDetail getEntity(String id) { + Session session = sessionFatory.getCurrentSession(); + return (FarmDocruninfoDetail) session.get(FarmDocruninfoDetail.class, + id); + } + + public FarmDocruninfoDetail insertEntity(FarmDocruninfoDetail entity) { + Session session = sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + + public void editEntity(FarmDocruninfoDetail entity) { + Session session = sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + + public DataResult runSqlQuery(DataQuery query) { + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction( + sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), + values, rules); + } + + @Override + public int countEntitys(List rules) { + return countSqlFromFunction(sessionFatory.getCurrentSession(), + rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + @Override + protected Class getTypeClass() { + return FarmDocruninfoDetail.class; + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDoctextDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDoctextDao.java new file mode 100644 index 0000000..97e51ce --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDoctextDao.java @@ -0,0 +1,98 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmDoctextDaoInter; +import com.farm.doc.domain.FarmDoctext; + +/**文档内容 + * @author MAC_wd + * + */ +@Repository +public class FarmDoctextDao extends HibernateSQLTools implements FarmDoctextDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDoctext entity) { + Session session=sessionFatory.getCurrentSession(); + session.delete(entity); + } + public int getAllListNum(){ + Session session= sessionFatory.getCurrentSession(); + SQLQuery sqlquery= session.createSQLQuery("select count(*) from farm_doctext"); + BigInteger num=(BigInteger)sqlquery.list().get(0); + return num.intValue() ; + } + public FarmDoctext getEntity(String id) { + Session session= sessionFatory.getCurrentSession(); + return (FarmDoctext)session.get(FarmDoctext.class, id); + } + public FarmDoctext insertEntity(FarmDoctext entity) { + Session session= sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + public void editEntity(FarmDoctext entity) { + Session session= sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + public DataResult runSqlQuery(DataQuery query){ + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction( + sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), + values, rules); + } + + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + @Override + protected Class getTypeClass() { + return FarmDoctext.class; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDoctypeDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDoctypeDao.java new file mode 100644 index 0000000..dd8dce9 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmDoctypeDao.java @@ -0,0 +1,113 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmDoctypeDaoInter; +import com.farm.doc.domain.FarmDoctype; + +/** + * 文档分类 + * + * @author MAC_wd + * + */ +@Repository +public class FarmDoctypeDao extends HibernateSQLTools implements FarmDoctypeDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmDoctype entity) { + Session session = sessionFatory.getCurrentSession(); + session.delete(entity); + } + + public int getAllListNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from farm_doctype"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + public FarmDoctype getEntity(String id) { + Session session = sessionFatory.getCurrentSession(); + return (FarmDoctype) session.get(FarmDoctype.class, id); + } + + public FarmDoctype insertEntity(FarmDoctype entity) { + Session session = sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + + public void editEntity(FarmDoctype entity) { + Session session = sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + + public DataResult runSqlQuery(DataQuery query) { + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + + @Override + protected Class getTypeClass() { + return FarmDoctype.class; + } + + @Override + public Integer getTypesNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from FARM_DOCTYPE where PSTATE=1"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmRfDoctextfileDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmRfDoctextfileDao.java new file mode 100644 index 0000000..ed11f7a --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmRfDoctextfileDao.java @@ -0,0 +1,98 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmRfDoctextfileDaoInter; +import com.farm.doc.domain.FarmRfDoctextfile; + +/**中间表-内容-附件 + * @author MAC_wd + * + */ +@Repository +public class FarmRfDoctextfileDao extends HibernateSQLTools implements FarmRfDoctextfileDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + public void deleteEntity(FarmRfDoctextfile entity) { + Session session=sessionFatory.getCurrentSession(); + session.delete(entity); + } + public int getAllListNum(){ + Session session= sessionFatory.getCurrentSession(); + SQLQuery sqlquery= session.createSQLQuery("select count(*) from farm_rf_doctextfile"); + BigInteger num=(BigInteger)sqlquery.list().get(0); + return num.intValue() ; + } + public FarmRfDoctextfile getEntity(String id) { + Session session= sessionFatory.getCurrentSession(); + return (FarmRfDoctextfile)session.get(FarmRfDoctextfile.class, id); + } + public FarmRfDoctextfile insertEntity(FarmRfDoctextfile entity) { + Session session= sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + public void editEntity(FarmRfDoctextfile entity) { + Session session= sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + public DataResult runSqlQuery(DataQuery query){ + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + @Override + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + return selectSqlFromFunction( + sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), + values, rules); + } + + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + @Override + protected Class getTypeClass() { + return FarmRfDoctextfile.class; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmRfDoctypeDao.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmRfDoctypeDao.java new file mode 100644 index 0000000..fcdb3a2 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmRfDoctypeDao.java @@ -0,0 +1,139 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import com.farm.doc.dao.FarmRfDoctypeDaoInter; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.domain.FarmRfDoctype; + +/** + * 中间表-分类文档 + * + * @author MAC_wd + * + */ +@Repository +public class FarmRfDoctypeDao extends HibernateSQLToolsimplements FarmRfDoctypeDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Transactional + public void deleteEntity(FarmRfDoctype entity) { + Session session = sessionFatory.getCurrentSession(); + session.delete(entity); + } + + @Transactional + public int getAllListNum() { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = session.createSQLQuery("select count(*) from farm_rf_doctype"); + BigInteger num = (BigInteger) sqlquery.list().get(0); + return num.intValue(); + } + + @Transactional + public FarmRfDoctype getEntity(String id) { + Session session = sessionFatory.getCurrentSession(); + return (FarmRfDoctype) session.get(FarmRfDoctype.class, id); + } + + @Transactional + public FarmRfDoctype insertEntity(FarmRfDoctype entity) { + Session session = sessionFatory.getCurrentSession(); + session.save(entity); + return entity; + } + + @Transactional + public void editEntity(FarmRfDoctype entity) { + Session session = sessionFatory.getCurrentSession(); + session.update(entity); + } + + @Override + public Session getSession() { + return sessionFatory.getCurrentSession(); + } + + public DataResult runSqlQuery(DataQuery query) { + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + + @Override + @Transactional + public void deleteEntitys(List rules) { + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + @Transactional + public List selectEntitys(List rules) { + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + @Transactional + public void updataEntitys(Map values, List rules) { + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + + @SuppressWarnings("unchecked") + @Override + @Transactional + public List getDocTypes(String docId) { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = (SQLQuery) session + .createSQLQuery( + "select a.NAME AS NAME,a.TYPEMOD AS TYPEMOD,a.READPOP as READPOP,a.WRITEPOP as WRITEPOP,a.AUDITPOP as AUDITPOP,a.CONTENTMOD AS CONTENTMOD,a.SORT AS SORT,a.TYPE AS TYPE,a.METATITLE AS METATITLE,a.METAKEY AS METAKEY,a.METACONTENT AS METACONTENT,a.LINKURL AS LINKURL,a.ID AS ID,a.CTIME AS CTIME,a.ETIME AS ETIME,a.CUSERNAME AS CUSERNAME,a.CUSER AS CUSER,a.EUSERNAME AS EUSERNAME,a.EUSER AS EUSER,a.PCONTENT AS PCONTENT,a.PSTATE,a.PARENTID,a.TAGS,a.TREECODE FROM farm_doctype a LEFT JOIN farm_rf_doctype b ON a.ID=b.TYPEID where b.docid=?") + .addEntity(FarmDoctype.class).setString(0, docId); + return (List) sqlquery.list(); + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } + + @Override + protected Class getTypeClass() { + return FarmRfDoctype.class; + } + + @Override + public FarmDoctype getDocType(String docId) { + Session session = sessionFatory.getCurrentSession(); + SQLQuery sqlquery = (SQLQuery) session + .createSQLQuery( + "select a.NAME AS NAME,a.TYPEMOD AS TYPEMOD,a.READPOP as READPOP,a.WRITEPOP as WRITEPOP,a.AUDITPOP as AUDITPOP,a.CONTENTMOD AS CONTENTMOD,a.SORT AS SORT,a.TYPE AS TYPE,a.METATITLE AS METATITLE,a.METAKEY AS METAKEY,a.METACONTENT AS METACONTENT,a.LINKURL AS LINKURL,a.ID AS ID,a.CTIME AS CTIME,a.ETIME AS ETIME,a.CUSERNAME AS CUSERNAME,a.CUSER AS CUSER,a.EUSERNAME AS EUSERNAME,a.EUSER AS EUSER,a.PCONTENT AS PCONTENT,a.PSTATE,a.PARENTID,a.TAGS,a.TREECODE FROM farm_doctype a LEFT JOIN farm_rf_doctype b ON a.ID=b.TYPEID where b.docid=?") + .addEntity(FarmDoctype.class).setString(0, docId); + @SuppressWarnings("unchecked") + List list = (List) sqlquery.list(); + return list.size() > 0 ? list.get(0) : null; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmtopDaoImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmtopDaoImpl.java new file mode 100644 index 0000000..e8c37d2 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/FarmtopDaoImpl.java @@ -0,0 +1,120 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import com.farm.doc.domain.Farmtop; +import com.farm.doc.dao.FarmtopDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import java.util.List; +import java.util.Map; +import org.springframework.stereotype.Repository; +import javax.annotation.Resource; + +/* * + *功能:置顶文档持久层实现 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Repository +public class FarmtopDaoImpl extends HibernateSQLTools implements FarmtopDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Farmtop farmtop) { + // TODO 自动生成代码,修改后请去除本注释 + Session session=sessionFatory.getCurrentSession(); + session.delete(farmtop); + } + @Override + public int getAllListNum(){ + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + SQLQuery sqlquery= session.createSQLQuery("select count(*) from farm_code_field"); + BigInteger num=(BigInteger)sqlquery.list().get(0); + return num.intValue() ; + } + @Override + public Farmtop getEntity(String farmtopid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + return (Farmtop)session.get(Farmtop.class, farmtopid); + } + @Override + public Farmtop insertEntity(Farmtop farmtop) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + session.save(farmtop); + return farmtop; + } + @Override + public void editEntity(Farmtop farmtop) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + session.update(farmtop); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + @Override + public DataResult runSqlQuery(DataQuery query){ + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + // TODO 自动生成代码,修改后请去除本注释 + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + @Override + protected Class getTypeClass() { + return Farmtop.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/UsermessageDaoImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/UsermessageDaoImpl.java new file mode 100644 index 0000000..f464efc --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/UsermessageDaoImpl.java @@ -0,0 +1,120 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import com.farm.doc.domain.Usermessage; +import com.farm.doc.dao.UsermessageDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import java.util.List; +import java.util.Map; +import org.springframework.stereotype.Repository; +import javax.annotation.Resource; + +/* * + *功能:用户消息持久层实现 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Repository +public class UsermessageDaoImpl extends HibernateSQLTools implements UsermessageDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Usermessage usermessage) { + // TODO 自动生成代码,修改后请去除本注释 + Session session=sessionFatory.getCurrentSession(); + session.delete(usermessage); + } + @Override + public int getAllListNum(){ + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + SQLQuery sqlquery= session.createSQLQuery("select count(*) from farm_code_field"); + BigInteger num=(BigInteger)sqlquery.list().get(0); + return num.intValue() ; + } + @Override + public Usermessage getEntity(String usermessageid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + return (Usermessage)session.get(Usermessage.class, usermessageid); + } + @Override + public Usermessage insertEntity(Usermessage usermessage) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + session.save(usermessage); + return usermessage; + } + @Override + public void editEntity(Usermessage usermessage) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + session.update(usermessage); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + @Override + public DataResult runSqlQuery(DataQuery query){ + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + // TODO 自动生成代码,修改后请去除本注释 + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + @Override + protected Class getTypeClass() { + return Usermessage.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/WeburlDaoImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/WeburlDaoImpl.java new file mode 100644 index 0000000..1cc951a --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/dao/impl/WeburlDaoImpl.java @@ -0,0 +1,120 @@ +package com.farm.doc.dao.impl; + +import java.math.BigInteger; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import com.farm.doc.domain.Weburl; +import com.farm.doc.dao.WeburlDaoInter; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.utils.HibernateSQLTools; +import java.util.List; +import java.util.Map; +import org.springframework.stereotype.Repository; +import javax.annotation.Resource; + +/* * + *功能:推荐服务持久层实现 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Repository +public class WeburlDaoImpl extends HibernateSQLTools implements WeburlDaoInter { + @Resource(name = "sessionFactory") + private SessionFactory sessionFatory; + + @Override + public void deleteEntity(Weburl weburl) { + // TODO 自动生成代码,修改后请去除本注释 + Session session=sessionFatory.getCurrentSession(); + session.delete(weburl); + } + @Override + public int getAllListNum(){ + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + SQLQuery sqlquery= session.createSQLQuery("select count(*) from farm_code_field"); + BigInteger num=(BigInteger)sqlquery.list().get(0); + return num.intValue() ; + } + @Override + public Weburl getEntity(String weburlid) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + return (Weburl)session.get(Weburl.class, weburlid); + } + @Override + public Weburl insertEntity(Weburl weburl) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + session.save(weburl); + return weburl; + } + @Override + public void editEntity(Weburl weburl) { + // TODO 自动生成代码,修改后请去除本注释 + Session session= sessionFatory.getCurrentSession(); + session.update(weburl); + } + + @Override + public Session getSession() { + // TODO 自动生成代码,修改后请去除本注释 + return sessionFatory.getCurrentSession(); + } + @Override + public DataResult runSqlQuery(DataQuery query){ + // TODO 自动生成代码,修改后请去除本注释 + try { + return query.search(sessionFatory.getCurrentSession()); + } catch (Exception e) { + return null; + } + } + @Override + public void deleteEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + deleteSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public List selectEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return selectSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + @Override + public void updataEntitys(Map values, List rules) { + // TODO 自动生成代码,修改后请去除本注释 + updataSqlFromFunction(sessionFatory.getCurrentSession(), values, rules); + } + + @Override + public int countEntitys(List rules) { + // TODO 自动生成代码,修改后请去除本注释 + return countSqlFromFunction(sessionFatory.getCurrentSession(), rules); + } + + public SessionFactory getSessionFatory() { + return sessionFatory; + } + + public void setSessionFatory(SessionFactory sessionFatory) { + this.sessionFatory = sessionFatory; + } + @Override + protected Class getTypeClass() { + return Weburl.class; + } + + @Override + protected SessionFactory getSessionFactory() { + return sessionFatory; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/Doc.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/Doc.java new file mode 100644 index 0000000..987b699 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/Doc.java @@ -0,0 +1,226 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +import com.farm.core.time.TimeTool; +/* * + *功能:文档类 + *详细: + * + *版本:v2.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Entity(name = "Doc") +@Table(name = "farm_doc") +public class Doc implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "DOCGROUPID", length = 32) + private String docgroupid; + @Column(name = "RUNINFOID", length = 32, nullable = false) + private String runinfoid; + @Column(name = "READPOP", length = 2, nullable = false) + private String readpop; + @Column(name = "WRITEPOP", length = 2, nullable = false) + private String writepop; + @Column(name = "TEXTID", length = 32, nullable = false) + private String textid; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "EUSERNAME", length = 64, nullable = false) + private String eusername; + @Column(name = "EUSER", length = 32, nullable = false) + private String euser; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "STATE", length = 2, nullable = false) + private String state; + @Column(name = "IMGID", length = 32) + private String imgid; + @Column(name = "TOPLEVE", length = 10) + private Integer topleve; + @Column(name = "SOURCE", length = 256) + private String source; + @Column(name = "TAGKEY", length = 1024) + private String tagkey; + @Column(name = "SHORTTITLE", length = 64) + private String shorttitle; + @Column(name = "DOMTYPE", length = 2, nullable = false) + private String domtype; + @Column(name = "PUBTIME", length = 14, nullable = false) + private String pubtime; + @Column(name = "TITLE", length = 256, nullable = false) + private String title; + @Column(name = "AUTHOR", length = 64) + private String author; + @Column(name = "DOCDESCRIBE", length = 256) + private String docdescribe; + //-------------------------------------------- + + public String getDocgroupid() { + return this.docgroupid; + } + public void setDocgroupid(String docgroupid) { + this.docgroupid = docgroupid; + } + public String getRuninfoid() { + return this.runinfoid; + } + public void setRuninfoid(String runinfoid) { + this.runinfoid = runinfoid; + } + public String getReadpop() { + return this.readpop; + } + public void setReadpop(String readpop) { + this.readpop = readpop; + } + public String getWritepop() { + return this.writepop; + } + public void setWritepop(String writepop) { + this.writepop = writepop; + } + public String getTextid() { + return this.textid; + } + public void setTextid(String textid) { + this.textid = textid; + } + public String getPcontent() { + return this.pcontent; + } + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + public String getCuser() { + return this.cuser; + } + public void setCuser(String cuser) { + this.cuser = cuser; + } + public String getEusername() { + return this.eusername; + } + public void setEusername(String eusername) { + this.eusername = eusername; + } + public String getEuser() { + return this.euser; + } + public void setEuser(String euser) { + this.euser = euser; + } + public String getEtime() { + return this.etime; + } + public void setEtime(String etime) { + this.etime = etime; + } + public String getCusername() { + return this.cusername; + } + public void setCusername(String cusername) { + this.cusername = cusername; + } + public String getCtime() { + return this.ctime; + } + public void setCtime(String ctime) { + this.ctime = ctime; + } + public String getId() { + return this.id; + } + public void setId(String id) { + this.id = id; + } + public String getState() { + return this.state; + } + public void setState(String state) { + this.state = state; + } + public String getImgid() { + return this.imgid; + } + public void setImgid(String imgid) { + this.imgid = imgid; + } + public Integer getTopleve() { + return this.topleve; + } + public void setTopleve(Integer topleve) { + this.topleve = topleve; + } + public String getSource() { + return this.source; + } + public void setSource(String source) { + this.source = source; + } + public String getTagkey() { + return this.tagkey; + } + public void setTagkey(String tagkey) { + this.tagkey = tagkey; + } + public String getShorttitle() { + return this.shorttitle; + } + public void setShorttitle(String shorttitle) { + this.shorttitle = shorttitle; + } + public String getDomtype() { + return this.domtype; + } + public void setDomtype(String domtype) { + this.domtype = domtype; + } + public String getPubtime() { + if(pubtime == null || pubtime.isEmpty()){ + pubtime = TimeTool.getTimeDate14(); + } + return this.pubtime; + } + public void setPubtime(String pubtime) { + this.pubtime = pubtime; + } + public String getTitle() { + return this.title; + } + public void setTitle(String title) { + this.title = title; + } + public String getAuthor() { + return this.author; + } + public void setAuthor(String author) { + this.author = author; + } + public String getDocdescribe() { + return this.docdescribe; + } + public void setDocdescribe(String docdescribe) { + this.docdescribe = docdescribe; + } +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocenjoy.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocenjoy.java new file mode 100644 index 0000000..12dfa26 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocenjoy.java @@ -0,0 +1,68 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmDocenjoy entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmDocenjoy") +@Table(name = "farm_docenjoy") +public class FarmDocenjoy implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "USERID", length = 32, nullable = false) + private String userid; + @Column(name = "DOCID", length = 32, nullable = false) + private String docid; + + // Constructors + + /** default constructor */ + public FarmDocenjoy() { + } + + /** full constructor */ + public FarmDocenjoy(String docid, String userid) { + this.docid = docid; + this.userid = userid; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDocid() { + return this.docid; + } + + public void setDocid(String docid) { + this.docid = docid; + } + + public String getUserid() { + return this.userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocfile.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocfile.java new file mode 100644 index 0000000..79294a2 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocfile.java @@ -0,0 +1,256 @@ +package com.farm.doc.domain; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.hibernate.annotations.GenericGenerator; + +@Entity(name = "FarmDocfile") +@Table(name = "farm_docfile") +public class FarmDocfile implements java.io.Serializable { + private static final long serialVersionUID = 3911185369411888075L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "EUSER", length = 32, nullable = false) + private String euser; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "EUSERNAME", length = 64, nullable = false) + private String eusername; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "FILENAME", length = 64, nullable = false) + private String filename; + @Column(name = "DIR", length = 256, nullable = false) + private String dir; + @Column(name = "LEN", length = 12, nullable = false) + private Float len; + @Column(name = "EXNAME", length = 16, nullable = false) + private String exname; + @Column(name = "NAME", length = 64, nullable = false) + private String name; + @Column(name = "TYPE", length = 2, nullable = false) + private String type; + @Column(name = "SERVERID", length = 32, nullable = false) + private String serverid; + + @Transient + private File file; + @Transient + private String url; + + public FarmDocfile() { + } + + public FarmDocfile(String dir, String serverid, String type, String name, + String filename, String ctime, String etime, String cusername, + String cuser, String eusername, String euser, String pstate) { + this.dir = dir; + this.serverid = serverid; + this.type = type; + this.name = name; + this.filename = filename; + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + } + + public FarmDocfile(String dir, String serverid, String type, String name, + String filename, String ctime, String etime, String cusername, + String cuser, String eusername, String euser, String pstate, + String pcontent, String exname, Float len) { + this.dir = dir; + this.serverid = serverid; + this.type = type; + this.name = name; + this.filename = filename; + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + this.exname = exname; + this.len = len; + this.pcontent = pcontent; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getEuser() { + return this.euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getPcontent() { + return this.pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getEusername() { + return this.eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getEtime() { + return this.etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFilename() { + return this.filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getDir() { + return this.dir; + } + + public void setDir(String dir) { + this.dir = dir; + } + + public Float getLen() { + return len; + } + + public void setLen(Float len) { + this.len = len; + } + + public String getExname() { + return this.exname; + } + + public void setExname(String exname) { + this.exname = exname; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public String getServerid() { + return this.serverid; + } + + public void setServerid(String serverid) { + this.serverid = serverid; + } + + public InputStream getInputStream() throws FileNotFoundException { + if(!file.exists()){ + return null; + } + + return new FileInputStream(file); + } + + public File getFile() { + return file; + } + + public void setFile(File file) { + this.file = file; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocgroup.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocgroup.java new file mode 100644 index 0000000..be39e02 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocgroup.java @@ -0,0 +1,233 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmDocgroup entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmDocgroup") +@Table(name = "farm_docgroup") +public class FarmDocgroup implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "JOINCHECK", length = 2, nullable = false) + private String joincheck; + @Column(name = "HOMEDOCID", length = 32) + private String homedocid; + @Column(name = "USERNUM", length = 10, nullable = false) + private Integer usernum; + @Column(name = "GROUPIMG", length = 32, nullable = false) + private String groupimg; + @Column(name = "GROUPTAG", length = 256, nullable = false) + private String grouptag; + @Column(name = "GROUPNOTE", length = 256, nullable = false) + private String groupnote; + @Column(name = "GROUPNAME", length = 128, nullable = false) + private String groupname; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "EUSER", length = 32, nullable = false) + private String euser; + @Column(name = "EUSERNAME", length = 64, nullable = false) + private String eusername; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + + + // Constructors + + /** default constructor */ + public FarmDocgroup() { + } + + /** minimal constructor */ + public FarmDocgroup(String ctime, String etime, String cusername, + String cuser, String eusername, String euser, String pstate, + String groupname, String groupnote, String grouptag, + String groupimg, String joincheck) { + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + this.groupname = groupname; + this.groupnote = groupnote; + this.grouptag = grouptag; + this.groupimg = groupimg; + this.joincheck = joincheck; + } + + /** full constructor */ + public FarmDocgroup(String ctime, String etime, String cusername, + String cuser, String eusername, String euser, String pstate, + String pcontent, String groupname, String groupnote, + String grouptag, String groupimg, String joincheck) { + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + this.pcontent = pcontent; + this.groupname = groupname; + this.groupnote = groupnote; + this.grouptag = grouptag; + this.groupimg = groupimg; + this.joincheck = joincheck; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getEtime() { + return this.etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getEusername() { + return this.eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getEuser() { + return this.euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getPcontent() { + return this.pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getGroupname() { + return this.groupname; + } + + public void setGroupname(String groupname) { + this.groupname = groupname; + } + + public String getGroupnote() { + return this.groupnote; + } + + public void setGroupnote(String groupnote) { + this.groupnote = groupnote; + } + + public String getGrouptag() { + return this.grouptag; + } + + public void setGrouptag(String grouptag) { + this.grouptag = grouptag; + } + + public String getGroupimg() { + return this.groupimg; + } + + public void setGroupimg(String groupimg) { + this.groupimg = groupimg; + } + + public String getJoincheck() { + return this.joincheck; + } + + public void setJoincheck(String joincheck) { + this.joincheck = joincheck; + } + + + public Integer getUsernum() { + return usernum; + } + + public void setUsernum(Integer usernum) { + this.usernum = usernum; + } + + public String getHomedocid() { + return homedocid; + } + + public void setHomedocid(String homedocid) { + this.homedocid = homedocid; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocgroupUser.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocgroupUser.java new file mode 100644 index 0000000..77010fa --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocgroupUser.java @@ -0,0 +1,234 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmDocgroupUser entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmDocgroupUser") +@Table(name = "farm_docgroup_user") +public class FarmDocgroupUser implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "APPLYNOTE", length = 128) + private String applynote; + @Column(name = "SHOWHOME", length = 2, nullable = false) + private String showhome; + @Column(name = "SHOWSORT", length = 10, nullable = false) + private Integer showsort; + @Column(name = "EDITIS", length = 2, nullable = false) + private String editis; + @Column(name = "LEADIS", length = 2, nullable = false) + private String leadis; + @Column(name = "USERID", length = 32, nullable = false) + private String userid; + @Column(name = "GROUPID", length = 32, nullable = false) + private String groupid; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "EUSER", length = 32, nullable = false) + private String euser; + @Column(name = "EUSERNAME", length = 64, nullable = false) + private String eusername; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + + // Constructors + + /** default constructor */ + public FarmDocgroupUser() { + } + + /** minimal constructor */ + public FarmDocgroupUser(String ctime, String etime, String cusername, + String cuser, String eusername, String euser, String pstate, + String groupid, String userid, String leadis, String editis, + String showhome, Integer showsort) { + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + this.groupid = groupid; + this.userid = userid; + this.leadis = leadis; + this.editis = editis; + this.showhome = showhome; + this.showsort = showsort; + } + + /** full constructor */ + public FarmDocgroupUser(String ctime, String etime, String cusername, + String cuser, String eusername, String euser, String pstate, + String pcontent, String groupid, String userid, String leadis, + String editis, String showhome, Integer showsort) { + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + this.pcontent = pcontent; + this.groupid = groupid; + this.userid = userid; + this.leadis = leadis; + this.editis = editis; + this.showhome = showhome; + this.showsort = showsort; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getEtime() { + return this.etime; + } + + public String getApplynote() { + return applynote; + } + + public void setApplynote(String applynote) { + this.applynote = applynote; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getEusername() { + return this.eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getEuser() { + return this.euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getPcontent() { + return this.pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getGroupid() { + return this.groupid; + } + + public void setGroupid(String groupid) { + this.groupid = groupid; + } + + public String getUserid() { + return this.userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + + public String getLeadis() { + return this.leadis; + } + + public void setLeadis(String leadis) { + this.leadis = leadis; + } + + public String getEditis() { + return this.editis; + } + + public void setEditis(String editis) { + this.editis = editis; + } + + public String getShowhome() { + return this.showhome; + } + + public void setShowhome(String showhome) { + this.showhome = showhome; + } + + public Integer getShowsort() { + return this.showsort; + } + + public void setShowsort(Integer showsort) { + this.showsort = showsort; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocmessage.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocmessage.java new file mode 100644 index 0000000..673a97a --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocmessage.java @@ -0,0 +1,199 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmDocmessage entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmDocmessage") +@Table(name = "farm_docmessage") +public class FarmDocmessage implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "READSTATE", length = 2, nullable = false) + private String readstate; + @Column(name = "APPID", length = 32) + private String appid; + @Column(name = "TITLE", length = 64, nullable = false) + private String title; + @Column(name = "CONTENT", length = 256, nullable = false) + private String content; + @Column(name = "READUSERID", length = 32, nullable = false) + private String readuserid; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "PRAISNUM") + private int praisnum; + @Column(name = "CRITCISMNUM") + private int critcismnum; + @Column(name = "PARENTID", length = 32) + private String parentid; + + + /** default constructor */ + public FarmDocmessage() { + } + + /** minimal constructor */ + public FarmDocmessage(String ctime, String cusername, String pstate, + String readuserid, String content, String title, String readstate) { + this.ctime = ctime; + this.cusername = cusername; + this.pstate = pstate; + this.readuserid = readuserid; + this.content = content; + this.title = title; + this.readstate = readstate; + } + + /** full constructor */ + public FarmDocmessage(String ctime, String cusername, String pstate, + String pcontent, String readuserid, String content, String title, + String appid, String readstate) { + this.ctime = ctime; + this.cusername = cusername; + this.pstate = pstate; + this.pcontent = pcontent; + this.readuserid = readuserid; + this.content = content; + this.title = title; + this.appid = appid; + this.readstate = readstate; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public String getParentid() { + return parentid; + } + + public void setParentid(String parentid) { + this.parentid = parentid; + } + + public void setId(String id) { + this.id = id; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getPcontent() { + return this.pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getReaduserid() { + return this.readuserid; + } + + public void setReaduserid(String readuserid) { + this.readuserid = readuserid; + } + + public String getContent() { + return this.content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAppid() { + return this.appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getReadstate() { + return this.readstate; + } + + public void setReadstate(String readstate) { + this.readstate = readstate; + } + + public String getCuser() { + return cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public int getPraisnum() { + return praisnum; + } + + public void setPraisnum(int praisnum) { + this.praisnum = praisnum; + } + + public int getCritcismnum() { + return critcismnum; + } + + public void setCritcismnum(int critcismnum) { + this.critcismnum = critcismnum; + } + + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocruninfo.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocruninfo.java new file mode 100644 index 0000000..41e7e00 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocruninfo.java @@ -0,0 +1,124 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmDocruninfo entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmDocruninfo") +@Table(name = "farm_docruninfo") +public class FarmDocruninfo implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + @Column(name = "ANSWERINGNUM", length = 10, nullable = false) + private Integer answeringnum; + @Column(name = "PRAISEYES", length = 10, nullable = false) + private Integer praiseyes; + @Column(name = "PRAISENO", length = 10, nullable = false) + private Integer praiseno; + @Column(name = "EVALUATE", length = 10, nullable = false) + private Integer evaluate; + @Column(name = "LASTVTIME", length = 14, nullable = false) + private String lastvtime; + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "HOTNUM", length = 10, nullable = false) + private Integer hotnum; + @Column(name = "VISITNUM", length = 10, nullable = false) + private Integer visitnum; + + // Constructors + + /** default constructor */ + public FarmDocruninfo() { + } + + /** full constructor */ + public FarmDocruninfo(Integer visitnum, Integer hotnum, String lastvtime, + Integer praiseyes, Integer praiseno, Integer evaluate) { + this.visitnum = visitnum; + this.hotnum = hotnum; + this.lastvtime = lastvtime; + this.praiseyes = praiseyes; + this.praiseno = praiseno; + this.evaluate = evaluate; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public Integer getVisitnum() { + return this.visitnum; + } + + public void setVisitnum(Integer visitnum) { + this.visitnum = visitnum; + } + + public Integer getHotnum() { + return this.hotnum; + } + + public void setHotnum(Integer hotnum) { + this.hotnum = hotnum; + } + + public String getLastvtime() { + return this.lastvtime; + } + + public void setLastvtime(String lastvtime) { + this.lastvtime = lastvtime; + } + + public Integer getPraiseyes() { + return this.praiseyes; + } + + public void setPraiseyes(Integer praiseyes) { + this.praiseyes = praiseyes; + } + + public Integer getPraiseno() { + return this.praiseno; + } + + public void setPraiseno(Integer praiseno) { + this.praiseno = praiseno; + } + + public Integer getEvaluate() { + return this.evaluate; + } + + public void setEvaluate(Integer evaluate) { + this.evaluate = evaluate; + } + + public Integer getAnsweringnum() { + return answeringnum; + } + + public void setAnsweringnum(Integer answeringnum) { + this.answeringnum = answeringnum; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocruninfoDetail.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocruninfoDetail.java new file mode 100644 index 0000000..33608e7 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDocruninfoDetail.java @@ -0,0 +1,159 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmDocruninfoDetail entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmDocruninfoDetail") +@Table(name = "farm_docruninfo_detail") +public class FarmDocruninfoDetail implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "USERIP", length = 128, nullable = false) + private String userip; + @Column(name = "RUNINFOID", length = 32, nullable = false) + private String runinfoid; + @Column(name = "DOCTEXTID", length = 32, nullable = false) + private String doctextid; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "VTYPE", length = 2, nullable = false) + private String vtype; + @Column(name = "CUSERNAME", length = 64) + private String cusername; + @Column(name = "CUSER", length = 32) + private String cuser; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + + // Constructors + + /** default constructor */ + public FarmDocruninfoDetail() { + } + + /** minimal constructor */ + public FarmDocruninfoDetail(String ctime, String pstate, String vtype, + String doctextid, String runinfoid, String userip) { + this.ctime = ctime; + this.pstate = pstate; + this.vtype = vtype; + this.doctextid = doctextid; + this.runinfoid = runinfoid; + this.userip = userip; + } + + /** full constructor */ + public FarmDocruninfoDetail(String ctime, String cusername, String cuser, + String pstate, String pcontent, String vtype, String doctextid, + String runinfoid, String userip) { + this.ctime = ctime; + this.cusername = cusername; + this.cuser = cuser; + this.pstate = pstate; + this.pcontent = pcontent; + this.vtype = vtype; + this.doctextid = doctextid; + this.runinfoid = runinfoid; + this.userip = userip; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getPcontent() { + return this.pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getVtype() { + return this.vtype; + } + + public void setVtype(String vtype) { + this.vtype = vtype; + } + + public String getDoctextid() { + return this.doctextid; + } + + public void setDoctextid(String doctextid) { + this.doctextid = doctextid; + } + + public String getRuninfoid() { + return this.runinfoid; + } + + public void setRuninfoid(String runinfoid) { + this.runinfoid = runinfoid; + } + + public String getUserip() { + return this.userip; + } + + public void setUserip(String userip) { + this.userip = userip; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDoctext.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDoctext.java new file mode 100644 index 0000000..0b7e3a5 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDoctext.java @@ -0,0 +1,194 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmDoctext entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmDoctext") +@Table(name = "farm_doctext") +public class FarmDoctext implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "DOCID", length = 32) + private String docid; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "EUSER", length = 32, nullable = false) + private String euser; + @Column(name = "EUSERNAME", length = 64, nullable = false) + private String eusername; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "TEXT1", length = 2147483647, nullable = false) + private String text1; + @Column(name = "TEXT2", length = 2147483647) + private String text2; + @Column(name = "TEXT3", length = 2147483647) + private String text3; + + // Constructors + + /** default constructor */ + public FarmDoctext() { + } + + /** minimal constructor */ + public FarmDoctext(String text1, String ctime, String etime, + String cusername, String cuser, String eusername, String euser, + String pstate) { + this.text1 = text1; + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + } + + /** full constructor */ + public FarmDoctext(String text1, String text2, String text3, String ctime, + String etime, String cusername, String cuser, String eusername, + String euser, String pstate, String pcontent) { + this.text1 = text1; + this.text2 = text2; + this.text3 = text3; + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + this.pcontent = pcontent; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getText1() { + return this.text1; + } + + public void setText1(String text1) { + this.text1 = text1; + } + + public String getText2() { + return this.text2; + } + + public void setText2(String text2) { + this.text2 = text2; + } + + public String getText3() { + return this.text3; + } + + public void setText3(String text3) { + this.text3 = text3; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getEtime() { + return this.etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getEusername() { + return this.eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getEuser() { + return this.euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getPcontent() { + return this.pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getDocid() { + return docid; + } + + public void setDocid(String docid) { + this.docid = docid; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDoctype.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDoctype.java new file mode 100644 index 0000000..c09687b --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmDoctype.java @@ -0,0 +1,311 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmDoctype entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmDoctype") +@Table(name = "farm_doctype") +public class FarmDoctype implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "TAGS", length = 256) + private String tags; + @Column(name = "TREECODE", length = 256, nullable = false) + private String treecode; + @Column(name = "PARENTID", length = 32, nullable = false) + private String parentid; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "EUSERNAME", length = 64, nullable = false) + private String eusername; + @Column(name = "EUSER", length = 32, nullable = false) + private String euser; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "LINKURL", length = 256) + private String linkurl; + @Column(name = "METACONTENT", length = 256) + private String metacontent; + @Column(name = "CONTENTMOD", length = 128) + private String contentmod; + @Column(name = "SORT", length = 10, nullable = false) + private Integer sort; + @Column(name = "TYPE", length = 2, nullable = false) + private String type; + @Column(name = "METATITLE", length = 256) + private String metatitle; + @Column(name = "METAKEY", length = 256) + private String metakey; + @Column(name = "NAME", length = 128, nullable = false) + private String name; + @Column(name = "TYPEMOD", length = 128) + private String typemod; + @Column(name = "READPOP", length = 2, nullable = false) + private String readpop; + @Column(name = "WRITEPOP", length = 2, nullable = false) + private String writepop; + @Column(name = "AUDITPOP", length = 2, nullable = false) + private String auditpop; + + // Constructors + + /** default constructor */ + public FarmDoctype() { + } + + /** minimal constructor */ + public FarmDoctype(String name, Integer sort, String type, String ctime, String etime, String cusername, + String cuser, String eusername, String euser, String pstate) { + this.name = name; + this.sort = sort; + this.type = type; + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pstate = pstate; + } + + /** full constructor */ + public FarmDoctype(String name, String typemod, String contentmod, Integer sort, String type, String metatitle, + String metakey, String metacontent, String linkurl, String ctime, String etime, String cusername, + String cuser, String eusername, String euser, String pcontent, String pstate) { + this.name = name; + this.typemod = typemod; + this.contentmod = contentmod; + this.sort = sort; + this.type = type; + this.metatitle = metatitle; + this.metakey = metakey; + this.metacontent = metacontent; + this.linkurl = linkurl; + this.ctime = ctime; + this.etime = etime; + this.cusername = cusername; + this.cuser = cuser; + this.eusername = eusername; + this.euser = euser; + this.pcontent = pcontent; + this.pstate = pstate; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTypemod() { + return this.typemod; + } + + public void setTypemod(String typemod) { + this.typemod = typemod; + } + + public String getContentmod() { + return this.contentmod; + } + + public void setContentmod(String contentmod) { + this.contentmod = contentmod; + } + + public Integer getSort() { + return this.sort; + } + + public void setSort(Integer sort) { + this.sort = sort; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public String getMetatitle() { + return this.metatitle; + } + + public void setMetatitle(String metatitle) { + this.metatitle = metatitle; + } + + public String getMetakey() { + return this.metakey; + } + + public void setMetakey(String metakey) { + this.metakey = metakey; + } + + public String getMetacontent() { + return this.metacontent; + } + + public void setMetacontent(String metacontent) { + this.metacontent = metacontent; + } + + public String getLinkurl() { + return this.linkurl; + } + + public void setLinkurl(String linkurl) { + this.linkurl = linkurl; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getEtime() { + return this.etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getEusername() { + return this.eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getEuser() { + return this.euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getPcontent() { + return this.pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getParentid() { + return parentid; + } + + public void setParentid(String parentid) { + this.parentid = parentid; + } + + public String getTreecode() { + return treecode; + } + + public void setTreecode(String treecode) { + this.treecode = treecode; + } + + public String getTags() { + return tags; + } + + public void setTags(String tags) { + this.tags = tags; + } + + public String getReadpop() { + return readpop; + } + + public void setReadpop(String readpop) { + this.readpop = readpop; + } + + public String getWritepop() { + return writepop; + } + + public void setWritepop(String writepop) { + this.writepop = writepop; + } + + public String getAuditpop() { + return auditpop; + } + + public void setAuditpop(String auditpop) { + this.auditpop = auditpop; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmRfDoctextfile.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmRfDoctextfile.java new file mode 100644 index 0000000..df4e8f1 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmRfDoctextfile.java @@ -0,0 +1,70 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmRfDoctextfile entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmRfDoctextfile") +@Table(name = "farm_rf_doctextfile") +public class FarmRfDoctextfile implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "FILEID", length = 32, nullable = false) + private String fileid; + @Column(name = "DOCID", length = 32, nullable = false) + private String docid; + + // Constructors + + /** default constructor */ + public FarmRfDoctextfile() { + } + + /** full constructor */ + public FarmRfDoctextfile(String docid, String fileid) { + this.docid = docid; + this.fileid = fileid; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + + public String getDocid() { + return docid; + } + + public void setDocid(String docid) { + this.docid = docid; + } + + public String getFileid() { + return this.fileid; + } + + public void setFileid(String fileid) { + this.fileid = fileid; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmRfDoctype.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmRfDoctype.java new file mode 100644 index 0000000..3cd9b3a --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/FarmRfDoctype.java @@ -0,0 +1,69 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/** + * FarmRfDoctype entity. @author MyEclipse Persistence Tools + */ + +@Entity(name = "FarmRfDoctype") +@Table(name = "farm_rf_doctype") +public class FarmRfDoctype implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "TYPEID", length = 32, nullable = false) + private String typeid; + @Column(name = "DOCID", length = 32, nullable = false) + private String docid; + + // Constructors + + /** default constructor */ + public FarmRfDoctype() { + } + + /** full constructor */ + public FarmRfDoctype(String typeid, String docid) { + this.typeid = typeid; + this.docid = docid; + } + + // Property accessors + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTypeid() { + return this.typeid; + } + + public void setTypeid(String typeid) { + this.typeid = typeid; + } + + public String getDocid() { + return this.docid; + } + + public void setDocid(String docid) { + this.docid = docid; + } + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/Farmtop.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/Farmtop.java new file mode 100644 index 0000000..5df9172 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/Farmtop.java @@ -0,0 +1,92 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; +/* * + *功能:置顶文档类 + *详细: + * + *版本:v2.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Entity(name = "FarmTop") +@Table(name = "farm_top") +public class Farmtop implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "SORT", length = 10, nullable = false) + private Integer sort; + @Column(name = "DOCID", length = 32, nullable = false) + private String docid; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + + public Integer getSort() { + return this.sort; + } + public void setSort(Integer sort) { + this.sort = sort; + } + public String getDocid() { + return this.docid; + } + public void setDocid(String docid) { + this.docid = docid; + } + public String getPcontent() { + return this.pcontent; + } + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + public String getPstate() { + return this.pstate; + } + public void setPstate(String pstate) { + this.pstate = pstate; + } + public String getCuser() { + return this.cuser; + } + public void setCuser(String cuser) { + this.cuser = cuser; + } + public String getId() { + return this.id; + } + public void setId(String id) { + this.id = id; + } + public String getCtime() { + return this.ctime; + } + public void setCtime(String ctime) { + this.ctime = ctime; + } + public String getCusername() { + return this.cusername; + } + public void setCusername(String cusername) { + this.cusername = cusername; + } +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/Usermessage.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/Usermessage.java new file mode 100644 index 0000000..e3a0414 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/Usermessage.java @@ -0,0 +1,108 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; +/* * + *功能:用户消息类 + *详细: + * + *版本:v2.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Entity(name = "Usermessage") +@Table(name = "farm_usermessage") +public class Usermessage implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "READUSERID", length = 32, nullable = false) + private String readuserid; + @Column(name = "CONTENT", length = 256, nullable = false) + private String content; + @Column(name = "TITLE", length = 64, nullable = false) + private String title; + @Column(name = "READSTATE", length = 2, nullable = false) + private String readstate; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "CUSERNAME", length = 64) + private String cusername; + @Column(name = "CUSER", length = 32) + private String cuser; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + + public String getReaduserid() { + return this.readuserid; + } + public void setReaduserid(String readuserid) { + this.readuserid = readuserid; + } + public String getContent() { + return this.content; + } + public void setContent(String content) { + this.content = content; + } + public String getTitle() { + return this.title; + } + public void setTitle(String title) { + this.title = title; + } + public String getReadstate() { + return this.readstate; + } + public void setReadstate(String readstate) { + this.readstate = readstate; + } + public String getPcontent() { + return this.pcontent; + } + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + public String getPstate() { + return this.pstate; + } + public void setPstate(String pstate) { + this.pstate = pstate; + } + public String getCusername() { + return this.cusername; + } + public void setCusername(String cusername) { + this.cusername = cusername; + } + public String getCuser() { + return this.cuser; + } + public void setCuser(String cuser) { + this.cuser = cuser; + } + public String getCtime() { + return this.ctime; + } + public void setCtime(String ctime) { + this.ctime = ctime; + } + public String getId() { + return this.id; + } + public void setId(String id) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/Weburl.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/Weburl.java new file mode 100644 index 0000000..9542656 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/Weburl.java @@ -0,0 +1,158 @@ +package com.farm.doc.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; + +/* * + *功能:推荐服务类 + *详细: + * + *版本:v2.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Entity(name = "Weburl") +@Table(name = "farm_weburl") +public class Weburl implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + @Id + @GenericGenerator(name = "systemUUID", strategy = "uuid") + @GeneratedValue(generator = "systemUUID") + @Column(name = "ID", length = 32, insertable = true, updatable = true, nullable = false) + private String id; + @Column(name = "WEBNAME", length = 64, nullable = false) + private String webname; + @Column(name = "URL", length = 512, nullable = false) + private String url; + @Column(name = "CTIME", length = 16, nullable = false) + private String ctime; + @Column(name = "ETIME", length = 16, nullable = false) + private String etime; + @Column(name = "CUSERNAME", length = 64, nullable = false) + private String cusername; + @Column(name = "CUSER", length = 32, nullable = false) + private String cuser; + @Column(name = "EUSERNAME", length = 64, nullable = false) + private String eusername; + @Column(name = "EUSER", length = 32, nullable = false) + private String euser; + @Column(name = "PCONTENT", length = 128) + private String pcontent; + @Column(name = "PSTATE", length = 2, nullable = false) + private String pstate; + @Column(name = "SORT", nullable = false) + private int sort; + @Column(name = "FILEID") + private String fileid; + + public String getWebname() { + return this.webname; + } + + public void setWebname(String webname) { + this.webname = webname; + } + + public String getUrl() { + return this.url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCtime() { + return this.ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getEtime() { + return this.etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCusername() { + return this.cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getCuser() { + return this.cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getEusername() { + return this.eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getEuser() { + return this.euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getPcontent() { + return this.pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getPstate() { + return this.pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public int getSort() { + return sort; + } + + public void setSort(int sort) { + this.sort = sort; + } + + public String getFileid() { + return fileid; + } + + public void setFileid(String fileid) { + this.fileid = fileid; + } +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/ArticleRepository.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/ArticleRepository.java new file mode 100644 index 0000000..b7a7cca --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/ArticleRepository.java @@ -0,0 +1,18 @@ +package com.example.fulltextsearch.repository; + +import com.example.fulltextsearch.model.Article; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; + +/** + * ArticleRepository接口定义了用于与Elasticsearch交互的数据库操作方法。 + * 它继承自ElasticsearchRepository,这是一个Spring Data Elasticsearch提供的接口, + * 用于简化Elasticsearch的操作。 + * + * @param
存储在Elasticsearch中的文档类型,这里指的是Article类。 + * @param 文档的ID类型,这里使用String作为ID的类型。 + */ +public interface ArticleRepository extends ElasticsearchRepository { + // 这里可以添加自定义的查询方法,例如根据特定字段进行搜索等。 + // Spring Data Elasticsearch会自动生成这些方法的实现。 +} + diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/DocBrief.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/DocBrief.java new file mode 100644 index 0000000..6941bd8 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/DocBrief.java @@ -0,0 +1,225 @@ +package com.farm.doc.domain.ex; + +public class DocBrief implements java.io.Serializable { + /** + * + */ + private static final long serialVersionUID = -7431017567548414571L; + private String docid; + private String title; + private String text; + private String domtype; + private String etime; + private int visitnum; + private int praiseyes; + private int hotnum; + private int praiseno; + private int evaluate; + private int answeringnum; + private String typename; + private String typeid; + private String pubtime; + private String imgid; + private String imgurl; + private String author; + private String authorid; + private String photoid; + private String photourl; + private String userid; + private String username; + private String essence; + private String docpopis; + + public String getDocpopis() { + return docpopis; + } + + public void setDocpopis(String docpopis) { + this.docpopis = docpopis; + } + + public String getEssence() { + return essence; + } + + public void setEssence(String essence) { + this.essence = essence; + } + + public String getDomtype() { + return domtype; + } + + public String getEtime() { + return etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getImgurl() { + return imgurl; + } + + public void setImgurl(String imgurl) { + this.imgurl = imgurl; + } + + public String getPhotourl() { + return photourl; + } + + public void setPhotourl(String photourl) { + this.photourl = photourl; + } + + public String getPhotoid() { + return photoid; + } + + public void setPhotoid(String photoid) { + this.photoid = photoid; + } + + public int getHotnum() { + return hotnum; + } + + public void setHotnum(int hotnum) { + this.hotnum = hotnum; + } + + public void setDomtype(String domtype) { + this.domtype = domtype; + } + + public String getDocid() { + return docid; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getAuthorid() { + return authorid; + } + + public void setAuthorid(String authorid) { + this.authorid = authorid; + } + + public void setDocid(String docid) { + this.docid = docid; + } + + 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 int getVisitnum() { + return visitnum; + } + + public void setVisitnum(int visitnum) { + this.visitnum = visitnum; + } + + public int getPraiseyes() { + return praiseyes; + } + + public void setPraiseyes(int praiseyes) { + this.praiseyes = praiseyes; + } + + public int getPraiseno() { + return praiseno; + } + + public void setPraiseno(int praiseno) { + this.praiseno = praiseno; + } + + public int getEvaluate() { + return evaluate; + } + + public void setEvaluate(int evaluate) { + this.evaluate = evaluate; + } + + public int getAnsweringnum() { + return answeringnum; + } + + public void setAnsweringnum(int answeringnum) { + this.answeringnum = answeringnum; + } + + public String getTypename() { + return typename; + } + + public void setTypename(String typename) { + this.typename = typename; + } + + public String getTypeid() { + return typeid; + } + + public void setTypeid(String typeid) { + this.typeid = typeid; + } + + public String getPubtime() { + return pubtime; + } + + public void setPubtime(String pubtime) { + this.pubtime = pubtime; + } + + public String getImgid() { + return imgid; + } + + public void setImgid(String imgid) { + this.imgid = imgid; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/DocEntire.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/DocEntire.java new file mode 100644 index 0000000..c7462bf --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/DocEntire.java @@ -0,0 +1,247 @@ +package com.farm.doc.domain.ex; + +import java.util.ArrayList; +import java.util.List; + +import com.farm.authority.domain.User; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.time.TimeTool; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDocfile; +import com.farm.doc.domain.FarmDocruninfo; +import com.farm.doc.domain.FarmDoctext; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.server.plus.domain.DocAudit; +import com.farm.doc.server.plus.domain.Doctypepop; + +public class DocEntire implements java.io.Serializable { + + public DocEntire(Doc doc) { + this.doc = doc; + } + + public DocEntire() { + this.doc = new Doc(); + } + + /** + * + */ + private static final long serialVersionUID = 3170304648147893712L; + // 文档信息 + private Doc doc; + // 文档内容 + private FarmDoctext texts; + // 标签 + private List tags; + // 附件 + private List files; + // 类型 + /** + * 分类,1:1新增修改 + */ + private FarmDoctype type; + /** + * 工作小组,1:1新增修改 + */ + private GroupEntire group; + // -------------------------------------------------------------------------------------------------------- + /** + * 用量信息,输出 + */ + private FarmDocruninfo runinfo; + /** + * 当前知识分类,输出 + */ + private List currenttypes; + /** + * 作者信息,输出 + */ + private User user; + /** + * 内容图,输出 + */ + private String imgUrl; + /** + * 照片,输出 + */ + private String photoUrl; + + /** + * 分类读权限 + */ + private List typeReadPops; + /** + * 分类写权限 + */ + private List typeWritePops; + /** + * 分类审核权限 + */ + private List typeAuditPops; + + /** + * 审核信息 + */ + private DocAudit audit; + + // 待审版本 + private FarmDoctext auditTemp; + + + public FarmDoctext getAuditTemp() { + return auditTemp; + } + + public void setAuditTemp(FarmDoctext auditTemp) { + this.auditTemp = auditTemp; + } + + public DocAudit getAudit() { + return audit; + } + + public void setAudit(DocAudit audit) { + this.audit = audit; + } + + public List getTypeReadPops() { + return typeReadPops; + } + + public void setTypeReadPops(List typeReadPops) { + this.typeReadPops = typeReadPops; + } + + public List getTypeWritePops() { + return typeWritePops; + } + + public void setTypeWritePops(List typeWritePops) { + this.typeWritePops = typeWritePops; + } + + public List getTypeAuditPops() { + return typeAuditPops; + } + + public void setTypeAuditPops(List typeAuditPops) { + this.typeAuditPops = typeAuditPops; + } + + public String getPhotoUrl() { + return photoUrl; + } + + public void setPhotoUrl(String photoUrl) { + this.photoUrl = photoUrl; + } + + public Doc getDoc() { + return doc; + } + + public void setDoc(Doc doc) { + this.doc = doc; + } + + public FarmDoctext getTexts() { + return texts; + } + + public void setTexts(FarmDoctext texts) { + this.texts = texts; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public List getFiles() { + if (files == null) { + return new ArrayList(); + } + return files; + } + + public void setFiles(List files) { + this.files = files; + } + + /** + * 向文档添加附件的时候使用,该方法中的id会被封装到FarmDocfile对象中,单该对象其他属性都为null + * + * @param fileid + */ + public void addFile(FarmDocfile file) { + if (this.files == null) { + this.files = new ArrayList(); + } + files.add(file); + } + + public FarmDoctype getType() { + return type; + } + + public void setType(FarmDoctype type) { + this.type = type; + } + + public FarmDocruninfo getRuninfo() { + return runinfo; + } + + public void setRuninfo(FarmDocruninfo runinfo) { + this.runinfo = runinfo; + } + + public List getCurrenttypes() { + return currenttypes; + } + + public void setCurrenttypes(List currenttypes) { + this.currenttypes = currenttypes; + } + + public GroupEntire getGroup() { + return group; + } + + public void setGroup(GroupEntire group) { + this.group = group; + } + + public String getImgUrl() { + return imgUrl; + } + + public void setImgUrl(String imgUrl) { + this.imgUrl = imgUrl; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public void setTexts(String text, LoginUser user) { + FarmDoctext ntexts = new FarmDoctext(); + ntexts.setCtime(TimeTool.getTimeDate14()); + ntexts.setCuser(user.getId()); + ntexts.setCusername(user.getName()); + ntexts.setEtime(TimeTool.getTimeDate14()); + ntexts.setEuser(user.getId()); + ntexts.setEusername(user.getName()); + ntexts.setPstate("1"); + ntexts.setText1(text); + this.texts = ntexts; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/GroupBrief.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/GroupBrief.java new file mode 100644 index 0000000..0b39a02 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/GroupBrief.java @@ -0,0 +1,168 @@ +package com.farm.doc.domain.ex; + +public class GroupBrief { + private String id; + private String joincheck; + private String homedocid; + private Integer usernum; + private String groupimg; + private String grouptag; + private String groupnote; + private String groupname; + private String pcontent; + private String pstate; + private String euser; + private String eusername; + private String cuser; + private String cusername; + private String etime; + private String ctime; + private String imgurl; + private String userjoin; + + public String getImgurl() { + return imgurl; + } + + public void setImgurl(String imgurl) { + this.imgurl = imgurl; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getJoincheck() { + return joincheck; + } + + public void setJoincheck(String joincheck) { + this.joincheck = joincheck; + } + + public String getHomedocid() { + return homedocid; + } + + public void setHomedocid(String homedocid) { + this.homedocid = homedocid; + } + + public Integer getUsernum() { + return usernum; + } + + public void setUsernum(Integer usernum) { + this.usernum = usernum; + } + + public String getGroupimg() { + return groupimg; + } + + public void setGroupimg(String groupimg) { + this.groupimg = groupimg; + } + + public String getGrouptag() { + return grouptag; + } + + public void setGrouptag(String grouptag) { + this.grouptag = grouptag; + } + + public String getGroupnote() { + return groupnote; + } + + public void setGroupnote(String groupnote) { + this.groupnote = groupnote; + } + + public String getGroupname() { + return groupname; + } + + public void setGroupname(String groupname) { + this.groupname = groupname; + } + + public String getPcontent() { + return pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getPstate() { + return pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getEuser() { + return euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getEusername() { + return eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getCuser() { + return cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getCusername() { + return cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getEtime() { + return etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCtime() { + return ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public String getUserjoin() { + return userjoin; + } + + public void setUserjoin(String userjoin) { + this.userjoin = userjoin; + } + + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/GroupEntire.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/GroupEntire.java new file mode 100644 index 0000000..0ef4a6c --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/GroupEntire.java @@ -0,0 +1,188 @@ +package com.farm.doc.domain.ex; + +import java.util.List; + +import com.farm.authority.domain.User; + +public class GroupEntire { + private String id; + private String joincheck; + private String homedocid; + private Integer usernum; + private String groupimg; + private String grouptag; + private String groupnote; + private String groupname; + private String pcontent; + private String pstate; + private String euser; + private String eusername; + private String cuser; + private String cusername; + private String etime; + private String ctime; + private String imgurl; + private List tags; + private List users; + private List admins; + public String getImgurl() { + return imgurl; + } + + public void setImgurl(String imgurl) { + this.imgurl = imgurl; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getJoincheck() { + return joincheck; + } + + public void setJoincheck(String joincheck) { + this.joincheck = joincheck; + } + + public String getHomedocid() { + return homedocid; + } + + public void setHomedocid(String homedocid) { + this.homedocid = homedocid; + } + + public Integer getUsernum() { + return usernum; + } + + public void setUsernum(Integer usernum) { + this.usernum = usernum; + } + + public String getGroupimg() { + return groupimg; + } + + public void setGroupimg(String groupimg) { + this.groupimg = groupimg; + } + + public String getGrouptag() { + return grouptag; + } + + public void setGrouptag(String grouptag) { + this.grouptag = grouptag; + } + + public String getGroupnote() { + return groupnote; + } + + public void setGroupnote(String groupnote) { + this.groupnote = groupnote; + } + + public String getGroupname() { + return groupname; + } + + public void setGroupname(String groupname) { + this.groupname = groupname; + } + + public String getPcontent() { + return pcontent; + } + + public void setPcontent(String pcontent) { + this.pcontent = pcontent; + } + + public String getPstate() { + return pstate; + } + + public void setPstate(String pstate) { + this.pstate = pstate; + } + + public String getEuser() { + return euser; + } + + public void setEuser(String euser) { + this.euser = euser; + } + + public String getEusername() { + return eusername; + } + + public void setEusername(String eusername) { + this.eusername = eusername; + } + + public String getCuser() { + return cuser; + } + + public void setCuser(String cuser) { + this.cuser = cuser; + } + + public String getCusername() { + return cusername; + } + + public void setCusername(String cusername) { + this.cusername = cusername; + } + + public String getEtime() { + return etime; + } + + public void setEtime(String etime) { + this.etime = etime; + } + + public String getCtime() { + return ctime; + } + + public void setCtime(String ctime) { + this.ctime = ctime; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } + + public List getAdmins() { + return admins; + } + + public void setAdmins(List admins) { + this.admins = admins; + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/TypeBrief.java b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/TypeBrief.java new file mode 100644 index 0000000..c06ef41 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/domain/ex/TypeBrief.java @@ -0,0 +1,77 @@ +package com.farm.doc.domain.ex; + +public class TypeBrief { + // NAME,ID,PARENTID,NUM + private String name; + private String id; + private String parentid; + private int num; + private String type; + private String readpop; + private String writepop; + private String auditpop; + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getReadpop() { + return readpop; + } + + public void setReadpop(String readpop) { + this.readpop = readpop; + } + + public String getWritepop() { + return writepop; + } + + public void setWritepop(String writepop) { + this.writepop = writepop; + } + + public String getAuditpop() { + return auditpop; + } + + public void setAuditpop(String auditpop) { + this.auditpop = auditpop; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getParentid() { + return parentid; + } + + public void setParentid(String parentid) { + this.parentid = parentid; + } + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoDeleteException.java b/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoDeleteException.java new file mode 100644 index 0000000..fdce161 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoDeleteException.java @@ -0,0 +1,25 @@ +package com.farm.doc.exception; + +import com.farm.parameter.FarmParameterService; + +/** + * 没有删除权限异常 + * + * @author Administrator + * + */ +public class CanNoDeleteException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + + public CanNoDeleteException(String message) { + super(message); + } + + public CanNoDeleteException() { + super(FarmParameterService.getInstance().getParameter( + "title.com.farm.doc.exception.nowdel")); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoReadException.java b/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoReadException.java new file mode 100644 index 0000000..11bd4a6 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoReadException.java @@ -0,0 +1,26 @@ +package com.farm.doc.exception; + +import com.farm.parameter.FarmParameterService; + +/** + * 没有读取权限异常 + * + * @author Administrator + * + */ +public class CanNoReadException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public CanNoReadException(String message) { + super(message); + } + + public CanNoReadException() { + super(FarmParameterService.getInstance().getParameter( + "title.com.farm.doc.exception.noread")); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoWriteException.java b/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoWriteException.java new file mode 100644 index 0000000..f77085b --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/exception/CanNoWriteException.java @@ -0,0 +1,25 @@ +package com.farm.doc.exception; + +import com.farm.parameter.FarmParameterService; + +/** + * 没有修改权限异常 + * + * @author Administrator + * + */ +public class CanNoWriteException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + + public CanNoWriteException(String message) { + super(message); + } + + public CanNoWriteException() { + super(FarmParameterService.getInstance().getParameter( + "title.com.farm.doc.exception.nowrite")); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/exception/DocNoExistException.java b/src/wcp-doc/src/main/java/com/farm/doc/exception/DocNoExistException.java new file mode 100644 index 0000000..cddeb94 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/exception/DocNoExistException.java @@ -0,0 +1,25 @@ +package com.farm.doc.exception; + +import com.farm.parameter.FarmParameterService; + +/** + * 知识没有存在异常 + * + * @author Administrator + * + */ +public class DocNoExistException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + + public DocNoExistException(String message) { + super(message); + } + + public DocNoExistException() { + super(FarmParameterService.getInstance().getParameter( + "title.com.farm.doc.exception.docnoexist")); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/exception/NoGroupAuthForLicenceException.java b/src/wcp-doc/src/main/java/com/farm/doc/exception/NoGroupAuthForLicenceException.java new file mode 100644 index 0000000..a5d70f6 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/exception/NoGroupAuthForLicenceException.java @@ -0,0 +1,25 @@ +package com.farm.doc.exception; + +import com.farm.parameter.FarmParameterService; + +/** + * 没有删除权限异常 + * + * @author Administrator + * + */ +public class NoGroupAuthForLicenceException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + + public NoGroupAuthForLicenceException(String message) { + super(message); + } + + public NoGroupAuthForLicenceException() { + super(FarmParameterService.getInstance().getParameter( + "title.com.farm.doc.exception.licence.error")); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/quartz/task/RecountDocHotnumTask.java b/src/wcp-doc/src/main/java/com/farm/doc/quartz/task/RecountDocHotnumTask.java new file mode 100644 index 0000000..833415b --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/quartz/task/RecountDocHotnumTask.java @@ -0,0 +1,55 @@ +package com.farm.doc.quartz.task; + +import java.sql.SQLException; +import java.util.Map; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.server.FarmDocRunInfoInter; +import com.farm.util.spring.BeanFactory; + +/** + * 计算文档热度的定时器 + * + * @author Administrator + * + */ +public class RecountDocHotnumTask implements Job { + @Override + public void execute(JobExecutionContext arg0) throws JobExecutionException { + FarmDocRunInfoInter docRunInfoIMP = (FarmDocRunInfoInter) BeanFactory + .getBean("farmDocRunInfoImpl"); + DataResult result; + DataQuery query; + query = DataQuery.getInstance("1", "id,title", "farm_doc"); + query.setCurrentPage(1); + query.addRule(new DBRule("STATE", "1", "=")); + query.addRule(new DBRule("READPOP", "1", "=")); + int i = 1; + int docnum = 0; + while (true) { + try { + query.setPagesize(100); + query.setCurrentPage(i++); + result = query.search(); + if (result.getResultList().size() <= 0) { + break; + } + for (Map node : result.getResultList()) { + String docid = node.get("ID").toString(); + docRunInfoIMP.reCountDocHotNum(docid); + docnum++; + } + } catch (SQLException e1) { + e1.printStackTrace(); + break; + } + } + System.out.println("对文档(" + docnum + "条数据)计算热度"); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocIndexInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocIndexInter.java new file mode 100644 index 0000000..b926733 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocIndexInter.java @@ -0,0 +1,74 @@ +package com.farm.doc.server; + +import java.util.List; + +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.ex.DocBrief; +import com.farm.doc.domain.ex.DocEntire; + +/** + * 文档全文检索服务 + * + * @author 王东 + * @version 20140902 + */ +public interface FarmDocIndexInter { + + /** + * 查询相关知识 + * + * @param docid + * @param num + * @return + */ + List getRelationDocs(String docid, int num); + + /** + * 全文检索 + * + * @param word + * @param pagenum + * @return + */ + DataResult search(String word, String userid, Integer pagenum) throws Exception; + + /** + * 删除文档索引 + * + * @param doc + */ + public void delLuceneIndex(DocEntire doc); + /** + * 删除文档索引,用指定的id,doc是用来区分权限的 + * + * @param doc + */ + public void delLuceneIndex(DocEntire doc,String indexId); + /** + * 删除文档索引,在分类和小组下 + * + * @param doc + */ + public void delLuceneIndex(String docid, List typeIdList, List groupIdList); + + /** + * 添加文档索引 + * + * @param entity + */ + public void addLuceneIndex(DocEntire entity); + + /** + * 添加附件索引 + * + * @param entity + */ + public void addLuceneIndex(String fileid, String name, String text, DocEntire entity); + + /** + * 重做文档索引 + * + * @param entity + */ + public void reLuceneIndex(DocEntire olddoc, DocEntire newdoc); +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocManagerInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocManagerInter.java new file mode 100644 index 0000000..91da8d8 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocManagerInter.java @@ -0,0 +1,168 @@ +package com.farm.doc.server; + +import java.util.List; + +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDoctext; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.doc.exception.CanNoDeleteException; +import com.farm.doc.exception.CanNoReadException; +import com.farm.doc.exception.CanNoWriteException; +import com.farm.doc.exception.DocNoExistException; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DataQuery; + +/** + * 文档管理 + * + * @author MAC_wd + * + */ +public interface FarmDocManagerInter { + + /** + * 修改文档(不做权限控制) + * + * @param entity + * 标题、发布时间、内容类型是必填 texts中的TEXT1中存放超文本内容 + * @param editNote + * 修改时的注释 + * @param user + * 操作用户 + * @return + */ + public DocEntire editDoc(DocEntire entity, String editNote, LoginUser user); + + /** + * 带权限的修改实体 + * + * @param entity + * 标题、发布时间、内容类型是必填 texts中的TEXT1中存放超文本内容 + * @param editNote + * 修改备注(记录为啥修改) + * @param user + * @return + * @throws CanNoWriteException + */ + public DocEntire editDocByUser(DocEntire entity, String editNote, LoginUser user) throws CanNoWriteException; + + /** + * 删除文档(带权限) + * + * @param entity + */ + public DocEntire deleteDoc(String entity, LoginUser user) throws CanNoDeleteException; + + /** + * 删除文档(不带权限删除) + * + * @param entity + */ + public DocEntire deleteDocNoPop(String entity, LoginUser user) throws CanNoDeleteException; + + /** + * 创建文档 + * + * @param entity + * 标题、发布时间、内容类型是必填 texts中的TEXT1中存放超文本内容 + * @param currentUser + * @return + */ + public DocEntire createDoc(DocEntire entity, LoginUser currentUser); + + + /** + * 知识基本查询 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createSimpleDocQuery(DataQuery query); + + /** + * 获取文档数据 判断权限 + * + * @param id + * @param user + * 阅读用户 + * @return + */ + public DocEntire getDoc(String docid, LoginUser user) throws CanNoReadException, DocNoExistException; + + /** + * 获取文档数据 + * + * @param id + * @return + */ + public Doc getDocOnlyBean(String id); + + /** + * 获取文档数据(不判断权限) + * + * @param id + * @return + */ + @Deprecated + public DocEntire getDoc(String id); + + /** + * 创建一个基本查询用来查询当前分类实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createSimpleTypeQuery(DataQuery query); + + /** + * 更新文档的分类(唯一分类)将会清空doc的其它分类 + * + * @param docid + * @param typeId + */ + public void updateDocTypeOnlyOne(String docid, String typeId); + + /** + * 获得文档的版本信息 + * + * @param docId + * @return ID,ETIME,CUSERNAME,DOCID,PCONTENT + */ + public List getDocVersions(String docId); + + /** + * 获得文档版本信息 + * + * @param textId + * @param currentUser + * @return + */ + public DocEntire getDocVersion(String textId, LoginUser currentUser); + + /** + * 删除附件 void + */ + public void delImg(String imgid); + + + + /** + * 获得所有不带分类权限的知识 + * + * @param query + * @return + */ + public DataQuery createAllPubDocQuery(DataQuery query); + + /** + * 移动文档到指定分类 + * @param docIds 文档ID(多个ID用英文逗号分割) + * @param typeId 分类ID + * void + */ + public void move2Type(String docIds, String typeId); + + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocOperateRightInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocOperateRightInter.java new file mode 100644 index 0000000..397b6cd --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocOperateRightInter.java @@ -0,0 +1,154 @@ +package com.farm.doc.server; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDoctype; + +/** + * 文档权限操作接口 + * + * @author Administrator + * + */ +public interface FarmDocOperateRightInter { + /** + * 权限类型(阅读/编辑) + * + * @author 王东 + * + */ + public enum POP_TYPE { + /** + * 1公开 + */ + PUB("1"), /** + * 0本人 + */ + PRI("0"), /** + * 2小组 + */ + DOCGROUP("2"), /** + * 3禁止编辑 + */ + NONE("3"); + private String value; + + public String getValue() { + return value; + } + + /** + * 获得枚举对象 + * + * @param val + * @return + */ + public static POP_TYPE getEnum(String val) { + if (val.equals("1")) { + return POP_TYPE.PUB; + } + if (val.equals("3")) { + return POP_TYPE.NONE; + } + if (val.equals("2")) { + return POP_TYPE.DOCGROUP; + } + return POP_TYPE.PRI; + } + + public void setValue(String value) { + this.value = value; + } + + POP_TYPE(String value) { + this.value = value; + } + } + + /** + * 是否允许读取文档 + * + * @param user + * @param doc + * 传入docBean即可 + * @return + */ + public boolean isRead(LoginUser user, Doc doc); + + /** + * 是否允许未登陆用户及所有人读取文档(如果报出doc分类的空指针异常则使用isAllUserRead(Doc doc,FarmDoctype + * type)) + * + * @param doc + * 传入docBean即可 + * @return + */ + public boolean isAllUserRead(Doc doc); + + /** + * 是否允许未登陆用户及所有人读取文档 + * + * @param doc + * @param type + * 如果传入type则直接使用该type判断分类权限 + * @return + */ + public boolean isAllUserRead(Doc doc, FarmDoctype type); + + /** + * 是否允许编辑文档 + * + * @param user + * @param doc + * 传入docBean即可 + * @return + */ + public boolean isWrite(LoginUser user, Doc doc); + + /** + * 是否允许删除文档 + * + * @param user + * @param doc + * 传入docBean即可 + * @return + */ + public boolean isDel(LoginUser user, Doc doc); + + /** + * 是否允许审核文档 + * + * @param user + * @param doc + * 传入docBean即可 + * @return + */ + public boolean isAudit(LoginUser user, Doc doc); + + /** + * 修改文档权限 + * + * @param docId + * @param pop_type_read + * @param pop_type_write + * @param currentUser + * @return + */ + public Doc editDocRight(String docId, POP_TYPE pop_type_read, POP_TYPE pop_type_write, LoginUser currentUser); + + /** + * 公开文档(将该文档开放阅读和编辑权限,同时如果是小组文档将删除小组所有权) + * + * @param id + * @param currentUser + */ + public void flyDoc(String docID, LoginUser currentUser); + + /** + * 公开文档(不做权限验证) + * + * @param id + * @param currentUser + */ + public void flyDoc(Doc doc); +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocRunInfoInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocRunInfoInter.java new file mode 100644 index 0000000..55f1764 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocRunInfoInter.java @@ -0,0 +1,261 @@ +package com.farm.doc.server; + +import java.util.List; +import java.util.Map; + +import com.farm.authority.domain.User; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDocruninfo; +import com.farm.doc.domain.ex.DocBrief; + +/** + * 文档用量接口 + * + * @author 王东 + * @version 20140902 + */ +public interface FarmDocRunInfoInter { + /** + * 用户访问知识 + * + * @param docId + */ + public void visitDoc(String docId, LoginUser user, String ip); + + /** + * 关注一片文章 + */ + public void enjoyDoc(String userId, String docId); + + /** + * 取消关注一片文章 + */ + public void unEnjoyDoc(String userId, String docId); + + /** + * 用户是否关注一篇文章 + * + * @return + */ + public boolean isEnjoyDoc(String userId, String docId); + /**获得文档的关注用户 + * @param docid + * @return + */ + public List getDocJoinUserIds(String docid); + /** + * 获得用户关注的文章 + * + * @return + */ + public DataQuery getUserEnjoyDoc(String userId); + + /** + * 重新计算文章热度 + * + * @param userId + * @param docId + */ + public void reCountDocHotNum(String docId); + + /** + * 给文档一个好评(登录用户)必须配合loadRunInfo使用 + * + * @param docId + * @param user + */ + public void praiseDoc(String docId, LoginUser user, String IP); + + /** + * 给文档一个好评(未登录用户)必须配合loadRunInfo使用 + * + * @param docId + * @param IP + */ + public void praiseDoc(String docId, String IP); + + /** + * 给文档一个差评(登录用户)必须配合loadRunInfo使用 + * + * @param docId + * @param user + */ + public void criticalDoc(String docId, LoginUser user, String IP); + + /** + * 给文档一个差评(未登录用户)必须配合loadRunInfo使用 + * + * @param docId + * @param IP + */ + public void criticalDoc(String docId, String IP); + + /** + * 更新和加载计算用量信息 + * + * @param docId + * @return + */ + public FarmDocruninfo loadRunInfo(String docId); + + /** + * 获得最热知识 + * + * @param num + * 返回多少条 + * @return + */ + public List getPubHotDoc(int num); + + /** + * 展示最新知识 + */ + public List getNewKnowList(int pagesize); + + /** + * 获得分类知识 + * + * @param typeid + * 分类id + * @param userid + * 用户id + * @param num + * 查询数量 + * @return + */ + public List getTypeDocs(String typeid, String userid, int num); + + /** + * 获得置顶知识 + * + * @param num + * @return + */ + public List getPubTopDoc(int num); + + /** + * 获得好评用户 + * + * @param num + * @return ID,NAME,SUMYES + */ + public DataResult getStatGoodUsers(int num); + + /** + * 获得好评小组 + * + * @param num + * @return + */ + public DataResult getStatGoodGroups(int num); + + /** + * 做多知识用户 + * + * @param num + * @return + */ + public DataResult getStatMostUsers(int num); + + /** + * 好评文档 + * + * @param num + * @return + */ + public DataResult getStatGoodDocs(int num); + + /** + * 差评文档 + * + * @param num + * @return + */ + public DataResult getStatBadDocs(int num); + + /** + * 整体用量(获得每天的知识总数、好评数、差评数) + * + * @return + * @throws Exception + */ + public Map getStatNumForDay() throws Exception; + + + /**库的统计总数,知识总数、总人数、好评数、差评数、分类数量 + * @return + * @throws Exception + */ + public Map getStatNum() throws Exception; + + + /** + * 用户知识统计 + * + * @param user + * @return + */ + public DataResult getStatUser(User user); + + /** + * 获得用户所有文档 + * + * @param userid + * @param domtype + * @param pagesize + * @param pagenum + * @return + */ + public DataResult userDocs(String userid, String domtype, int pagesize, int pagenum); + + /** + * 获得用户所有公开文档 + * + * @param userid + * @param domtype + * @param pagesize + * @param pagenum + * @return + */ + public DataResult userPubDocs(String userid, String domtype, int pagesize, int pagenum); + + /** + * 获得我历史审核 + * + * @param userid + * @param pagesize + * @param pagenum + * @return + */ + public DataResult getMyAuditedByUser(String userid, int pagesize, int pagenum); + + /** + * 获得我的未审核文档 + * + * @param userid + * @param pagesize + * @param pagenum + * @return + */ + public DataResult getMyAuditingByUser(String userid, int pagesize, int pagenum); + + /** + * 获得需要我审核的文档列表 + * + * @param user + * @param pagesize + * @param pagenum + * @return + */ + public DataResult getAuditDocByUser(String user, int pagesize, int pagenum); + + /** + * 创建一个用户发布排名查询 + * + * @param query + * @return DataQuery + */ + public DataQuery createReleaseRankingSimpleQuery(DataQuery query); +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocTypeInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocTypeInter.java new file mode 100644 index 0000000..d5001f2 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocTypeInter.java @@ -0,0 +1,154 @@ +package com.farm.doc.server; + +import java.util.List; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.domain.ex.TypeBrief; +import com.farm.doc.server.plus.domain.Doctypepop; + +/** + * 文档分类 + * + * @author 王东 + * @version 20140902 + */ +public interface FarmDocTypeInter { + + /** + * 新增分类 + * + * @param entity + */ + public FarmDoctype insertType(FarmDoctype entity, LoginUser user); + + /** + * 修改分类 + * + * @param entity + */ + public FarmDoctype editType(FarmDoctype entity, LoginUser user); + + /** + * 删除分类实体 + * + * @param entity + */ + public void deleteType(String entity, LoginUser user); + + /** + * 获得分类实体 + * + * @param id + * @return + */ + public FarmDoctype getType(String id); + + /** + * 获得一个分类的所有上层节点序列(包含该分类,有排序) + * + * @param typeid + * @return + */ + public List getTypeAllParent(String typeid); + + /** + * 获取知识分类详细信息(带分类下知识数量)(下级分类和下下级别分类) + * + * @param query + * @return + */ + public List getTypeInfos(LoginUser user, String parentId); + + /** + * 获得用户的分类下的知识 + * + * @return DOCID,title,DOCDESCRIBE,AUTHOR,PUBTIME,TAGKEY + * ,IMGID,VISITNUM,PRAISEYES,PRAISENO,HOTNUM,EVALUATE,ANSWERINGNUM, + * TYPENAME,DOMTYPE,TYPEID + */ + public DataResult getTypeDocs(LoginUser userid, String typeid, int pagesize, int currentPage); + + /** + * 查询分类的权限(检查该分类的所有上级节点,并获取权限信息) + * + * @param query + * @param type + * @param typeid + * @return + */ + public List getTypePops(String typeid); + + /** + * 获得分类所有子节点 + * + * @param typeid + * @return + */ + public List getAllSubNode(String typeid); + + /** + * 获取知识分类信息(带分类下知识数量) + * + * @param query + * @return + */ + public List getPubTypes(); + /** + * 获取所有知识分类 + * + * @param query + * @return + */ + public List getTypes(); + /** + * 获得用户所有(被授权阅读的受限分类的分类的ID)(阅读) ///////受限分类是相对于为分配权限的分类(为分配权限的分类,所有人均可访问) + * + * @param user + * @return + */ + public List getUserReadTypeIds(LoginUser user); + + /** + * 获得用户所有(需要其审核的)分类的ID列表 + * + * @param userid + * 用户id + * @return + */ + public List getUserAuditTypeIds(String userid); + + /** + * 获得分类的审核人ID列表 + * + * @param typeid + * @return + */ + public List getPopTypeAudtUserIds(String typeid); + + /** + * 获取知识分类信息(带分类下知识数量) + * + * @param user + * user可空 + * @return + */ + public List getPopTypesForReadDoc(LoginUser user); + + /** + * 获取知识分类信息(带分类下知识数量)用于创建知识时候的 + * + * @param user + * @return + */ + public List getTypesForWriteDoc(LoginUser user); + + /** + * 获得用户可以阅读的所有分类ID + * + * @return + */ + public List getTypesForUserRead(LoginUser user); + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocgroupManagerInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocgroupManagerInter.java new file mode 100644 index 0000000..ce4c011 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocgroupManagerInter.java @@ -0,0 +1,503 @@ +package com.farm.doc.server; + +import java.util.List; +import java.util.Map; + +import com.farm.authority.domain.User; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.doc.domain.FarmDocgroup; +import com.farm.doc.domain.FarmDocgroupUser; +import com.farm.doc.domain.ex.GroupBrief; +import com.farm.doc.domain.ex.GroupEntire; +import com.farm.doc.exception.NoGroupAuthForLicenceException; + +/** + * 工作小组 + * + * @author MAC_wd + * + */ +public interface FarmDocgroupManagerInter { + + /** + * 查询条件是否执行 + * + * @author wangdong + * + */ + public enum SearchType { + yes, no, none + } + + /** + * 修改工作小组实体(控制台修改) + * + * @param entity + */ + public FarmDocgroup editFarmDocgroupEntity(FarmDocgroup entity, LoginUser user); + + /** + * 删除工作小组实体 + * + * @param entity + */ + public void deleteFarmDocgroupEntity(String groupId, LoginUser user); + + /** + * 获得工作小组实体 + * + * @param id + * @return + */ + public FarmDocgroup getFarmDocgroupEntity(String id); + + /** + * 获得工作小组实体 + * + * @param groupid + * @return + */ + public GroupEntire getFarmDocgroup(String groupid); + + /** + * 修改工作小组成员实体(控制台修改) + * + * @param entity + */ + public FarmDocgroupUser editFarmDocgroupUserEntity(FarmDocgroupUser entity, LoginUser user); + + /** + * 删除工作小组成员实体 + * + * @param entity + */ + public void deleteFarmDocgroupUserEntity(String entity, LoginUser user); + + /** + * 获得工作小组成员实体 + * + * @param id + * @return + */ + public FarmDocgroupUser getFarmDocgroupUserEntity(String id); + + /** + * 创建一个基本查询用来查询当前工作小组成员实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createFarmDocgroupUserSimpleQuery(DataQuery query); + + /** + * 创建一个工作小组 + * + * @param groupname + * 小组名称 + * @param grouptag + * 小组tag + * @param groupimg + * 小组头像 + * @param joincheck + * 加入小组是否需要验证 + * @param groupnote + * 小组备注 + * @param currentUser + * 当前操作用户 + */ + public FarmDocgroup creatDocGroup(String groupname, String grouptag, String groupimg, boolean joincheck, + String groupnote, LoginUser currentUser) throws NoGroupAuthForLicenceException; + + /** + * 修改一个工作小组 + * + * @param id + * @param groupname + * @param grouptag + * @param groupimg + * @param b + * @param groupnote + * @param currentUser + * @return + */ + public FarmDocgroup editDocGroup(String id, String groupname, String grouptag, String groupimg, boolean joincheck, + String groupnote, LoginUser currentUser); + + /** + * 是否需要验证才能够加入小组 + * + * @param groupid + * @return + */ + public boolean isJoinCheck(String groupid); + + /** + * 用户申请加入小组(如果不需要验证则直接加入) + * + * @param groupId + * 小组ID + * @param joinUserId + * 成员ID + * @param note + * 申请备注 + * @param currentUser + * 当前操作人员 + */ + public FarmDocgroupUser applyGroup(String groupId, String joinUserId, String note, LoginUser currentUser); + + /** + * 小组邀请用户加入 + * + * @param groupId + * 小组ID + * @param joinUserId + * 成员ID + * @param isLead + * 是否管理员 + * @param isEdit + * 是否享有编辑权限 + * @param currentUser + * 当前操作人员 + */ + public void inviteGroup(String groupId, String joinUserId, boolean isLead, boolean isEdit, LoginUser currentUser); + + /** + * 判断用户是否加入到某个小组中 + * + * @param groupId + * 小组id + * @param userId + * 用户id + */ + public boolean isJoinGroupByUser(String groupId, String userId); + + /** + * 创建一个外连接小组用户的查询用来查询当前工作小组实体farm_docgroup a left join FARM_DOCGROUP_USER b + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createFarmDocgroupQueryJoinUser(DataQuery query); + + /** + * 创建一个基本查询用来查询当前工作小组实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createFarmDocgroupQuery(DataQuery query); + + /** + * 查询用户没有加入的小组 + * + * @param query + * 传入的查询条件封装 + * @param userid + * 用户id + * @return + */ + public DataQuery createFarmDocgroupQueryNuContainUser(DataQuery query, String userid); + + /** + * 获得用户的groupUser + * + * @param groupId + * @param currentUser + * @return + */ + public FarmDocgroupUser getFarmDocgroupUser(String groupId, String userId); + + /** + * 离开小组 + * + * @param groupID + * @param userId + */ + public void leaveGroup(String groupID, String userId); + + /** + * 获得小组所有的管理员信息 + * + * @param groupId + * 小组ID + * @return + */ + public List getAllAdministratorByGroup(String groupId); + + /** + * 获得小组所有状态下的成员信息(含state不为1的的) + * + * @param groupId + * 小组ID + * @return + */ + public List getAllUserByGroup(String groupId); + + /** + * 获得小组所有可用成员信息(只含有state为1的) + * + * @param groupId + * 小组ID + * @return + */ + public List getAllUserNoApplyByGroup(String groupId); + + /** + * 同意用户加入申请 + * + * @param groupUserId + */ + public void agreeJoinApply(String groupUserId, LoginUser currentUser); + + /** + * 拒绝用户加入申请 + * + * @param groupUserId + */ + public void refuseJoinApply(String groupUserId, LoginUser currentUser); + + /** + * 删除用户小组管理员权限 + * + * @param groupUserId + */ + public void wipeAdminFromGroup(String groupUserId, LoginUser currentUser); + + /** + * 将用户退出小组 + * + * @param groupUserId + */ + public void leaveGroup(String groupUserId, LoginUser currentUser); + + /** + * 去除小组编辑权限 + * + * @param groupUserId + */ + public void wipeEditorForGroup(String groupUserId, LoginUser currentUser); + + /** + * 设置小组编辑权限 + * + * @param groupUserId + */ + public void setEditorForGroup(String groupUserId, LoginUser currentUser); + + /** + * 设置为小组管理员 + * + * @param groupUserId + */ + public void setAdminForGroup(String groupUserId, LoginUser currentUser); + + /** + * 用户是否为小组管理员 + * + * @param userid + * 用户ID + * @param groupId + * 小组ID + */ + public boolean isAdminForGroup(String userid, String groupId); + + /** + * 在我的首页显示小组 + * + * @param id + */ + public void setGroupHomeShow(String groupId, String userId); + + /** + * 在我的首页隐藏小组 + * + * @param id + */ + public void setGroupHomeHide(String groupId, String userId); + + /** + * 在我的小组中为小组上移一个排序 + * + * @param id + */ + public void setGroupSortUp(String groupId, String userId); + + /** + * 获得用户所有的小组 + * + * @param userId + */ + public List getAllGroupUserByUser(String userId); + + /** + * 获得所有具有编辑权限的小组 + * + * @param userId + * @return + */ + public List> getEditorGroupByUser(String userId); + + /** + * 用户是否具有小组的编辑权限 + * + * @param docgroupid + * @param id + */ + public boolean isGroupEditor(String docgroupid, String userId); + + /** + * 获得小组最新文档查询对象 + * + * @param query + * @return + */ + public DataQuery getGroupNewDocQuery(DataQuery query, String groupId, LoginUser user); + + /** + * 获得小组最优质文档查询对象 + * + * @param query + * @return + */ + public DataQuery getGroupGoodDocQuery(DataQuery query, String groupId, LoginUser currentUser); + + /** + * 获得小组最优质文档查询对象 + * + * @param query + * @return + */ + public DataQuery getGroupHotDocQuery(DataQuery query, String groupId, LoginUser currentUser); + + /** + * 获得小组文档的数量 + * + * @param groupId + * 小组ID + * @return + */ + public int getGroupDocNum(String groupId); + + /** + * 修改部分用户的小组权限(状态,是否小组管理员,是否有修改权限,是否首页显示) + * + * @param entity + * @param currentUser + * @return + */ + public FarmDocgroupUser editMinFarmDocgroupUserEntity(FarmDocgroupUser entity, LoginUser currentUser); + + /** + * 创建一个我的小组文档的查询对象 + * + * @param query + * + * @param query + * @param userid + * @return (ID,EVALUATE,DOMTYPE,ETIME,SHOWHOME,GROUPNAME,GROUPID,TITLE, + * DOCDESCRIBE + * ,AUTHOR,PUBTIME,TAGKEY,IMGID,VISITNUM,PRAISEYES,PRAISENO,HOTNUM, + * TYPENAME,GROUPIMG) + */ + public DataQuery createUserGroupDocQuery(DataQuery query, String userid); + + /** + * 修改小组加入时是否验证 + * + * @param isJoinCheck + * 加入时是否验证 + * @param currentUser + * 当前用户 + * @return + */ + public FarmDocgroup editDocgroupJoinCheck(boolean isJoinCheck, String groupId, LoginUser currentUser); + + /** + * 获得小组最差评文档查询对象 + * + * @param query + * @return + */ + public DataQuery getGroupBadDocQuery(DataQuery query, String groupId, LoginUser currentUser); + + /** + * 获得小组最新知识 + * + * @param userid + * 用户id + * @param gourpid + * 小组id + * @param pagesize + * @param pagenum + * @return + */ + public DataResult getNewGroupDoc(LoginUser user, String gourpid, int pagesize, Integer pagenum); + + /** + * 获得最热门小组 + * + * @param num + * 获得数量 + * @return + */ + public List getHotDocGroups(int num); + + public List getHotDocGroups(int num, LoginUser currentUser); + + /** + * 获得小组用户 + * + * @param groupid + * 小组id + * @param isApply + * 是否申请 + * @param isAdmin + * 是否管理员 + * @param isEditor + * 是否编辑权限 + * @return + */ + public DataResult getGroupUser(String groupid, SearchType isApply, SearchType isAdmin, SearchType isEditor, + int page, int pagesize); + + /** + * 用户是否正在小组审核中 + * + * @param groupId + * @param userid + * @return + */ + public boolean isAuditing(String groupId, String userid); + + /** + * 获得用户小组 + * + * @param userid + * @param pagesize + * @param pagenum + * @return + */ + public DataResult getGroupsByUser(String userid, int pagesize, Integer pagenum); + + /** + * 获得小组 + * + * @param pagesize + * @param pagenum + * @return + */ + public DataResult getGroups(int pagesize, Integer pagenum); + + /** + * 获得所有小组 + * + * @return + */ + public List getAllGroup(); + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocmessageManagerInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocmessageManagerInter.java new file mode 100644 index 0000000..551abb3 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmDocmessageManagerInter.java @@ -0,0 +1,168 @@ +package com.farm.doc.server; + +import com.farm.doc.domain.FarmDocmessage; + +import java.util.List; +import java.util.Map; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; + +/** + * 留言板 + * + * @author MAC_wd + * + */ +public interface FarmDocmessageManagerInter { + /** + * 发送消息 + * + * @param readUserId + * 收件人 + * @param text + * 内容 + * @param title + * 主题 + * @param note + * 备注 + * @param appId + * 应用id + * @param sendUser + * 发送人 + * @return + */ + public FarmDocmessage sendMessage(String readUserId, String text, String title, String note, String appId, + LoginUser sendUser); + + /** + * 发送消息 + * + * @param readUserId + * 收件人 + * @param text + * 内容 + * @param title + * 主题 + * @param note + * 备注 + * @param sendUser + * 发送人 + * @return + */ + public FarmDocmessage sendMessage(String readUserId, String text, String title, String note, LoginUser sendUser); + + /** + * 回复消息 + * + * @param entity + */ + public FarmDocmessage reSendMessage(String messageId, String text, LoginUser sendUser); + + /** + * 删除消息 + * + * @param entity + */ + public void deleteMessage(String messageId, LoginUser user); + + /** + * 阅读消息 + * + * @param id + * @return + */ + public FarmDocmessage readMessage(String messageId); + + /** + * 获得没有阅读的消息数量 + * + * @param user + * @return + */ + public int getNoReadMessageNum(LoginUser user); + + /** + * 查询消息列表 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createMessageQuery(DataQuery query); + + /** + * 获得消息 + * + * @param id + * @return + */ + public FarmDocmessage getMessage(String messageId); + + /** + * 发表一篇业务留言 + * + * @param content + * 内容(被显示的) + * @param title + * 主题 + * @param mark + * 留言的类型标签 + * @param appid + * 业务主键(按照该键可以找到业务得留言) + * @param sendUser + * 发表人 + * @return + */ + public FarmDocmessage sendAnswering(String content, String title, String mark, String appid, LoginUser sendUser); + + /** + * 获得文档所有评论 + * + * @param docid + * 文档id + * @param num + * 页数 + * @param pagesize + * 每页多少条 + * @return + */ + public DataResult getMessages(String docid, int num, int pagesize); + + /** + * 赞同 + * @param id + * @return + * FarmDocmessage + */ + public FarmDocmessage approveOf(String id, LoginUser loginUser); + + /** + * 反对 + * @param id + * @return + * FarmDocmessage + */ + public FarmDocmessage oppose(String id, LoginUser loginUser); + + /** + * 回复 评论 + * @param content 内容 + * @param appid 知识id或其他业务id + * @param messageId 父消息id(被回复id) + * @param loginUser 当前用户 + */ + public void reply(String content,String appid,String messageId, LoginUser loginUser); + + /** + * + * v1.0 zhanghc 2016年7月14日上午10:19:59 + * @param docid + * @param docMessageId + * @return + * Object + */ + public List> getReplys(String docid, String docMessageId); + +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmFileIndexManagerInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmFileIndexManagerInter.java new file mode 100644 index 0000000..b531c5c --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmFileIndexManagerInter.java @@ -0,0 +1,56 @@ +package com.farm.doc.server; + +import java.util.List; + +import com.farm.doc.domain.FarmDocfile; +import com.farm.doc.domain.ex.DocEntire; + +public interface FarmFileIndexManagerInter { + + /** + * 添加一个附件索引 + * + * @param fileid + * @param docid + * @param text + */ + public void addFileLuceneIndex(String fileid, DocEntire doc, String text); + + /** + * 删除一个附件索引 + * + * @param fileid + * @param doc + */ + public void delFileLucenneIndex(String fileid, DocEntire doc); + + /** + * 修改知识分类后处理(主要为了处理移动分类) + * + * @param oldDoce + * 旧的知识 + * @param newdoc + */ + public void handleFileLucenneIndexBymoveType(DocEntire oldDoce, DocEntire newdoc); + + /** + * 删除一批附件索引,判断新的和原来的附件列表少了哪些,少的附件将被删除索引 + * + * @param originalfiles + * 原来的 + * @param newfiles + * 新的 + * @param doc + * 附件属于的知识 + */ + public void delFileLucenneIndexs(List originalfiles, List newfiles, DocEntire doc); + + /** + * 删除一个附件索引,在所有索引文件中 + * + * @param fileid + * 文件id + */ + public void delFileLucenneIndex(String fileid); + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmFileManagerInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmFileManagerInter.java new file mode 100644 index 0000000..bb631c6 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmFileManagerInter.java @@ -0,0 +1,180 @@ +package com.farm.doc.server; + +import java.io.File; +import java.io.InputStream; +import java.util.List; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.doc.domain.FarmDocfile; + +public interface FarmFileManagerInter { + /** + * 附件类型 + * + * @author 王东 + * + */ + public enum FILE_TYPE { + HTML_INNER_IMG("1"), RESOURCE_FILE("2"), RESOURCE_ZIP("3"), OHTER("0"), WEB_FILE("4"); + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + FILE_TYPE(String value) { + this.value = value; + } + } + + /** + * 保存一个附件到系统中 + * + * @param file + * @param type + * @param title + * @return 附件ID + */ + public String saveFile(File file, FILE_TYPE type, String title, LoginUser user); + + /** + * 保存一个附件到系统中 + * + * @param inStream + * 文件流 + * @param filename + * 文件名称 + * @param title + * 文件title + * @param type + * 文件类型 + * @param user + * 当前用户 + * @return + */ + public String saveFile(InputStream inStream, String filename, String title, FILE_TYPE type, LoginUser user); + + /** + * 由文件id获得下载链接 + * + * @param fileid + * 文件id + * @return + */ + public String getFileURL(String fileid); + + /** + * 由文件id获得文件对象 + * + * @param fileid + * @return + */ + public FarmDocfile getFile(String fileid); + + /** + * 获得一个默认图片 + * + * @param file + * @return + */ + public File getNoneImg( ); + + /** + * 将文件状态改为提交状态,否则为临时状态 + * + * @param fileId + */ + public void submitFile(String fileId); + + /** + * 将文件设置为临时状态 + * + * @param fileId + */ + public void cancelFile(String fileId); + + /** + * 删除一个文件 + * + * @param fileId + */ + public void delFile(String fileId, LoginUser user); + + /** + * 创建并使用一个新的文件(并附带一个已经存在的File对象) + * + * @param exname + * 扩展名 + * @param content + * 备注 + * @param user + * @return + */ + public FarmDocfile openFile(String exname, String content, LoginUser user); + + /** + * 为文档添加一个附件 + * + * @param docid + * @param fileId + * @param user + */ + public void addFileForDoc(String docid, String fileId, LoginUser user); + + /** + * 为文档删除一个附件 + * + * @param docid + * @param fileId + * @param user + */ + public void delFileForDoc(String docid, String fileId, LoginUser user); + /** + * 删除一个文档的所有附件 + * + * @param docid + * @param fileId + * @param user + */ + public void delFileForDoc(String docid, LoginUser user); + /** + * 获得文档的所有附件 + * + * @param docid + */ + public List getAllFileForDoc(String docid); + + /** + * 获得文档的某类型的所有附件 + * + * @param docid + * @param exname + * 扩展名如.doc + * @return + */ + public List getAllTypeFileForDoc(String docid, String exname); + + /** + * 文档是否包含一个附件 + * + * @param id + * @param zipfileId + * @return + */ + public boolean containFileByDoc(String docid, String fileId); + + /** + * 删除一个文档的所有某类型附件 + * + * @param docid + * 文档id + * @param exname + * 扩展名如.doc + * @param LoginUser + */ + public void delAllFileForDoc(String docid, String exname, LoginUser LoginUser); +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/FarmtopServiceInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmtopServiceInter.java new file mode 100644 index 0000000..097d592 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/FarmtopServiceInter.java @@ -0,0 +1,62 @@ +package com.farm.doc.server; + +import com.farm.doc.domain.Farmtop; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.auth.domain.LoginUser; + +/* * + *功能:置顶文档服务层接口 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +public interface FarmtopServiceInter { + /** + * 新增实体管理实体 + * + * @param entity + */ + public Farmtop insertFarmtopEntity(Farmtop entity, LoginUser user); + + /** + * 修改实体管理实体 + * + * @param entity + */ + public Farmtop editFarmtopEntity(Farmtop entity, LoginUser user); + + /** + * 删除实体管理实体 + * + * @param entity + */ + public void deleteFarmtopEntity(String id, LoginUser user); + + /** + * 获得实体管理实体 + * + * @param id + * @return + */ + public Farmtop getFarmtopEntity(String id); + + /** + * 创建一个基本查询用来查询当前实体管理实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createFarmtopSimpleQuery(DataQuery query); + + /** + * 置顶文档选择文档列表数据 + * v1.0 zhanghc 2015年9月5日下午2:03:20 + * @param query + * @return DataQuery + */ + public DataQuery docTopChooseDocList(DataQuery query); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/UsermessageServiceInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/UsermessageServiceInter.java new file mode 100644 index 0000000..de60cd5 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/UsermessageServiceInter.java @@ -0,0 +1,118 @@ +package com.farm.doc.server; + +import com.farm.doc.domain.Usermessage; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; + +import java.util.List; + +import com.farm.core.auth.domain.LoginUser; + +/* * + *功能:用户消息服务层接口 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +public interface UsermessageServiceInter { + /** + * 新增实体管理实体 + * + * @param entity + */ + public Usermessage insertUsermessageEntity(Usermessage entity, + LoginUser user); + + /** + * 修改实体管理实体 + * + * @param entity + */ + public Usermessage editUsermessageEntity(Usermessage entity, LoginUser user); + + /** + * 删除实体管理实体 + * + * @param entity + */ + public void deleteUsermessageEntity(String id, LoginUser user); + + /** + * 获得实体管理实体 + * + * @param id + * @return + */ + public Usermessage getUsermessageEntity(String id); + + /** + * 创建一个基本查询用来查询当前实体管理实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createUsermessageSimpleQuery(DataQuery query); + + /** + * 设置为阅读 + * @param id + * void + */ + public void setRead(String id); + + /** + * 发送消息 + * + * @param readUserId 收件人 + * @param text 内容 + * @param title 主题 + * @param note 备注 + * @param sendUser 发送人 + * @return + */ + public void sendMessage(String readUserId, String text, String title, + String note, LoginUser sendUser); + /** + * 发送消息 + * + * @param readUserId 收件人 + * @param text 内容 + * @param title 主题 + * @param note 备注 + * @param sendUser 发送人 + * @return + */ + public void sendMessage(String readUserId, String text, String title,LoginUser sendUser); + /** + * 发送消息 + * + * @param readUserId 收件人 + * @param text 内容 + * @param title 主题 + * @param note 备注 + * @param sendUser 发送人 + * @return + */ + public void sendMessage(String readUserId, String text, String title); + + /**发送消息给一些人 + * @param userids + * @param text + * @param title + */ + public void sendMessage(List userids, String text, String title); + + /** + * 获取我的消息 + * @param userId 用户ID + * @param pageSize 每页多少条 + * @param currPage 当前第几页 + * @return + * DataResult + */ + public DataResult getMyMessageByUser(String userId, int pageSize, Integer currPage); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/WeburlServiceInter.java b/src/wcp-doc/src/main/java/com/farm/doc/server/WeburlServiceInter.java new file mode 100644 index 0000000..9433897 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/WeburlServiceInter.java @@ -0,0 +1,72 @@ +package com.farm.doc.server; + +import java.util.List; +import java.util.Map; + +import com.farm.doc.domain.Weburl; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.auth.domain.LoginUser; + +/* * + *功能:推荐服务服务层接口 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +public interface WeburlServiceInter { + /** + * 新增实体管理实体 + * + * @param entity + */ + public Weburl insertWeburlEntity(Weburl entity, LoginUser user); + + /** + * 修改实体管理实体 + * + * @param entity + */ + public Weburl editWeburlEntity(Weburl entity, LoginUser user); + + /** + * 删除实体管理实体 + * + * @param entity + */ + public void deleteWeburlEntity(String id, LoginUser user); + + /** + * 获得实体管理实体 + * + * @param id + * @return + */ + public Weburl getWeburlEntity(String id); + + /** + * 创建一个基本查询用来查询当前实体管理实体 + * + * @param query + * 传入的查询条件封装 + * @return + */ + public DataQuery createWeburlSimpleQuery(DataQuery query); + + /** + * 获取列表集合 + * @return + * List + */ + public List> getList(); + + /** + * 删除附件 + * v1.0 zhanghc 2015年11月12日下午8:34:32 + * @param imgid + * void + */ + public void delImg(String imgid); +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/commons/DocMessageCache.java b/src/wcp-doc/src/main/java/com/farm/doc/server/commons/DocMessageCache.java new file mode 100644 index 0000000..772d303 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/commons/DocMessageCache.java @@ -0,0 +1,35 @@ +package com.farm.doc.server.commons; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * 人员开门队列 + * v1.0 zhanghc 2015年9月23日上午11:30:38 + */ +public class DocMessageCache { + + private Queue queue = new LinkedList<>(); + private static final int maxNum = 10000; + private static final DocMessageCache cache = new DocMessageCache(); + + + public static DocMessageCache getInstance(){ + return cache; + } + + public synchronized boolean add(String userId, String docId, String docMessageId) { + String key = userId+docId+docMessageId; + + if(queue.contains(key)){ + return false; + } + + if(queue.size() >= maxNum){ + queue.poll(); + } + + queue.add(key); + return true; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/commons/DocumentConfig.java b/src/wcp-doc/src/main/java/com/farm/doc/server/commons/DocumentConfig.java new file mode 100644 index 0000000..684f676 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/commons/DocumentConfig.java @@ -0,0 +1,38 @@ +package com.farm.doc.server.commons; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.apache.log4j.Logger; + +/** + * 应用参数工具类,获得config中定义的参数 + * + * @author wangdong + * + */ +public class DocumentConfig { + private static final String BUNDLE_NAME = "document"; //$NON-NLS-1$ + private static final Logger log = Logger.getLogger(DocumentConfig.class); + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private DocumentConfig() { + } + + /**从properties文件中获得配置值 + * @param key 配置文件的key + * @return + */ + public static String getString(String key) { + try { + String messager = RESOURCE_BUNDLE.getString(key); + return messager; + } catch (MissingResourceException e) { + String messager = "不能在配置文件" + BUNDLE_NAME + "中发现参数:" + '!' + key + + '!'; + log.error(messager); + throw new RuntimeException(messager); + } + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/commons/FarmDocFiles.java b/src/wcp-doc/src/main/java/com/farm/doc/server/commons/FarmDocFiles.java new file mode 100644 index 0000000..47c73fb --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/commons/FarmDocFiles.java @@ -0,0 +1,158 @@ +package com.farm.doc.server.commons; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; + +import com.farm.core.time.TimeTool; +import com.farm.parameter.FarmParameterService; + +public class FarmDocFiles { + private static final Logger log = Logger.getLogger(FarmDocFiles.class); + + /** + * 生成文件目录 + * + * @return + */ + public static String generateDir() { + // 把临时文件拷贝到上传目录下 + String dirPath = File.separator + TimeTool.getTimeDate12().substring(0, 4) + File.separator + + TimeTool.getTimeDate12().substring(4, 6) + File.separator + TimeTool.getTimeDate12().substring(6, 8) + + File.separator + TimeTool.getTimeDate12().substring(8, 10) + File.separator; + File accessFile = new File(getFileDirPath() + dirPath); + accessFile.mkdirs(); + return dirPath; + } + + public static String getFileDirPath() { + String path = FarmParameterService.getInstance().getParameter("config.doc.dir"); + try { + if (path.startsWith("WEBROOT")) { + path = path.replace("WEBROOT", + FarmParameterService.getInstance().getParameter("farm.constant.webroot.path")); + } + String separator = File.separator; + if (separator.equals("\\")) { + separator = "\\\\"; + } + path = path.replaceAll("\\\\", "/").replaceAll("/", separator); + } catch (Exception e) { + log.warn(path + ":路径地址有误!"); + path = DocumentConfig.getString("config.doc.dir"); + } + return path; + } + + /** + * 获得文件的扩展名 + * + * @param fileName + * @return + */ + public static String getExName(String fileName) { + return fileName.substring(fileName.lastIndexOf(".")); + } + + /** + * 重html中获取系统中附件id + * + * @param html + * @return + */ + public static List getFilesIdFromHtml(String html) { + List list = new ArrayList(); + Document doc = Jsoup.parse(html); + for (Element node : doc.getElementsByTag("img")) { + String urlStr = node.attr("src"); + if (urlStr.indexOf(DocumentConfig.getString("config.doc.download.url")) >= 0) { + String splits = urlStr.substring(urlStr.indexOf(DocumentConfig.getString("config.doc.download.url")) + + DocumentConfig.getString("config.doc.download.url").length()); + list.add(splits); + } + } + for (Element node : doc.getElementsByTag("a")) { + String urlStr = node.attr("href"); + if (urlStr.indexOf(DocumentConfig.getString("config.doc.download.url")) >= 0) { + String splits = urlStr.substring(urlStr.indexOf(DocumentConfig.getString("config.doc.download.url")) + + DocumentConfig.getString("config.doc.download.url").length()); + list.add(splits); + } + } + return list; + } + + /** + * 拷贝一个文件到新的地址 + * + * @param file + * @param newPath + */ + public static void copyFile(File file, String newPath) { + int byteread = 0; + File oldfile = file; + if (oldfile.exists()) { // 文件存在时 + InputStream inStream = null; + FileOutputStream fs = null; + try { + inStream = new FileInputStream(file); + fs = new FileOutputStream(newPath + file.getName()); + byte[] buffer = new byte[1444]; + while ((byteread = inStream.read(buffer)) != -1) { + fs.write(buffer, 0, byteread); + } + } catch (FileNotFoundException e) { + log.error(e.getMessage()); + } catch (IOException e) { + log.error(e.getMessage()); + } finally { + try { + inStream.close(); + fs.close(); + } catch (IOException e) { + } + } + } + } + + /** + * 将文件流保存到一个地址 + * + * @param file + * @param newPath + */ + public static Long saveFile(InputStream inStream, String filename, String newPath) { + int byteread = 0; + FileOutputStream fs = null; + try { + fs = new FileOutputStream(newPath + filename); + byte[] buffer = new byte[1444]; + while ((byteread = inStream.read(buffer)) != -1) { + fs.write(buffer, 0, byteread); + } + } catch (FileNotFoundException e) { + log.error(e.getMessage()); + } catch (IOException e) { + log.error(e.getMessage()); + } finally { + try { + inStream.close(); + fs.close(); + } catch (IOException e) { + } + } + File file = new File(newPath + filename); + return file.length(); + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/exception/NotIsHttpZipException.java b/src/wcp-doc/src/main/java/com/farm/doc/server/exception/NotIsHttpZipException.java new file mode 100644 index 0000000..b9af689 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/exception/NotIsHttpZipException.java @@ -0,0 +1,10 @@ +package com.farm.doc.server.exception; + +public class NotIsHttpZipException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 5439455131912587745L; + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/ArticleService.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/ArticleService.java new file mode 100644 index 0000000..64040fe --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/ArticleService.java @@ -0,0 +1,52 @@ +//创建服务类 +//创建一个服务类来处理全文检索逻辑: +package com.example.fulltextsearch.service; + +import com.example.fulltextsearch.model.Article; +import com.example.fulltextsearch.repository.ArticleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * ArticleService类是服务层组件,负责处理与文章相关的业务逻辑。 + * 它通过ArticleRepository与Elasticsearch进行交互,实现文章的保存和搜索功能。 + */ +@Service +public class ArticleService { + + private final ArticleRepository articleRepository; + + /** + * ArticleService的构造函数,通过依赖注入获取ArticleRepository的实例。 + * + * @param articleRepository ArticleRepository的实例,用于执行文章的数据库操作。 + */ + @Autowired + public ArticleService(ArticleRepository articleRepository) { + this.articleRepository = articleRepository; + } + + /** + * 保存文章到Elasticsearch。 + * + * @param article 要保存的文章对象。 + * @return 返回保存后的文章对象。 + */ + public Article saveArticle(Article article) { + return articleRepository.save(article); + } + + /** + * 根据关键字搜索文章。 + * 搜索会在文章的标题和内容中进行,只要标题或内容包含关键字,文章就会被返回。 + * + * @param keyword 用于搜索的关键字。 + * @return 返回包含关键字的文章列表。 + */ + public List
searchArticles(String keyword) { + return articleRepository.findByTitleContainingOrContentContaining(keyword, keyword); + } +} + diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocIndexManagerImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocIndexManagerImpl.java new file mode 100644 index 0000000..56aff5b --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocIndexManagerImpl.java @@ -0,0 +1,334 @@ +package com.farm.doc.server.impl; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.authority.FarmAuthorityService; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.result.ResultsHandle; +import com.farm.doc.dao.FarmDocDaoInter; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.ex.DocBrief; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.doc.server.FarmDocIndexInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.doc.util.HtmlUtils; +import com.farm.doc.util.LuceneDocUtil; +import com.farm.lucene.FarmLuceneFace; +import com.farm.lucene.adapter.DocMap; +import com.farm.lucene.server.DocIndexInter; +import com.farm.lucene.server.DocQueryImpl; +import com.farm.lucene.server.DocQueryInter; +import com.farm.util.web.WebHotCase; + +@Service +public class FarmDocIndexManagerImpl implements FarmDocIndexInter { + @Resource + private FarmDocDaoInter farmDocDao; + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + @Resource + private FarmDocgroupManagerInter farmDocgroupManagerImpl; + private final static Logger log = Logger.getLogger(FarmDocIndexManagerImpl.class); + + @Override + @Transactional + public List getRelationDocs(String docid, int num) { + Doc doc = farmDocDao.getEntity(docid); + List file = new ArrayList(); + List types = farmDocTypeManagerImpl.getTypesForUserRead(getLoginUser(null)); + for (String typeid : types) { + file.add(FarmLuceneFace.inctance().getIndexPathFile("TYPE" + typeid)); + } + DocQueryInter query = DocQueryImpl.getInstance(file); + String iql = null; + if (iql == null) { + iql = "WHERE(TITLE,TEXT=" + HtmlUtils.HtmlRemoveTag(doc.getTitle().trim()).replaceAll(":", "") + ")"; + } + try { + DataResult result = query.queryByMultiIndex(iql, 1, num).getDataResult(); + result.runHandle((new ResultsHandle() { + @Override + public void handle(Map row) { + row.put("DOCID", row.get("ID")); + } + })); + return result.getObjectList(DocBrief.class); + } catch (Exception e) { + log.error(e.toString()); + return new ArrayList<>(); + } + } + + private LoginUser getLoginUser(String userId) { + if (userId == null || userId.isEmpty()) { + return null; + } else { + return FarmAuthorityService.getInstance().getUserById(userId); + } + } + + @Override + @Transactional + public DataResult search(String word, String userid, Integer pagenum) throws Exception { + // TITLE,PUBTIME,VISITNUM,TYPENAME,AUTHOR,TAGKEY,DOCDESCRIBE,TEXT + List files = new ArrayList(); + if (userid != null) { + DataResult groups = farmDocgroupManagerImpl.getGroupsByUser(userid, 1000, 1); + for (Map node : groups.getResultList()) { + File file = FarmLuceneFace.inctance().getIndexPathFile("GROUP" + (String) node.get("ID")); + if (file.isDirectory()) { + files.add(file); + } + } + } + List types = farmDocTypeManagerImpl.getTypesForUserRead(getLoginUser(userid)); + for (String typeid : types) { + files.add(FarmLuceneFace.inctance().getIndexPathFile("TYPE" + typeid)); + } + DocQueryInter query = DocQueryImpl.getInstance(files); + String iql = null; + word = HtmlUtils.HtmlRemoveTag(word.trim()); + if (word.indexOf("TYPE:") >= 0 && iql == null) { + word = word.substring(word.indexOf("TYPE:") + 5).replaceAll(":", ""); + iql = "WHERE(TYPENAME=" + word + ")"; + } + if (word.indexOf("TAG:") >= 0 && iql == null) { + word = word.substring(word.indexOf("TYPE:") + 5).replaceAll(":", ""); + iql = "WHERE(TAGKEY=" + word + ")"; + } + if (word.indexOf("AUTHOR:") >= 0 && iql == null) { + word = word.substring(word.indexOf("AUTHOR:") + 7).replaceAll(":", ""); + iql = "WHERE(AUTHOR=" + word + ")"; + } + if (word.indexOf("TITLE:") >= 0 && iql == null) { + word = word.substring(word.indexOf("TITLE:") + 6).replaceAll(":", ""); + iql = "WHERE(TITLE=" + word + ")"; + } + if (iql == null) { + // word.substring(word.indexOf("TYPE:")); + iql = "WHERE(TITLE,TEXT,TAGKEY,TYPENAME,AUTHOR=" + word.replaceAll(":", "") + ")"; + } + if (pagenum == null) { + pagenum = 1; + } + WebHotCase.putCase(word); + DataResult result = query.queryByMultiIndex(iql, pagenum, 10).getDataResult(); + for (Map node : result.getResultList()) { + String tags = node.get("TAGKEY").toString(); + String text = node.get("TEXT").toString(); + node.put("DOCDESCRIBE", text.length() > 256 ? text.substring(0, 256) : text); + if (tags != null && tags.trim().length() > 0) { + String[] tags1 = tags.trim().replaceAll(",", ",").replaceAll("、", ",").split(","); + node.put("TAGKEY", Arrays.asList(tags1)); + } else { + node.put("TAGKEY", new ArrayList()); + } + } + return result; + } + + /** + * 添加索引 + * + * @param entity + */ + @Override + @Transactional + public void addLuceneIndex(DocEntire entity) { + // 做索引 + { + DocIndexInter typeindex = null; + DocIndexInter groupindex = null; + if (entity.getCurrenttypes() == null && entity.getType() != null && entity.getType().getId() != null) { + // 构造文档分类 + entity.setCurrenttypes(farmDocTypeManagerImpl.getTypeAllParent(entity.getType().getId())); + } + try { + FarmLuceneFace luceneImpl = FarmLuceneFace.inctance(); + if (entity.getType() != null && entity.getType().getId() != null) { + // 创建分类索引 + typeindex = luceneImpl.getDocIndex(luceneImpl.getIndexPathFile("TYPE" + entity.getType().getId())); + typeindex.indexDoc(LuceneDocUtil.getDocMap(entity)); + } + if (entity.getGroup() != null && !entity.getGroup().getId().isEmpty()) { + // 创建小组索引 + groupindex = luceneImpl + .getDocIndex(luceneImpl.getIndexPathFile("GROUP" + entity.getGroup().getId())); + groupindex.indexDoc(LuceneDocUtil.getDocMap(entity)); + } + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + try { + if (groupindex != null) { + groupindex.close(); + } + if (typeindex != null) { + typeindex.close(); + } + } catch (Exception e1) { + log.error("lucene error:" + e1); + } + } + } + } + + @Override + @Transactional + public void addLuceneIndex(String fileid, String name, String text, DocEntire entity) { + // 做索引 + { + DocIndexInter typeindex = null; + DocIndexInter groupindex = null; + try { + FarmLuceneFace luceneImpl = FarmLuceneFace.inctance(); + if (entity.getType() != null && entity.getType().getId() != null) { + // 创建分类索引 + typeindex = luceneImpl.getDocIndex(luceneImpl.getIndexPathFile("TYPE" + entity.getType().getId())); + DocMap map = LuceneDocUtil.getDocMap(entity); + typeindex.indexDoc(LuceneDocUtil.convertFileMap(map, fileid, name, text)); + } + if (entity.getGroup() != null && !entity.getGroup().getId().isEmpty()) { + // 创建小组索引 + groupindex = luceneImpl + .getDocIndex(luceneImpl.getIndexPathFile("GROUP" + entity.getGroup().getId())); + DocMap map = LuceneDocUtil.getDocMap(entity); + groupindex.indexDoc(LuceneDocUtil.convertFileMap(map, fileid, name, text)); + } + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + try { + if (groupindex != null) { + groupindex.close(); + } + if (typeindex != null) { + typeindex.close(); + } + } catch (Exception e1) { + log.error("lucene error:" + e1); + } + } + } + + } + + @Override + @Transactional + public void delLuceneIndex(String docid, List typeIdList, List groupIdList) { + // 做索引 + { + DocIndexInter index = null; + DocIndexInter groupindex = null; + FarmLuceneFace luceneImpl = FarmLuceneFace.inctance(); + if (typeIdList != null) { + for (String typeid : typeIdList) { + try { + // 删除分类索引 + index = luceneImpl.getDocIndex(luceneImpl.getIndexPathFile("TYPE" + typeid)); + index.deleteFhysicsIndex(docid); + } catch (Exception e) { + throw new RuntimeException(e + "删除索引"); + } finally { + try { + if (index != null) { + index.close(); + } + } catch (Exception e1) { + log.error("lucene error:" + e1); + } + } + } + } + if (groupIdList != null) { + for (String groupid : groupIdList) { + try { + // 删除小组索引 + groupindex = luceneImpl.getDocIndex(luceneImpl.getIndexPathFile("GROUP" + groupid)); + groupindex.deleteFhysicsIndex(docid); + } catch (Exception e) { + throw new RuntimeException(e + "删除索引"); + } finally { + try { + if (groupindex != null) { + groupindex.close(); + } + } catch (Exception e1) { + log.error("lucene error:" + e1); + } + } + } + } + + } + + } + + @Override + @Transactional + public void delLuceneIndex(DocEntire doc) { + delLuceneIndex(doc, doc.getDoc().getId()); + } + + @Override + @Transactional + public void delLuceneIndex(DocEntire doc, String indexId) { + // 做索引 + { + DocIndexInter index = null; + DocIndexInter groupindex = null; + try { + FarmLuceneFace luceneImpl = FarmLuceneFace.inctance(); + if (doc.getType() != null && doc.getType().getId() != null) { + // 删除分类索引 + index = luceneImpl.getDocIndex(luceneImpl.getIndexPathFile("TYPE" + doc.getType().getId())); + index.deleteFhysicsIndex(indexId); + } + if (doc.getDoc().getDocgroupid() != null && !doc.getDoc().getDocgroupid().isEmpty()) { + // 删除小组索引 + groupindex = luceneImpl + .getDocIndex(luceneImpl.getIndexPathFile("GROUP" + doc.getDoc().getDocgroupid())); + groupindex.deleteFhysicsIndex(indexId); + } + } catch (Exception e) { + throw new RuntimeException(e + "删除索引"); + } finally { + try { + if (groupindex != null) { + groupindex.close(); + } + if (index != null) { + index.close(); + } + } catch (Exception e1) { + log.error("lucene error:" + e1); + } + } + } + + } + + /** + * 重做索引 + * + * @param entity + */ + @Override + @Transactional + public void reLuceneIndex(DocEntire olddoc, DocEntire newdoc) { + delLuceneIndex(olddoc); + addLuceneIndex(newdoc); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocManagerImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocManagerImpl.java new file mode 100644 index 0000000..66bc54f --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocManagerImpl.java @@ -0,0 +1,775 @@ +package com.farm.doc.server.impl; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Resource; + +import org.apache.commons.beanutils.BeanUtils; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.authority.domain.User; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.FarmDocDaoInter; +import com.farm.doc.dao.FarmDocenjoyDaoInter; +import com.farm.doc.dao.FarmDocfileDaoInter; +import com.farm.doc.dao.FarmDocruninfoDaoInter; +import com.farm.doc.dao.FarmDocruninfoDetailDaoInter; +import com.farm.doc.dao.FarmDoctextDaoInter; +import com.farm.doc.dao.FarmDoctypeDaoInter; +import com.farm.doc.dao.FarmRfDoctextfileDaoInter; +import com.farm.doc.dao.FarmRfDoctypeDaoInter; +import com.farm.doc.dao.FarmtopDaoInter; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDocfile; +import com.farm.doc.domain.FarmDocgroup; +import com.farm.doc.domain.FarmDocruninfo; +import com.farm.doc.domain.FarmDoctext; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.domain.FarmRfDoctextfile; +import com.farm.doc.domain.FarmRfDoctype; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.doc.domain.ex.TypeBrief; +import com.farm.doc.exception.CanNoDeleteException; +import com.farm.doc.exception.CanNoReadException; +import com.farm.doc.exception.CanNoWriteException; +import com.farm.doc.exception.DocNoExistException; +import com.farm.doc.server.FarmDocIndexInter; +import com.farm.doc.server.FarmDocManagerInter; +import com.farm.doc.server.FarmDocOperateRightInter; +import com.farm.doc.server.FarmDocOperateRightInter.POP_TYPE; +import com.farm.doc.server.FarmDocRunInfoInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.doc.server.FarmFileIndexManagerInter; +import com.farm.doc.server.FarmFileManagerInter; +import com.farm.doc.server.UsermessageServiceInter; +import com.farm.doc.server.commons.DocumentConfig; +import com.farm.doc.server.commons.FarmDocFiles; +import com.farm.doc.server.plus.FarmTypePopServerInter; +import com.farm.doc.server.plus.domain.DocAudit; +import com.farm.doc.server.plus.domain.Doctypepop; +import com.farm.doc.util.DocTagUtils; +import com.farm.doc.util.HtmlUtils; + +/** + * 文档管理 + * + * @author MAC_wd + */ +@Service +public class FarmDocManagerImpl implements FarmDocManagerInter { + private static final Logger log = Logger.getLogger(FarmDocManagerImpl.class); + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + @Resource + private FarmDocDaoInter farmDocDao; + @Resource + private FarmDocfileDaoInter farmDocfileDao; + @Resource + private FarmDoctextDaoInter farmDoctextDao; + @Resource + private FarmTypePopServerInter farmTypePopServerImpl; + @Resource + private FarmRfDoctextfileDaoInter farmRfDoctextfileDao; + @Resource + private FarmRfDoctypeDaoInter farmRfDoctypeDao; + @Resource + private FarmDoctypeDaoInter farmDoctypeDao; + @Resource + private FarmDocruninfoDaoInter farmDocruninfoDao; + @Resource + private FarmDocenjoyDaoInter farmDocenjoyDao; + @Resource + private FarmDocOperateRightInter farmDocOperate; + @Resource + private FarmDocgroupManagerInter farmDocgroupManagerImpl; + @Resource + private FarmDocruninfoDetailDaoInter farmDocruninfoDetailDao; + @Resource + private FarmDocRunInfoInter farmDocRunInfoImpl; + @Resource + private FarmFileManagerInter farmFileServer; + @Resource + private FarmtopDaoInter farmtopDaoImpl; + @Resource + private FarmDocOperateRightInter farmDocOperateRightImpl; + @Resource + private UsermessageServiceInter usermessageServiceImpl; + @Resource + private FarmDocIndexInter farmDocIndexManagerImpl; + @Resource + private FarmFileIndexManagerInter farmFileIndexManagerImpl; + + @Transactional + public DocEntire createDoc(DocEntire entity, LoginUser user) { + try { + {// 保存用量信息 + FarmDocruninfo runinfo = new FarmDocruninfo(); + runinfo.setHotnum(0); + runinfo.setLastvtime(TimeTool.getTimeDate14()); + runinfo.setPraiseno(0); + runinfo.setPraiseyes(0); + runinfo.setVisitnum(0); + runinfo.setAnsweringnum(0); + runinfo.setEvaluate(0); + runinfo = farmDocruninfoDao.insertEntity(runinfo); + entity.getDoc().setRuninfoid(runinfo.getId()); + entity.setRuninfo(runinfo); + } + {// 先保存text + entity.getTexts().setPstate("1");// 1在用内容。2.版本存档 + entity.getTexts().setPcontent("CREAT"); + entity.setTexts(farmDoctextDao.insertEntity(entity.getTexts())); + entity.getDoc().setTextid(entity.getTexts().getId()); + } + + {// 保存doc对象 + // 如果没有文字简介自动填充简介 + if (entity.getDoc().getDocdescribe() == null || entity.getDoc().getDocdescribe().trim().length() <= 0) { + if (entity.getTexts() != null) { + String html = HtmlUtils.HtmlRemoveTag(entity.getTexts().getText1()); + entity.getDoc().setDocdescribe(html.length() > 128 ? html.substring(0, 128) : html); + } + } + // 如果没有 tags就生成tags + if (entity.getDoc().getTagkey() == null || entity.getDoc().getTagkey().trim().length() <= 0) {// 自动生成tag + entity.getDoc().setTagkey(DocTagUtils.getTags(entity.getTexts().getText1())); + } + entity.getDoc().setCtime(TimeTool.getTimeDate14()); + entity.getDoc().setEtime(TimeTool.getTimeDate14()); + entity.getDoc().setCuser(user.getId()); + entity.getDoc().setEuser(user.getId()); + entity.getDoc().setCusername(user.getName()); + entity.getDoc().setEusername(user.getName()); + entity.getDoc().setPubtime( + entity.getDoc().getPubtime().replaceAll("-", "").replaceAll(":", "").replaceAll(" ", "")); + if (entity.getDoc().getReadpop() == null) { + entity.getDoc().setReadpop(POP_TYPE.PUB.getValue()); + } + if (entity.getDoc().getWritepop() == null) { + entity.getDoc().setWritepop(POP_TYPE.PUB.getValue()); + } + if (entity.getDoc().getImgid() != null && !entity.getDoc().getImgid().isEmpty()) { + farmFileServer.submitFile(entity.getDoc().getImgid()); + } + if (entity.getDoc().getAuthor() == null || entity.getDoc().getAuthor().isEmpty()) { + entity.getDoc().setAuthor(user.getName()); + } + if (entity.getType() != null && !entity.getType().getAuditpop().equals("0")) { + // 文档需要审核,修改状态 + entity.getDoc().setState("2"); + } + entity.setDoc(farmDocDao.insertEntity(entity.getDoc())); + } + + {// audit + if (entity.getType() != null && !entity.getType().getAuditpop().equals("0")) { + DocAudit audit = farmTypePopServerImpl.auditHandleForDocCreate(entity.getDoc().getId(), + entity.getTexts().getId(), user); + entity.setAudit(audit); + entity.setAuditTemp(entity.getTexts()); + usermessageServiceImpl.sendMessage( + farmDocTypeManagerImpl.getPopTypeAudtUserIds(entity.getType().getId()), + farmTypePopServerImpl.getMessageForNeedAudit(entity.getDoc().getTitle()), + farmTypePopServerImpl.getMessageTitleForNeedAudit(entity.getDoc().getTitle())); + } + } + {// 保存分类信息 + if (entity.getType() != null) { + farmRfDoctypeDao.insertEntity(new FarmRfDoctype(entity.getType().getId(), entity.getDoc().getId())); + } + } + entity.setDoc(farmDocDao.insertEntity(entity.getDoc())); + { + // 保存关联附件信息(中间表) + List files = FarmDocFiles.getFilesIdFromHtml(entity.getTexts().getText1()); + for (String id : files) { + farmRfDoctextfileDao.insertEntity(new FarmRfDoctextfile(entity.getDoc().getId(), id)); + farmFileServer.submitFile(id); + } + // 处理文档表单中带人的图片附件 + List files2 = entity.getFiles(); + for (FarmDocfile file : files2) { + farmRfDoctextfileDao.insertEntity(new FarmRfDoctextfile(entity.getDoc().getId(), file.getId())); + farmFileServer.submitFile(file.getId()); + } + } + { + // 处理小组 + if (entity.getDoc().getDocgroupid() != null && !entity.getDoc().getDocgroupid().isEmpty()) { + entity.setGroup(farmDocgroupManagerImpl.getFarmDocgroup(entity.getDoc().getDocgroupid())); + } + } + {// 如果分类不需要审核,就做索引 + if (entity.getType() == null || entity.getType().getAuditpop().equals("0")) { + farmDocIndexManagerImpl.addLuceneIndex(entity); + } + } + } catch (Exception e) { + throw new RuntimeException("farmDoc文档创建失败:" + e + e.getMessage()); + } + return entity; + } + + @Transactional + public DocEntire editDocByUser(DocEntire entity, String editNote, LoginUser user) throws CanNoWriteException { + Doc entity2 = farmDocDao.getEntity(entity.getDoc().getId()); + if (!farmDocOperate.isWrite(user, entity2)) { + throw new CanNoWriteException(); + } + return editDoc(entity, editNote, user); + } + + @Transactional + public DocEntire editDoc(DocEntire paradoce, String editNote, LoginUser user) { + DocEntire newDoce = getDoc(paradoce.getDoc().getId()); + DocEntire oldDoce = null; + try { + oldDoce = (DocEntire) BeanUtils.cloneBean(newDoce); + } catch (Exception e) { + throw new RuntimeException(e); + } + newDoce.getDoc().setEtime(TimeTool.getTimeDate14()); + newDoce.getDoc().setEuser(user.getId()); + newDoce.getDoc().setEusername(user.getName()); + if (paradoce.getDoc().getPcontent() != null) { + newDoce.getDoc().setPcontent(paradoce.getDoc().getPcontent()); + } + if (paradoce.getDoc().getReadpop() != null) { + newDoce.getDoc().setReadpop(paradoce.getDoc().getReadpop()); + } + if (paradoce.getDoc().getWritepop() != null) { + newDoce.getDoc().setWritepop(paradoce.getDoc().getWritepop()); + } + if (paradoce.getDoc().getState() != null) { + newDoce.getDoc().setState(paradoce.getDoc().getState()); + } + if (paradoce.getDoc().getDocgroupid() != null) { + newDoce.getDoc().setDocgroupid(paradoce.getDoc().getDocgroupid()); + } + if (paradoce.getDoc().getImgid() != null && !paradoce.getDoc().getImgid().isEmpty()) { + newDoce.getDoc().setImgid(paradoce.getDoc().getImgid()); + } + if (paradoce.getDoc().getTopleve() != null) { + newDoce.getDoc().setTopleve(paradoce.getDoc().getTopleve()); + } + if (paradoce.getDoc().getPubtime() != null) { + newDoce.getDoc().setPubtime( + paradoce.getDoc().getPubtime().replaceAll(" ", "").replaceAll("-", "").replaceAll(":", "")); + } + if (paradoce.getDoc().getSource() != null) { + newDoce.getDoc().setSource(paradoce.getDoc().getSource()); + } + if (paradoce.getDoc().getTagkey() != null) { + newDoce.getDoc().setTagkey(paradoce.getDoc().getTagkey()); + } + if (paradoce.getDoc().getShorttitle() != null) { + newDoce.getDoc().setShorttitle(paradoce.getDoc().getShorttitle()); + } + if (paradoce.getDoc().getDomtype() != null) { + newDoce.getDoc().setDomtype(paradoce.getDoc().getDomtype()); + } + if (newDoce.getDoc().getAuthor() == null) { + newDoce.getDoc().setAuthor(newDoce.getDoc().getCusername()); + } + if (paradoce.getDoc().getAuthor() != null) { + newDoce.getDoc().setAuthor(paradoce.getDoc().getAuthor()); + } + if (paradoce.getTexts() != null) { + String html = HtmlUtils.HtmlRemoveTag(paradoce.getTexts().getText1()); + newDoce.getDoc().setDocdescribe(html.length() > 128 ? html.substring(0, 128) : html); + } + if (!paradoce.getDoc().getDocdescribe().isEmpty()) { + newDoce.getDoc().setDocdescribe(paradoce.getDoc().getDocdescribe()); + } + if (paradoce.getDoc().getTitle() != null) { + newDoce.getDoc().setTitle(paradoce.getDoc().getTitle()); + } + + FarmDoctype oldType = farmRfDoctypeDao.getDocType(paradoce.getDoc().getId()); + FarmDoctype newType = paradoce.getType(); + if(newType!=null){ + newDoce.setType(newType); + List typelist = new ArrayList(); + typelist.add(newType); + newDoce.setCurrenttypes(typelist); + } + if (newType == null) { + newType = oldType; + } + farmDocDao.editEntity(newDoce.getDoc()); + // 处理版本信息 + { + // 审核相关代码(处理版本,分类未改变时知识新建立版本并设置为待审核状态) + if (newType != null && !newType.getAuditpop().equals("0")) { + editDocAuditHandle(newType, oldType, newDoce, paradoce, user, editNote); + + } else { + // 不需要审核,直接提交到新版本 + usermessageServiceImpl.sendMessage(farmDocRunInfoImpl.getDocJoinUserIds(newDoce.getDoc().getId()), + "知识‘" + newDoce.getDoc().getTitle() + "’有新版本提交", "知识更新消息"); + insertDocTextVersionForCurrent(newDoce, paradoce, user, editNote); + } + } + { + // 处理超文本中的图片附件 + List files = FarmDocFiles.getFilesIdFromHtml(paradoce.getTexts().getText1()); + for (String id : files) { + // 删除掉重复的附件 + List listRules = new ArrayList(); + listRules.add(new DBRule("FILEID", id, "=")); + listRules.add(new DBRule("DOCID", newDoce.getDoc().getId(), "=")); + + FarmDocfile file = farmFileServer.getFile(id); + if (file != null) { + farmRfDoctextfileDao.deleteEntitys(listRules); + farmRfDoctextfileDao.insertEntity(new FarmRfDoctextfile(newDoce.getDoc().getId(), id)); + // 处理附件 + farmFileServer.submitFile(id); + } else { + log.error("file(" + id + ") not exist at database!"); + } + } + // 处理文档表单中带人的图片附件 + List files2 = paradoce.getFiles(); + for (FarmDocfile file : files2) { + farmRfDoctextfileDao.insertEntity(new FarmRfDoctextfile(newDoce.getDoc().getId(), file.getId())); + // 处理附件 + farmFileServer.submitFile(file.getId()); + } + } + // 修改分类 + List list = farmRfDoctypeDao + .selectEntitys(new DBRule("DOCID", paradoce.getDoc().getId(), "=").getDBRules()); + if (paradoce.getType() != null) { + if (list != null && list.size() > 0) { + // 知识有分类 + FarmRfDoctype farmRfDoctype = list.get(0); + farmRfDoctype.setTypeid(paradoce.getType().getId()); + farmRfDoctypeDao.editEntity(farmRfDoctype); + } else { + // 知识无分类,创建分类 + farmRfDoctypeDao.insertEntity(new FarmRfDoctype(paradoce.getType().getId(), paradoce.getDoc().getId())); + } + } + + // 不需要审核,做索引 + if (newType == null || newType.getAuditpop().equals("0")) { + // 如果是资源文件,移动分类需要处理附件的索引 + farmFileIndexManagerImpl.handleFileLucenneIndexBymoveType(oldDoce, newDoce); + // 重做知识索引 + farmDocIndexManagerImpl.reLuceneIndex(oldDoce, newDoce); + } else { + // 分类已变,知识需要重新审核,并在审核之前删除索引 + if (!newType.getId().equals(oldType.getId())) { + farmDocIndexManagerImpl.delLuceneIndex(oldDoce); + } + } + return newDoce; + } + + /** + * audit + * + * @param newType + * @param oldType + * @param newDoce + * @param paradoce + * @param user + * @param editNote + */ + private void editDocAuditHandle(FarmDoctype newType, FarmDoctype oldType, DocEntire newDoce, DocEntire paradoce, + LoginUser user, String editNote) { + // 需要审核 + FarmDoctext newText = null; + // 分类未变,只是审核版本 + if (newType.getId().equals(oldType.getId())) { + // 为文档添加一个版本(增加新版本,且新版本状态为待审核) + newText = insertDocTextVersionForTemp(newDoce, paradoce, user, editNote); + } else { + // 分类改变的情况下 + // 添加新的版本.并将知识变为待审核状态 原来版本 新版本 + newText = insertDocTextVersionForTemp(newDoce, paradoce, user, editNote); + newDoce.getDoc().setState("2"); + farmDocDao.editEntity(newDoce.getDoc()); + farmDocIndexManagerImpl.delLuceneIndex(paradoce); + } + DocAudit audit = farmTypePopServerImpl.auditHandleForDocEdit(paradoce.getDoc().getId(), newText.getId(), user); + newDoce.setAudit(audit); + newDoce.setAuditTemp(newText); + usermessageServiceImpl.sendMessage(farmDocTypeManagerImpl.getPopTypeAudtUserIds(newType.getId()), + farmTypePopServerImpl.getMessageForNeedAudit(newDoce.getDoc().getTitle()), + farmTypePopServerImpl.getMessageTitleForNeedAudit(newDoce.getDoc().getTitle())); + } + + /** + * 添加一个新版本到当前版本(直接不需要审核直接通过) + * + * @param oldText + * 原来的版本 + * @param newText + * 新版本 + * @param user + * 当前用户 + * @param message + * 修改备注 + * @return 原来版本 新版本 + */ + private FarmDoctext insertDocTextVersionForCurrent(DocEntire dbText, DocEntire newText, LoginUser user, + String message) { + FarmDoctext text = farmDoctextDao.getEntity(dbText.getDoc().getTextid()); + try { + FarmDoctext histext = (FarmDoctext) BeanUtils.cloneBean(text); + histext.setId(null); + histext.setPstate("2"); + histext.setDocid(dbText.getDoc().getId()); + farmDoctextDao.insertEntity(histext); + } catch (Exception e) { + throw new RuntimeException(e); + } + text.setText1(newText.getTexts().getText1()); + text.setCtime(TimeTool.getTimeDate14()); + text.setEtime(TimeTool.getTimeDate14()); + text.setCuser(user.getId()); + text.setPcontent(message); + text.setCusername(user.getName()); + text.setEuser(user.getId()); + text.setEusername(user.getName()); + farmDoctextDao.editEntity(text); + return newText.getTexts(); + } + + /** + * 添加一个新版本到待审核版本(需要审核,) + * + * @param oldText + * 原来的版本 + * @param newText + * 新版本 + * @param user + * 当前用户 + * @param message + * 修改备注 + * @return + */ + private FarmDoctext insertDocTextVersionForTemp(DocEntire oldText, DocEntire newText, LoginUser user, + String message) { + // 直接添加新的未审核版本 + FarmDoctext text = farmDoctextDao.getEntity(oldText.getDoc().getTextid()); + FarmDoctext newtext; + try { + if (text == null) { + text = new FarmDoctext(); + } + FarmDoctext histext = (FarmDoctext) BeanUtils.cloneBean(text); + histext.setId(null); + // 1在用内容。2.版本存档,3待审核 + histext.setPstate("3"); + histext.setDocid(oldText.getDoc().getId()); + histext.setText1(newText.getTexts().getText1()); + histext.setCtime(TimeTool.getTimeDate14()); + histext.setEtime(TimeTool.getTimeDate14()); + histext.setCuser(user.getId()); + histext.setPcontent(message); + histext.setCusername(user.getName()); + histext.setEuser(user.getId()); + histext.setEusername(user.getName()); + newtext = farmDoctextDao.insertEntity(histext); + } catch (Exception e) { + throw new RuntimeException(e); + } + return newtext; + } + + @Transactional + public DocEntire deleteDoc(String entity, LoginUser user) throws CanNoDeleteException { + Doc doc = farmDocDao.getEntity(entity); + if (!farmDocOperate.isDel(user, doc)) { + throw new CanNoDeleteException("当前用户无此权限!"); + } + return deleteDocNoPop(entity, user); + } + + @Override + public DataQuery createSimpleDocQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, + "FARM_DOC A LEFT JOIN FARM_RF_DOCTYPE B ON B.DOCID =A.ID LEFT JOIN FARM_DOCTYPE C ON C.ID=B.TYPEID LEFT JOIN farm_docgroup d ON d.ID=a.DOCGROUPID", + "A.ID AS ID,A.DOCDESCRIBE as DOCDESCRIBE,A.WRITEPOP as WRITEPOP,A.READPOP as READPOP,A.TITLE AS TITLE,A.AUTHOR AS AUTHOR,A.PUBTIME AS PUBTIME,A.DOMTYPE AS DOMTYPE,A.SHORTTITLE AS SHORTTITLE,A.TAGKEY AS TAGKEY,A.STATE AS STATE,D.GROUPNAME AS GROUPNAME "); + return dbQuery; + } + + @Override + @Transactional + public DocEntire getDoc(String docid) { + if (docid == null || docid.isEmpty()) { + return null; + } + DocEntire doce = new DocEntire(farmDocDao.getEntity(docid)); + doce.setTexts(farmDoctextDao.getEntity(doce.getDoc().getTextid())); + List types = farmRfDoctypeDao.getDocTypes(docid); + if (types.size() > 0) { + doce.setType(types.get(0)); + doce.setCurrenttypes(farmDocTypeManagerImpl.getTypeAllParent(doce.getType().getId())); + } + doce.setRuninfo(farmDocruninfoDao.getEntity(doce.getDoc().getRuninfoid())); + if (doce.getDoc().getTagkey() != null) { + String tags = doce.getDoc().getTagkey(); + String[] tags1 = tags.trim().replaceAll(",", ",").replaceAll("、", ",").split(","); + doce.setTags(Arrays.asList(tags1)); + } + if (doce.getDoc().getDocgroupid() != null) { + doce.setGroup(farmDocgroupManagerImpl.getFarmDocgroup(doce.getDoc().getDocgroupid())); + doce.getGroup().setImgurl(farmFileServer.getFileURL(doce.getGroup().getGroupimg())); + } + // 处理附件 + List files = farmDocfileDao.getEntityByDocId(docid); + for (FarmDocfile file : files) { + file.setUrl(farmFileServer.getFileURL(file.getId())); + } + doce.setFiles(files); + if (doce.getDoc().getImgid() != null && doce.getDoc().getImgid().trim().length() > 0) { + String url = DocumentConfig.getString("config.doc.download.url") + doce.getDoc().getImgid(); + doce.setImgUrl(url); + } + // 处理作者信息 + { + User user = new User(); + user.setId(doce.getDoc().getCuser()); + user.setName(doce.getDoc().getCusername()); + doce.setUser(user); + } + // 处理分类权限 + { + if (doce.getType() != null) { + List pops = farmDocTypeManagerImpl.getTypePops(doce.getType().getId()); + List readpops = new ArrayList<>(); + List writepops = new ArrayList<>(); + List auditpops = new ArrayList<>(); + for (Doctypepop node : pops) { + if (node.getFuntype().equals("1")) { + // 浏览 + readpops.add(node); + } + if (node.getFuntype().equals("2")) { + // 编辑 + writepops.add(node); + } + if (node.getFuntype().equals("3")) { + // 审核 + auditpops.add(node); + } + } + doce.setTypeReadPops(readpops); + doce.setTypeWritePops(writepops); + doce.setTypeAuditPops(auditpops); + } + } + return doce; + } + + @Override + @Transactional + public DocEntire getDoc(String docid, LoginUser user) throws CanNoReadException, DocNoExistException { + Doc docbean = farmDocDao.getEntity(docid); + if (docbean == null) { + { + // 在所有分类和小组中删除该知识 + List types = farmDocTypeManagerImpl.getPubTypes(); + List types_str = new ArrayList<>(); + for (TypeBrief type : types) { + types_str.add(type.getId()); + } + List groups = farmDocgroupManagerImpl.getAllGroup(); + List groups_str = new ArrayList<>(); + for (FarmDocgroup group : groups) { + groups_str.add(group.getId()); + } + farmDocIndexManagerImpl.delLuceneIndex(docid, types_str, groups_str); + } + throw new DocNoExistException(); + } + if (!farmDocOperate.isRead(user, docbean)) { + throw new CanNoReadException(); + } + DocEntire doc = getDoc(docid); + return doc; + } + + @Override + @Transactional + public Doc getDocOnlyBean(String id) { + return farmDocDao.getEntity(id); + } + + @Override + public DataQuery createSimpleTypeQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, "farm_doctype a LEFT JOIN farm_doctype b ON a.PARENTID=b.id", + "a.ID AS id,a.READPOP as READPOP,a.WRITEPOP as WRITEPOP,a.AUDITPOP as AUDITPOP,a.NAME AS NAME,a.TYPEMOD AS TYPEMOD,a.CONTENTMOD AS CONTENTMOD,a.SORT AS SORT,a.TYPE AS TYPE, a.METATITLE AS METATITLE,a.METAKEY AS METAKEY,a.METACONTENT AS METACONTENT,a.LINKURL AS LINKURL,a.PCONTENT AS PCONTENT,a.PSTATE AS PSTATE"); + return dbQuery; + } + + @Override + @Transactional + public void updateDocTypeOnlyOne(String docid, String typeId) { + List list = new ArrayList(); + list.add(new DBRule("DOCID", docid, "=")); + farmRfDoctypeDao.deleteEntitys(list); + farmRfDoctypeDao.insertEntity(new FarmRfDoctype(typeId, docid)); + } + + // WHERE PSTATE='2' AND DOCID='' + @SuppressWarnings("unchecked") + @Override + @Transactional + public List getDocVersions(String docId) { + FarmDoctext docText = farmDoctextDao.getEntity(getDocOnlyBean(docId).getTextid()); + DataQuery dbQuery = DataQuery.getInstance("1", "ID,ETIME,CUSERNAME,DOCID,PCONTENT,PSTATE", "farm_doctext"); + dbQuery.addRule(new DBRule("PSTATE", "1", "!=")); + dbQuery.addRule(new DBRule("DOCID", docId, "=")); + dbQuery.addSqlRule("and PSTATE !='3'"); + dbQuery.setPagesize(100); + dbQuery.addSort(new DBSort("CTIME", "DESC")); + dbQuery.setNoCount(); + @SuppressWarnings("rawtypes") + List list = new ArrayList(); + list.add(docText); + try { + list.addAll(dbQuery.search().getObjectList(FarmDoctext.class)); + } catch (SQLException e) { + throw new RuntimeException(); + } + return list; + } + + @Override + @Transactional + public DocEntire getDocVersion(String textId, LoginUser currentUser) { + if (textId == null) { + return null; + } + FarmDoctext text = farmDoctextDao.getEntity(textId); + DocEntire doc = new DocEntire(farmDocDao.getEntity(text.getDocid())); + if (doc.getDoc().getReadpop().equals("0") && !doc.getDoc().getCuser().equals(currentUser.getId())) { + throw new RuntimeException("没有阅读权限"); + } + doc.setTexts(text); + + List doctypes = farmRfDoctypeDao.getDocTypes(doc.getDoc().getId()); + if (doctypes.size() > 0) { + doc.setType(doctypes.get(0)); + doc.setCurrenttypes(farmDocTypeManagerImpl.getTypeAllParent(doctypes.get(0).getId())); + } + if (doc.getDoc().getTagkey() != null) { + String tags = doc.getDoc().getTagkey(); + String[] tags1 = tags.trim().replaceAll(",", ",").replaceAll("、", ",").split(","); + doc.setTags(Arrays.asList(tags1)); + } + return doc; + } + + @Override + @Transactional + public void delImg(String imgid) { + // farmDocfileDao.deleteEntity(farmDocfileDao.getEntity(imgid)); + // 清空文档关联附件字段 + List docList = farmDocDao.selectEntitys(new DBRule("IMGID", imgid, "=").getDBRules()); + + for (Doc doc : docList) { + doc.setImgid(null); + } + + // 删除文档和附件中间表 + farmRfDoctextfileDao.deleteEntitys(new DBRule("FILEID", imgid, "=").getDBRules()); + + // 删除附件表和附件 + farmFileServer.delFile(imgid, null); + } + + @Override + @Transactional + public DocEntire deleteDocNoPop(String entity, LoginUser user) throws CanNoDeleteException { + DocEntire doc = getDoc(entity); + FarmDoctext text = farmDoctextDao.getEntity(doc.getDoc().getTextid()); + farmTypePopServerImpl.delAuditInfo(doc.getDoc().getId()); + // 删除置顶 + farmtopDaoImpl.deleteEntitys(new DBRule("docid", entity, "=").getDBRules()); + // 删除关注 + List joylist = new ArrayList(); + joylist.add(new DBRule("DOCID", doc.getDoc().getId(), "=")); + farmDocenjoyDao.deleteEntitys(joylist); + // 删除分类中间表 + List rulesDelType = new ArrayList(); + rulesDelType.add(new DBRule("DOCID", doc.getDoc().getId(), "=")); + farmRfDoctypeDao.deleteEntitys(rulesDelType); + // 删除文档 + farmDocDao.deleteEntity(doc.getDoc()); + // 删除附件中间表 + List rulesDelFile = new ArrayList(); + rulesDelFile.add(new DBRule("DOCID", doc.getDoc().getId(), "=")); + List files = farmRfDoctextfileDao.selectEntitys(rulesDelFile); + for (FarmRfDoctextfile node : files) { + farmFileServer.delFile(node.getFileid(), user); + } + // 删除中间表文档和附件表 + List rulesDelText = new ArrayList(); + rulesDelText.add(new DBRule("DOCID", doc.getDoc().getId(), "=")); + farmRfDoctextfileDao.deleteEntitys(rulesDelText); + // 删除附件 + if (doc.getDoc().getImgid() != null && doc.getDoc().getImgid().trim().length() > 0) { + farmDocfileDao.deleteEntity(farmDocfileDao.getEntity(doc.getDoc().getImgid())); + } + // 删除用量明细 + { + List rulesDelruninfoDetail = new ArrayList(); + rulesDelruninfoDetail.add(new DBRule("RUNINFOID", doc.getDoc().getRuninfoid(), "=")); + farmDocruninfoDetailDao.deleteEntitys(rulesDelruninfoDetail); + } + // 删除用量信息 + farmDocruninfoDao.deleteEntity(farmDocruninfoDao.getEntity(doc.getDoc().getRuninfoid())); + // 删除大文本信息 + farmDoctextDao.deleteEntity(text); + farmDocIndexManagerImpl.delLuceneIndex(doc); + return doc; + } + + @Override + public DataQuery createAllPubDocQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, + "FARM_DOC A LEFT JOIN FARM_RF_DOCTYPE B ON B.DOCID =A.ID LEFT JOIN FARM_DOCTYPE C ON C.ID=B.TYPEID LEFT JOIN farm_docgroup d ON d.ID=a.DOCGROUPID", + "A.ID AS ID,A.DOCDESCRIBE as DOCDESCRIBE,A.WRITEPOP as WRITEPOP,A.READPOP as READPOP,A.TITLE AS TITLE,A.AUTHOR AS AUTHOR,A.PUBTIME AS PUBTIME,A.DOMTYPE AS DOMTYPE,A.SHORTTITLE AS SHORTTITLE,A.TAGKEY AS TAGKEY,A.STATE AS STATE,D.GROUPNAME AS GROUPNAME "); + dbQuery.addRule(new DBRule("c.READPOP", "0", "=")); + dbQuery.addRule(new DBRule("a.READPOP", "1", "=")); + return dbQuery; + } + + @Override + @Transactional + public void move2Type(String docIds, String typeId) { + if (docIds == null || docIds.isEmpty()) { + throw new RuntimeException("无法获取参数:docIds"); + } + if (typeId == null || typeId.isEmpty()) { + throw new RuntimeException("无法获取参数:typeId"); + } + + String[] docIdsArr = docIds.split(","); + for (String docId : docIdsArr) { + List list = farmRfDoctypeDao.selectEntitys(new DBRule("DOCID", docId, "=").getDBRules()); + if (list.size() > 0) { + FarmRfDoctype farmRfDoctype = list.get(0); + farmRfDoctype.setTypeid(typeId); + farmRfDoctypeDao.editEntity(farmRfDoctype); + } + } + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocOperateRightImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocOperateRightImpl.java new file mode 100644 index 0000000..17281c9 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocOperateRightImpl.java @@ -0,0 +1,293 @@ +package com.farm.doc.server.impl; + +import java.util.List; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.authority.domain.Organization; +import com.farm.authority.service.OrganizationServiceInter; +import com.farm.authority.service.UserServiceInter; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.FarmDocDaoInter; +import com.farm.doc.dao.FarmRfDoctypeDaoInter; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.server.FarmDocOperateRightInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.doc.server.plus.domain.Doctypepop; + +@Service +public class FarmDocOperateRightImpl implements FarmDocOperateRightInter { + @Resource + private FarmDocDaoInter farmDocDao; + @Resource + private FarmDocgroupManagerInter farmdocgroupServer; + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + @Resource + private FarmRfDoctypeDaoInter farmRfDoctypeDao; + @Resource + private OrganizationServiceInter organizationServiceImpl; + @Resource + UserServiceInter userServiceImpl; + + @Override + @Transactional + public boolean isDel(LoginUser user, Doc doc) { + FarmDoctype type = farmRfDoctypeDao.getDocType(doc.getId()); + if (type != null && !type.getAuditpop().equals("0")) { + // 分类需要审核 + return false; + } + if (user == null) { + return false; + } + // 非小组权限只允许本人删除 + if (!doc.getWritepop().equals("2") && doc.getCuser().equals(user.getId())) { + return true; + } + // 如果编辑权限是小组的,只有管理员可以删除 + if (doc.getWritepop().equals("2")) { + if (doc.getDocgroupid() == null) { + return false; + } + // 本人可以删除 + // if(doc.getCuser().equals(user.getId())){ + // return true; + // } + if (farmdocgroupServer.isAdminForGroup(user.getId(), doc.getDocgroupid())) { + return true; + } + } + return false; + } + + private boolean isRead(LoginUser user, Doc doc, FarmDoctype type) { + // 1分类 + if (doc.getReadpop().equals("1")) { + if (type == null) { + type = farmRfDoctypeDao.getDocType(doc.getId()); + } + if (type == null) { + //如果该分类不存在则运行访问 + return true; + } + if (type.getReadpop().equals("0")) { + // 分类公开 + return true; + } else { + // 分类有权限 + if (user != null) { + Organization org = userServiceImpl.getUserOrganization(user.getId()); + List pops = farmDocTypeManagerImpl.getTypePops(type.getId()); + for (Doctypepop node : pops) { + if (node.getFuntype().equals("1")) { + if (node.getOid().equals(user.getId())) { + // 该用户又权限访问分类 + return true; + } + if (org.getTreecode().indexOf(node.getOid()) >= 0) { + // 该组织机构又权限访问分类 + return true; + } + } + } + return false; + } else { + return false; + } + } + } + // 0本人 + if (doc.getReadpop().equals("0")) { + // 权限是本人的时候,允许本人阅读 + if (user != null && doc.getCuser().equals(user.getId())) { + return true; + } + return false; + } + // 2小组 + if (doc.getReadpop().equals("2")) { + // 当阅读权限被指定到小组,且小组是公开的时候可以阅读 + if (doc.getDocgroupid() != null && !farmdocgroupServer.isJoinCheck(doc.getDocgroupid())) { + return true; + } + if (user != null && doc.getDocgroupid() != null + && farmdocgroupServer.isJoinGroupByUser(doc.getDocgroupid(), user.getId())) { + return true; + } + } + // 3禁用 + if (doc.getReadpop().equals("3")) { + return false; + } + return false; + } + + @Override + @Transactional + public boolean isRead(LoginUser user, Doc doc) { + return isRead(user, doc, null); + } + + @Override + @Transactional + public boolean isAllUserRead(Doc doc) { + return isRead(null, doc); + } + + @Override + @Transactional + public boolean isAllUserRead(Doc doc, FarmDoctype type) { + return isRead(null, doc, type); + } + + @Override + @Transactional + public boolean isWrite(LoginUser user, Doc doc) { + // 1分类 + if (doc.getWritepop().equals("1")) { + FarmDoctype type = farmRfDoctypeDao.getDocType(doc.getId()); + if (type.getWritepop().equals("0")) { + // 分类公开 + return true; + } else { + // 分类有权限 + if (user != null) { + // 如果是资源则不能被修改 + if (doc.getDomtype().equals("5")) { + return false; + } + Organization org = userServiceImpl.getUserOrganization(user.getId()); + List pops = farmDocTypeManagerImpl.getTypePops(type.getId()); + for (Doctypepop node : pops) { + if (node.getFuntype().equals("2")) { + if (node.getOid().equals(user.getId())) { + // 该用户又权限访问分类 + return true; + } + if (org.getTreecode().indexOf(node.getOid()) >= 0) { + // 该组织机构又权限访问分类 + return true; + } + } + } + return false; + } else { + return false; + } + } + } + // 0本人 + if (doc.getWritepop().equals("0")) { + // 权限是本人的时候,允许本人阅读 + if (user != null && doc.getCuser().equals(user.getId())) { + return true; + } + return false; + } + // 2小组 + if (doc.getWritepop().equals("2")) { + // 当阅读权限被指定到小组,且小组是公开的时候可以阅读 + if (doc.getDocgroupid() != null && !farmdocgroupServer.isJoinCheck(doc.getDocgroupid())) { + return true; + } + if (user != null && doc.getDocgroupid() != null + && farmdocgroupServer.isJoinGroupByUser(doc.getDocgroupid(), user.getId())) { + return true; + } + } + // 3禁用 + if (doc.getWritepop().equals("3")) { + return false; + } + return false; + } + + @Override + @Transactional + public Doc editDocRight(String docId, POP_TYPE pop_type_read, POP_TYPE pop_type_write, LoginUser currentUser) { + Doc entity2 = farmDocDao.getEntity(docId); + entity2.setWritepop(pop_type_write.getValue()); + entity2.setReadpop(pop_type_read.getValue()); + entity2.setEuser(currentUser.getId()); + entity2.setEusername(currentUser.getName()); + entity2.setEtime(TimeTool.getTimeDate14()); + farmDocDao.editEntity(entity2); + return entity2; + } + + @Override + @Transactional + public void flyDoc(String id, LoginUser currentUser) { + Doc doc = farmDocDao.getEntity(id); + if (isDel(currentUser, doc)) { + flyDoc(doc); + } else { + throw new RuntimeException("您没有此权限"); + } + } + + @Override + @Transactional + public void flyDoc(Doc doc) { + doc.setDocgroupid(null); + doc.setReadpop(POP_TYPE.PUB.getValue()); + doc.setWritepop(POP_TYPE.PUB.getValue()); + farmDocDao.editEntity(doc); + } + + public FarmDocDaoInter getFarmDocDao() { + return farmDocDao; + } + + public void setFarmDocDao(FarmDocDaoInter farmDocDao) { + this.farmDocDao = farmDocDao; + } + + public FarmDocgroupManagerInter getFarmdocgroupServer() { + return farmdocgroupServer; + } + + public void setFarmdocgroupServer(FarmDocgroupManagerInter farmdocgroupServer) { + this.farmdocgroupServer = farmdocgroupServer; + } + + @Override + @Transactional + public boolean isAudit(LoginUser user, Doc doc) { + // 1分类 + FarmDoctype type = farmRfDoctypeDao.getDocType(doc.getId()); + if (type.getAuditpop().equals("0")) { + // 不需要审核 + return false; + } else { + // 分类有权限 + if (user != null) { + Organization org = userServiceImpl.getUserOrganization(user.getId()); + List pops = farmDocTypeManagerImpl.getTypePops(type.getId()); + for (Doctypepop node : pops) { + if (node.getFuntype().equals("3")) { + if (node.getOid().equals(user.getId())) { + // 该用户又权限访问分类 + return true; + } + if (org.getTreecode().indexOf(node.getOid()) >= 0) { + // 该组织机构又权限访问分类 + return true; + } + } + } + return false; + } else { + return false; + } + } + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocRunInfoImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocRunInfoImpl.java new file mode 100644 index 0000000..7d9fb46 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocRunInfoImpl.java @@ -0,0 +1,765 @@ +package com.farm.doc.server.impl; + +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.authority.FarmAuthorityService; +import com.farm.authority.domain.User; +import com.farm.authority.service.UserServiceInter; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.query.DataQuery.CACHE_UNIT; +import com.farm.core.sql.result.DataResult; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.FarmDocDaoInter; +import com.farm.doc.dao.FarmDocenjoyDaoInter; +import com.farm.doc.dao.FarmDocmessageDaoInter; +import com.farm.doc.dao.FarmDocruninfoDaoInter; +import com.farm.doc.dao.FarmDocruninfoDetailDaoInter; +import com.farm.doc.dao.FarmDoctextDaoInter; +import com.farm.doc.dao.FarmDoctypeDaoInter; +import com.farm.doc.dao.FarmRfDoctextfileDaoInter; +import com.farm.doc.dao.FarmRfDoctypeDaoInter; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDocenjoy; +import com.farm.doc.domain.FarmDocruninfo; +import com.farm.doc.domain.FarmDocruninfoDetail; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.domain.ex.DocBrief; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.doc.server.FarmDocOperateRightInter; +import com.farm.doc.server.FarmDocRunInfoInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.FarmFileManagerInter; +import com.farm.doc.server.commons.DocumentConfig; +import com.farm.doc.util.HtmlUtils; +import com.farm.parameter.FarmParameterService; +import com.farm.util.web.FarmFormatUnits; +import com.farm.util.web.FarmproHotnum; +import com.farm.util.web.WebVisitBuff; + +/** + * @author Administrator + * + */ +@Service +public class FarmDocRunInfoImpl implements FarmDocRunInfoInter { + @Resource + private FarmDocDaoInter farmDocDao; + @Resource + private FarmFileManagerInter farmFileServer; + @Resource + private FarmDoctextDaoInter farmDoctextDao; + @Resource + private FarmRfDoctextfileDaoInter farmRfDoctextfileDao; + @Resource + private FarmRfDoctypeDaoInter farmRfDoctypeDao; + @Resource + private FarmDoctypeDaoInter farmDoctypeDao; + @Resource + private FarmDocmessageDaoInter farmDocmessageDao; + @Resource + private FarmDocruninfoDaoInter farmDocruninfoDao; + @Resource + private FarmDocenjoyDaoInter farmDocenjoyDao; + @Resource + private FarmDocOperateRightInter farmDocOperate; + @Resource + private FarmDocruninfoDetailDaoInter farmDocruninfoDetailDao; + @Resource + private FarmFileManagerInter farmFileManagerImpl; + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + @Resource + private UserServiceInter userServiceImpl; + private final static Logger log = Logger.getLogger(FarmDocRunInfoImpl.class); + + @Override + @Transactional + public void visitDoc(String docId, LoginUser user, String ip) { + WebVisitBuff vbuff = WebVisitBuff.getInstance("KNOW", 1000); + String userId = "noLogin"; + if (user != null) { + userId = user.getId(); + } + if (vbuff.canVisite(docId + ip + userId)) { + DocEntire doc = new DocEntire(farmDocDao.getEntity(docId)); + doc.setRuninfo(farmDocruninfoDao.getEntity(doc.getDoc().getRuninfoid())); + doc.getRuninfo().setVisitnum(doc.getRuninfo().getVisitnum() + 1); + doc.getRuninfo().setHotnum(countHotNum(doc)); + doc.getRuninfo().setLastvtime(TimeTool.getTimeDate12()); + farmDocruninfoDao.editEntity(doc.getRuninfo()); + } + } + + @Override + public DataQuery createReleaseRankingSimpleQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, + "(SELECT A.USERNAME AS USERNAME, A.DOCNUM AS DOCNUM, A.GOODNUM AS GOODNUM, A.BADNUM AS BADNUM," + + " A.VISITNUM AS VISITNUM, A.PRAISEYES AS PRAISEYES, A.PRAISENO AS PRAISENO," + + " TRUNCATE(A.GOODNUM / A.DOCNUM * 100, 0) AS GOODRATE " + "FROM (" + + " SELECT MAX(USER.NAME) AS USERNAME, COUNT(*) AS DOCNUM, " + + " SUM(CASE WHEN DOCRUNINFO.EVALUATE > 0 THEN 1 ELSE 0 END) AS GOODNUM," + + " SUM(CASE WHEN DOCRUNINFO.EVALUATE < 0 THEN 1 ELSE 0 END) AS BADNUM," + + " SUM(DOCRUNINFO.VISITNUM) AS VISITNUM," + " SUM(DOCRUNINFO.PRAISEYES) AS PRAISEYES," + + " SUM(DOCRUNINFO.PRAISENO) AS PRAISENO" + + " FROM (SELECT * FROM FARM_DOC A WHERE A.STATE = '1') DOC " + + " INNER JOIN FARM_DOCRUNINFO DOCRUNINFO ON DOC.RUNINFOID = DOCRUNINFO.ID" + + " LEFT JOIN ALONE_AUTH_USER USER ON DOC.CUSER = USER.ID" + " GROUP BY DOC.CUSER) A )B", + "B.USERNAME AS USERNAME, B.DOCNUM AS DOCNUM, B.GOODNUM AS GOODNUM, B.BADNUM AS BADNUM," + + " B.VISITNUM AS VISITNUM, B.PRAISEYES AS PRAISEYES, B.PRAISENO AS PRAISENO, B.GOODRATE AS GOODRATE"); + return dbQuery; + } + + /** + * 计算文章热度 + * + * @param doc + * @return + */ + private int countHotNum(DocEntire doc) { + int hotnum = FarmproHotnum.getHotnum(doc.getRuninfo().getLastvtime(), doc.getRuninfo().getHotnum(), 1, + Integer.valueOf(DocumentConfig.getString("config.doc.hot.weight"))); + return hotnum; + } + + @Override + @Transactional + public void enjoyDoc(String userId, String docId) { + farmDocenjoyDao.insertEntity(new FarmDocenjoy(docId.trim(), userId.trim())); + } + + @Override + @Transactional + public DataQuery getUserEnjoyDoc(String userId) { + DataQuery query = DataQuery.getInstance("1", + "TITLE,b.ID AS ID,b.PUBTIME as PUBTIME,b.id as DOCID ,c.VISITNUM as VISITNUM,c.HOTNUM as HOTNUM,c.ANSWERINGNUM as ANSWERINGNUM", + "FARM_DOCENJOY a left join FARM_DOC b on a.DOCID=b.ID and b.STATE = '1' left join FARM_DOCRUNINFO c on c.id =b.RUNINFOID"); + query.addRule(new DBRule("a.USERID", userId, "=")); + query.setDistinct(true); + return query; + } + + @Override + @Transactional + public boolean isEnjoyDoc(String userId, String docId) { + List list = new ArrayList(); + list.add(new DBRule("DOCID", docId, "=")); + list.add(new DBRule("USERID", userId, "=")); + return farmDocenjoyDao.selectEntitys(list).size() > 0; + } + + @Override + @Transactional + public List getNewKnowList(int pagesize) { + DataQuery query = DataQuery.getInstance("1", + "a.ID as docid,a.TITLE AS title,a.CUSER as authorid,a.DOCDESCRIBE AS text,DOMTYPE,a.AUTHOR AS AUTHOR,a.PUBTIME AS pubtime,a.IMGID AS imgid,b.VISITNUM AS VISITNUM,b.answeringnum as answeringnum,b.PRAISEYES AS PRAISEYES,b.PRAISENO AS PRAISENO,b.HOTNUM AS HOTNUM,d.NAME AS typename,e.IMGID AS photoid, e.id as userid, e.name as username", + "farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID=b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID LEFT JOIN ALONE_AUTH_USER e ON e.ID=a.CUSER"); + query.addRule(new DBRule("a.READPOP", "1", "=")); + query.addRule(new DBRule("a.STATE", "1", "=")); + query.addRule(new DBRule("d.READPOP", "0", "=")); + query.addSort(new DBSort("a.etime", "desc")); + query.setPagesize(pagesize); + query.setNoCount(); + List result = null; + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + try { + result = query.search().getObjectList(DocBrief.class); + } catch (SQLException e) { + e.printStackTrace(); + } + for (DocBrief node : result) { + node.setPubtime(FarmFormatUnits.getFormateTime(node.getPubtime().toString(), true)); + node.setText(node.getText().toString().replaceAll("<", "").replaceAll(">", "")); + if (node.getPhotoid() != null) { + node.setPhotourl(farmFileManagerImpl.getFileURL(node.getPhotoid())); + } + } + return result; + } + + @Override + @Transactional + public void unEnjoyDoc(String userId, String docId) { + List list = new ArrayList(); + list.add(new DBRule("DOCID", docId, "=")); + list.add(new DBRule("USERID", userId, "=")); + farmDocenjoyDao.deleteEntitys(list); + } + + @Override + public List getDocJoinUserIds(String docid) { + List list = new ArrayList(); + list.add(new DBRule("DOCID", docid, "=")); + List enjoyList = farmDocenjoyDao.selectEntitys(list); + List ids = new ArrayList(); + for (FarmDocenjoy node : enjoyList) { + ids.add(node.getUserid()); + } + return ids; + } + + @Override + @Transactional + public void reCountDocHotNum(String docId) { + DocEntire doc = new DocEntire(farmDocDao.getEntity(docId)); + doc.setRuninfo(farmDocruninfoDao.getEntity(doc.getDoc().getRuninfoid())); + doc.getRuninfo().setHotnum(countHotNum(doc)); + farmDocruninfoDao.editEntity(doc.getRuninfo()); + } + + @Override + @Transactional + public void criticalDoc(String docId, LoginUser user, String IP) { + evaluateDoc(docId, user, IP, "3"); + } + + /** + * 评价一个文档 + * + * @param docId + * 文档id + * @param user + * 当前用户(可空) + * @param IP + * 用户IP + * @param type + * 评价类型(2好评、3差评) + * @return 文档评价值(好评减去差评) + */ + private void evaluateDoc(String docId, LoginUser user, String IP, String type) { + Doc doc = farmDocDao.getEntity(docId); + FarmDocruninfo runinfo = farmDocruninfoDao.getEntity(doc.getRuninfoid()); + // 删除本用户对于该文档的评价(好评、差评) + List list = new ArrayList(); + list.add(new DBRule("RUNINFOID", runinfo.getId(), "=")); + list.add(new DBRule("VTYPE", "2", "=")); + if (user != null) { + list.add(new DBRule("CUSER", user.getId(), "=")); + } else { + list.add(new DBRule("USERIP", IP, "=")); + } + farmDocruninfoDetailDao.deleteEntitys(list); + List list2 = new ArrayList(); + list2.add(new DBRule("RUNINFOID", runinfo.getId(), "=")); + list2.add(new DBRule("VTYPE", "3", "=")); + if (user != null) { + list2.add(new DBRule("CUSER", user.getId(), "=")); + } else { + list2.add(new DBRule("USERIP", IP, "=")); + } + farmDocruninfoDetailDao.deleteEntitys(list2); + // 增加一条好评 + FarmDocruninfoDetail infDetail = new FarmDocruninfoDetail(); + infDetail.setCtime(TimeTool.getTimeDate14()); + if (user != null) { + infDetail.setCuser(user.getId()); + infDetail.setCusername(user.getName()); + } + infDetail.setDoctextid(doc.getTextid()); + infDetail.setPstate("1"); + infDetail.setRuninfoid(runinfo.getId()); + infDetail.setUserip(IP); + // 1访问、2好评、3差评 + infDetail.setVtype(type); + farmDocruninfoDetailDao.insertEntity(infDetail); + } + + @Override + @Transactional + public void criticalDoc(String docId, String IP) { + evaluateDoc(docId, null, IP, "3"); + } + + @Override + @Transactional + public void praiseDoc(String docId, LoginUser user, String IP) { + evaluateDoc(docId, user, IP, "2"); + } + + @Override + @Transactional + public void praiseDoc(String docId, String IP) { + evaluateDoc(docId, null, IP, "2"); + } + + @Override + @Transactional + public FarmDocruninfo loadRunInfo(String docId) { + Doc doc = farmDocDao.getEntity(docId); + FarmDocruninfo runinfo = farmDocruninfoDao.getEntity(doc.getRuninfoid()); + // 更新用量信息(好评、差评、评价) + List listCount1 = new ArrayList(); + listCount1.add(new DBRule("RUNINFOID", runinfo.getId(), "=")); + listCount1.add(new DBRule("VTYPE", "2", "=")); + int good = farmDocruninfoDetailDao.countEntitys(listCount1); + List listCount2 = new ArrayList(); + listCount2.add(new DBRule("RUNINFOID", runinfo.getId(), "=")); + listCount2.add(new DBRule("VTYPE", "3", "=")); + int bad = farmDocruninfoDetailDao.countEntitys(listCount2); + // (2好评、3差评) + runinfo.setPraiseyes(good); + runinfo.setPraiseno(bad); + runinfo.setEvaluate(good - bad); + farmDocruninfoDao.editEntity(runinfo); + return runinfo; + } + + @Override + @Transactional + public List getPubHotDoc(int num) { + List list = null; + DataQuery query = DataQuery.getInstance("1", + "A.ID AS docid,a.DOCDESCRIBE as text,A.AUTHOR AS author, A.TITLE AS TITLE, domtype, B.HOTNUM AS hotnum,b.VISITNUM as VISITNUM,b.ANSWERINGNUM as ANSWERINGNUM", + "farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID = b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID "); + query.addRule(new DBRule("a.READPOP", "1", "=")); + query.addSort(new DBSort("b.HOTNUM", "desc")); + query.addRule(new DBRule("d.READPOP", "0", "=")); + query.setNoCount(); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + query.setPagesize(num); + try { + list = query.search().getObjectList(DocBrief.class); + for (DocBrief node : list) { + node.setText(HtmlUtils.HtmlRemoveTag(node.getText())); + node.setText(("" + node.getText()).length() > 50 ? ("" + node.getText()).substring(0, 50) + "..." + : node.getText()); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return list; + } + + @Override + @Transactional + public List getTypeDocs(String typeid, String userid, int num) { + FarmDoctype doctype = farmDoctypeDao.getEntity(typeid); + DataQuery query = new DataQuery(); + query = DataQuery.init(query, + "farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID=b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID", + "a.ID as DOCID,a.TITLE AS title,a.DOCDESCRIBE AS DOCDESCRIBE,a.AUTHOR AS AUTHOR,a.PUBTIME AS PUBTIME,a.TAGKEY AS TAGKEY ,a.IMGID AS IMGID,b.VISITNUM AS VISITNUM,b.PRAISEYES AS PRAISEYES,b.PRAISENO AS PRAISENO,b.HOTNUM AS HOTNUM,b.EVALUATE as EVALUATE,b.ANSWERINGNUM as ANSWERINGNUM,d.NAME AS TYPENAME"); + query.addSort(new DBSort("a.etime", "desc")); + query.addRule(new DBRule("a.STATE", "1", "=")); + query.addRule(new DBRule("d.TREECODE", doctype.getTreecode(), "like-")) + // 文章三种情况判断 + // 1.文章阅读权限为公共 + // 2.文章的创建者为当前登录用户 + // 3.文章的阅读权限为小组,并且当前登陆用户为组内成员.(使用子查询处理) + .addSqlRule("and (a.READPOP='1' or a.CUSER='" + userid + + "' OR (a.READPOP = '2' AND 0 < (SELECT e.ID FROM farm_docgroup_user e WHERE e.PSTATE = 1 AND e.GROUPID = a.DOCGROUPID AND e.CUSER = '" + + userid + "')))"); + query.setPagesize(num); + List list = null; + try { + list = query.search().getObjectList(DocBrief.class); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList(); + } + return list; + } + + @Override + public List getPubTopDoc(int num) { + // 获取前五条置顶文档 + DataResult result = null; + List list = null; + try { + DataQuery query = new DataQuery(); + query.setPagesize(num); + query.addSort(new DBSort("TOP.SORT", "asc")); + query = DataQuery.init(query, "FARM_TOP TOP " + "LEFT JOIN FARM_DOC A ON TOP.DOCID = A.ID and a.STATE='1' " + + "LEFT JOIN FARM_RF_DOCTYPE B ON B.DOCID =A.ID " + "LEFT JOIN FARM_DOCTYPE C ON C.ID=B.TYPEID " + + "LEFT JOIN FARM_DOCGROUP D ON D.ID=A.DOCGROUPID " + + "LEFT JOIN FARM_DOCRUNINFO DOCRUNINFO ON A.RUNINFOID = DOCRUNINFO.ID", + "TOP.ID AS ID, TOP.SORT AS SORT, A.DOCDESCRIBE AS text,A.WRITEPOP AS WRITEPOP," + + "A.READPOP AS READPOP,A.TITLE AS TITLE,A.AUTHOR AS AUTHOR,A.PUBTIME AS PUBTIME," + + "A.DOMTYPE AS DOMTYPE,A.SHORTTITLE AS SHORTTITLE,A.TAGKEY AS TAGKEY,A.STATE AS STATE," + + "D.GROUPNAME AS GROUPNAME, DOCRUNINFO.VISITNUM AS VISITNUM, DOCRUNINFO.ANSWERINGNUM AS ANSWERINGNUM, " + + "A.IMGID AS IMGID, A.ID AS docid,a.cuser as authorid"); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + result = query.search(); + result.runDictionary("1:开放,0:禁用,2:待审核", "STATE"); + result.runDictionary("1:HTML,2:TXT", "DOMTYPE"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "WRITEPOP"); + result.runDictionary("1:分类,0:本人,2:小组,3:禁止", "READPOP"); + result.runformatTime("PUBTIME", "yyyy-MM-dd HH:mm:ss"); + list = result.getObjectList(DocBrief.class); + for (DocBrief node : list) { + if (node.getImgid() != null) { + node.setImgurl(farmFileManagerImpl.getFileURL(node.getImgid())); + } + } + } catch (SQLException e) { + log.error(e.toString()); + list = new ArrayList(); + } + return list; + } + + @Override + public DataResult getStatGoodUsers(int i) { + try { + DataQuery query = new DataQuery(); + query.setPagesize(i); + query = DataQuery.init(query, + "( SELECT d.ID AS ID,d.NAME AS NAME,SUM(b.PRAISEYES) AS SUMYES FROM FARM_DOC a LEFT JOIN FARM_DOCRUNINFO b ON a.RUNINFOID = b.ID LEFT JOIN ALONE_AUTH_USER d ON a.CUSER = d.ID where a.STATE='1' GROUP BY d.ID,d.NAME ) g", + "ID,NAME,SUMYES"); + query.addSort(new DBSort("g.SUMYES", "DESC")); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + return query.search(); + } catch (Exception e) { + return DataResult.getInstance(); + } + } + + @Override + public DataResult getStatGoodGroups(int i) { + try { + DataQuery query = new DataQuery(); + query.setPagesize(i); + query = DataQuery.init(query, + "( SELECT d.ID AS ID, d.GROUPNAME AS NAME,d.JOINCHECK as JOINCHECK, SUM(b.PRAISEYES) AS SUMYES FROM FARM_DOC a LEFT JOIN FARM_DOCRUNINFO b ON a.RUNINFOID = b.ID LEFT JOIN FARM_DOCGROUP d ON d.id=a.DOCGROUPID WHERE a.STATE='1' and d.ID IS NOT NULL GROUP BY d.ID,d.GROUPNAME,d.JOINCHECK) g", + "ID,NAME,SUMYES,JOINCHECK"); + query.addSort(new DBSort("g.SUMYES", "DESC")); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + return query.search(); + } catch (Exception e) { + return DataResult.getInstance(); + } + } + + @Override + public DataResult getStatMostUsers(int i) { + try { + DataQuery query = new DataQuery(); + query.setPagesize(i); + query = DataQuery.init(query, + "( SELECT b.ID AS ID, b.name AS NAME, COUNT(*) AS NUM FROM FARM_DOC a LEFT JOIN ALONE_AUTH_USER b ON a.CUSER = b.ID where a.STATE='1' GROUP BY b.id,b.NAME) g", + "ID,NAME,NUM"); + query.addSort(new DBSort("NUM", "DESC")); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + return query.search(); + } catch (Exception e) { + return DataResult.getInstance(); + } + } + + @Override + public DataResult getStatGoodDocs(int i) { + try { + DataQuery query = new DataQuery(); + query.setPagesize(i); + query = DataQuery.init(query, + "FARM_DOC a LEFT JOIN FARM_DOCRUNINFO b ON a.RUNINFOID=b.ID LEFT JOIN FARM_DOCGROUP c ON a.DOCGROUPID=c.ID LEFT JOIN ALONE_AUTH_USER d ON a.CUSER=d.ID", + "a.title AS title,a.id AS id,c.JOINCHECK AS JOINCHECK,b.EVALUATE AS EVALUATE,c.GROUPIMG AS GROUPIMG,d.IMGID AS PHOTOID,d.NAME AS USERNAME,c.GROUPNAME AS GROUPNAME,a.DOCGROUPID AS GROUPID"); + query.addSort(new DBSort("b.EVALUATE", "DESC")); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + return query.search(); + } catch (Exception e) { + return DataResult.getInstance(); + } + } + + @Override + public DataResult getStatBadDocs(int i) { + try { + DataQuery query = new DataQuery(); + query.setPagesize(i); + query = DataQuery.init(query, + "FARM_DOC a LEFT JOIN FARM_DOCRUNINFO b ON a.RUNINFOID=b.ID LEFT JOIN FARM_DOCGROUP c ON a.DOCGROUPID=c.ID LEFT JOIN ALONE_AUTH_USER d ON a.CUSER=d.ID", + "a.title AS title,a.id AS id,c.JOINCHECK AS JOINCHECK,b.EVALUATE AS EVALUATE,c.GROUPIMG AS GROUPIMG,d.IMGID AS PHOTOID,d.NAME AS USERNAME,c.GROUPNAME AS GROUPNAME,a.DOCGROUPID AS GROUPID"); + query.addSort(new DBSort("b.EVALUATE", "ASC")); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + return query.search(); + } catch (Exception e) { + return DataResult.getInstance(); + } + } + + @Override + public Map getStatNumForDay() throws Exception { + Map map = new HashMap<>(); + DataQuery query = new DataQuery(); + query = DataQuery.init(query, + "(SELECT COUNT(id) AS num,LEFT(ctime,8) AS DATE FROM farm_doc GROUP BY DATE) AS a", "NUM,DATE"); + query.setPagesize(10000); + query.addSort(new DBSort("DATE", "ASC")); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.minute); + DataResult result = query.search(); + DataQuery queryGood = DataQuery.init(query, + "(SELECT COUNT(a.id) AS num,LEFT(a.ctime,8) AS DATE FROM farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID=b.ID WHERE b.EVALUATE>0 GROUP BY DATE) AS a", + "NUM,DATE"); + queryGood.setPagesize(10000); + queryGood.addSort(new DBSort("DATE", "ASC")); + DataResult resultGood = queryGood.search(); + DataQuery queryBad = DataQuery.init(query, + "(SELECT COUNT(a.id) AS num,LEFT(a.ctime,8) AS DATE FROM farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID=b.ID WHERE b.EVALUATE<0 GROUP BY DATE) AS a", + "NUM,DATE"); + queryBad.setPagesize(10000); + queryBad.addSort(new DBSort("DATE", "ASC")); + DataResult resultBad = queryBad.search(); + List> jsonResultDayNum = new ArrayList>(); + List> jsonResultTotalNum = new ArrayList>(); + List> jsonResultTotalGoodNum = new ArrayList>(); + List> jsonResultTotalBadNum = new ArrayList>(); + for (Map node : result.getResultList()) { + List nodeList = new ArrayList(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + nodeList.add(Long.valueOf(sdf.parse(node.get("DATE").toString()).getTime())); + nodeList.add(Float.valueOf(node.get("NUM").toString())); + jsonResultDayNum.add(nodeList); + } + Float TotalNum = Float.valueOf(0); + for (Map node : result.getResultList()) { + List nodeList = new ArrayList(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + nodeList.add(Long.valueOf(sdf.parse(node.get("DATE").toString()).getTime())); + TotalNum = TotalNum + Float.valueOf(node.get("NUM").toString()); + nodeList.add(TotalNum); + jsonResultTotalNum.add(nodeList); + } + Float TotalGoodNum = Float.valueOf(0); + for (Map node : resultGood.getResultList()) { + List nodeList = new ArrayList(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + nodeList.add(Long.valueOf(sdf.parse(node.get("DATE").toString()).getTime())); + TotalGoodNum = TotalGoodNum + Float.valueOf(node.get("NUM").toString()); + nodeList.add(TotalGoodNum); + jsonResultTotalGoodNum.add(nodeList); + } + Float TotalBadNum = Float.valueOf(0); + for (Map node : resultBad.getResultList()) { + List nodeList = new ArrayList(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + nodeList.add(Long.valueOf(sdf.parse(node.get("DATE").toString()).getTime())); + TotalBadNum = TotalBadNum + Float.valueOf(node.get("NUM").toString()); + nodeList.add(TotalBadNum); + jsonResultTotalBadNum.add(nodeList); + } + map.put("DayNum", jsonResultDayNum); + map.put("TotalNum", jsonResultTotalNum); + map.put("GoodNum", jsonResultTotalGoodNum); + map.put("BadNum", jsonResultTotalBadNum); + return map; + } + + @Override + public DataResult getStatUser(User user) { + try { + DataQuery query = new DataQuery(); + StringBuffer sql = new StringBuffer(); + sql.append( + "SELECT a.NAME AS NAME,a.ID AS ID,a.ctime AS ctime,(SELECT COUNT(*) FROM FARM_DOC WHERE cuser=a.ID and STATE='1') num,(SELECT MIN(ctime) FROM FARM_DOC WHERE cuser=a.ID) stime,(SELECT MAX(ctime) FROM FARM_DOC WHERE cuser=a.ID) etime,"); + sql.append( + "(SELECT SUM(pb.PRAISEYES) FROM FARM_DOC pa LEFT JOIN FARM_DOCRUNINFO pb ON pb.id=pa.RUNINFOID WHERE cuser=a.ID and pa.STATE='1') AS OKNUM,"); + sql.append( + "(SELECT SUM(pb.PRAISENO) FROM FARM_DOC pa LEFT JOIN FARM_DOCRUNINFO pb ON pb.id=pa.RUNINFOID WHERE cuser=a.ID and pa.STATE='1') AS NONUM,"); + sql.append( + "(SELECT SUM(pb.EVALUATE) FROM FARM_DOC pa LEFT JOIN FARM_DOCRUNINFO pb ON pb.id=pa.RUNINFOID WHERE cuser=a.ID and pa.STATE='1') AS EVANUM,"); + sql.append( + "(SELECT SUM(pb.VISITNUM) FROM FARM_DOC pa LEFT JOIN FARM_DOCRUNINFO pb ON pb.id=pa.RUNINFOID WHERE cuser=a.ID and pa.STATE='1') AS VINUM,"); + sql.append( + "(SELECT COUNT(*) FROM FARM_DOC pa LEFT JOIN FARM_DOCRUNINFO pb ON pb.id=pa.RUNINFOID WHERE cuser=a.ID AND pb.EVALUATE>0 and pa.STATE='1') AS GOODNUM,"); + sql.append( + "(SELECT COUNT(*) FROM FARM_DOC pa LEFT JOIN FARM_DOCRUNINFO pb ON pb.id=pa.RUNINFOID WHERE cuser=a.ID AND pb.EVALUATE<0 and pa.STATE='1') AS BADNUM"); + sql.append(" FROM ALONE_AUTH_USER a WHERE a.ID='" + user.getId() + "'"); + query.setPagesize(10); + query = DataQuery.init(query, "(" + sql.toString() + ") g", + "ID,NAME,NUM,OKNUM,NONUM,EVANUM,VINUM,GOODNUM,BADNUM,STIME,ETIME,CTIME"); + query.setNoCount(); + + // query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + // CACHE_UNIT.second);//修改用户信息后,这里取到的是缓存数据。 + DataResult result = query.search(); + if (result.getResultList().get(0).get("EVANUM") == null) { + result.getResultList().get(0).put("EVANUM", 0); + } + if (result.getResultList().get(0).get("VINUM") == null) { + result.getResultList().get(0).put("VINUM", 0); + } + if (result.getResultList().get(0).get("OKNUM") == null) { + result.getResultList().get(0).put("OKNUM", 0); + } + if (result.getResultList().get(0).get("NONUM") == null) { + result.getResultList().get(0).put("NONUM", 0); + } + float eva = new Float(result.getResultList().get(0).get("EVANUM").toString()); + if (eva < 0) { + eva = 0;// 该等级值不能为负数 + } + float startRight = 5; + int L4 = (int) Math.floor(eva / (startRight * startRight * startRight));// 125 + float L4m = eva % (startRight * startRight * startRight); + int L3 = (int) Math.floor(L4m / (startRight * startRight));// 25 + float L3m = L4m % (startRight * startRight);// 25 + int L2 = (int) Math.floor(L3m / startRight);// 5 + float L2m = L3m % startRight;// 5 + int L1 = (int) Math.floor(L2m);// 1 + result.getResultList().get(0).put("L4", L4); + result.getResultList().get(0).put("L3", L3); + result.getResultList().get(0).put("L2", L2); + result.getResultList().get(0).put("L1", L1); + return result; + } catch (Exception e) { + return DataResult.getInstance(); + } + } + + @Override + public DataResult userDocs(String userid, String domtype, int pagesize, int pagenum) { + DataQuery query = DataQuery.getInstance(pagenum, + "a.ID as docid,a.TITLE AS title,a.CUSER as authorid,a.DOCDESCRIBE AS text,DOMTYPE,a.AUTHOR AS AUTHOR,a.PUBTIME AS pubtime,a.IMGID AS imgid,b.VISITNUM AS VISITNUM,b.answeringnum as answeringnum,b.PRAISEYES AS PRAISEYES,b.PRAISENO AS PRAISENO,b.HOTNUM AS HOTNUM,d.NAME AS typename,e.IMGID AS photoid, e.id as userid, e.name as username", + "farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID=b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID LEFT JOIN ALONE_AUTH_USER e ON e.ID=a.CUSER"); + query.addRule(new DBRule("a.STATE", "1", "=")); + query.addRule(new DBRule("a.domtype", domtype, "=")); + query.addRule(new DBRule("a.CUSER", userid, "=")); + query.addSort(new DBSort("a.etime", "desc")); + query.setPagesize(pagesize); + DataResult result = null; + try { + result = query.search(); + } catch (SQLException e) { + e.printStackTrace(); + } + for (Map node : result.getResultList()) { + node.put("PUBTIME", FarmFormatUnits.getFormateTime(node.get("PUBTIME").toString(), true)); + node.put("TEXT", node.get("TEXT").toString().replaceAll("<", "").replaceAll(">", "")); + if (node.get("PHOTOID") != null) { + node.put("PHOTOID", farmFileManagerImpl.getFileURL(node.get("PHOTOID").toString())); + } + } + return result; + } + + @Override + public DataResult userPubDocs(String userid, String domtype, int pagesize, int pagenum) { + DataQuery query = DataQuery.getInstance(pagenum, + "a.ID as docid,a.TITLE AS title,a.CUSER as authorid,a.DOCDESCRIBE AS text,DOMTYPE,a.AUTHOR AS AUTHOR,a.PUBTIME AS pubtime,a.IMGID AS imgid,b.VISITNUM AS VISITNUM,b.answeringnum as answeringnum,b.PRAISEYES AS PRAISEYES,b.PRAISENO AS PRAISENO,b.HOTNUM AS HOTNUM,d.NAME AS typename,e.IMGID AS photoid, e.id as userid, e.name as username", + "farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID=b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID LEFT JOIN ALONE_AUTH_USER e ON e.ID=a.CUSER"); + query.addRule(new DBRule("a.READPOP", "1", "=")); + query.addRule(new DBRule("a.STATE", "1", "=")); + query.addRule(new DBRule("a.domtype", domtype, "=")); + query.addRule(new DBRule("a.CUSER", userid, "=")); + query.addSort(new DBSort("a.etime", "desc")); + query.setPagesize(pagesize); + DataResult result = null; + try { + result = query.search(); + } catch (SQLException e) { + e.printStackTrace(); + } + for (Map node : result.getResultList()) { + node.put("PUBTIME", FarmFormatUnits.getFormateTime(node.get("PUBTIME").toString(), true)); + node.put("TEXT", node.get("TEXT").toString().replaceAll("<", "").replaceAll(">", "")); + if (node.get("PHOTOID") != null) { + node.put("PHOTOID", farmFileManagerImpl.getFileURL(node.get("PHOTOID").toString())); + } + } + return result; + } + + @Override + public DataResult getMyAuditingByUser(String userid, int pagesize, int pagenum) { + DataQuery query = DataQuery.getInstance(pagenum, + "a.ID as docid,b.id as AUDITID,b.PCONTENT as AUDITCONTENT,d.NAME AS typename,a.TITLE AS title,b.PSTATE as STATE,a.CUSER as authorid,a.DOCDESCRIBE AS text,DOMTYPE,f.PCONTENT as CONTENT,a.AUTHOR AS AUTHOR,a.PUBTIME AS pubtime,a.IMGID AS imgid", + "FARM_DOC_AUDIT b left join FARM_DOC a on a.id=b.DOCID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID left join FARM_DOCTEXT f on f.id=b.TEXTID"); + query.addRule(new DBRule("b.PSTATE", "1", "=")); + query.addRule(new DBRule("a.CUSER", userid, "=")); + query.addSort(new DBSort("b.etime", "desc")); + query.setPagesize(pagesize); + DataResult result = null; + try { + result = query.search(); + } catch (SQLException e) { + e.printStackTrace(); + } + return result; + } + + @Override + public DataResult getAuditDocByUser(String userid, int pagesize, int pagenum) { + // 先查出该用户所有拥有的审核权限的分类 + // 在用这些分类id去查询分类下的待审核的知识 + List types = farmDocTypeManagerImpl.getUserAuditTypeIds(userid); + String typeids = null; + for (String node : types) { + if (typeids == null) { + typeids = "'" + node + "'"; + } else { + typeids = typeids + ",'" + node + "'"; + } + } + DataQuery query = DataQuery.getInstance(pagenum, + "a.ID as docid,b.id as AUDITID,b.PCONTENT as AUDITCONTENT,d.NAME AS typename,a.TITLE AS title,b.PSTATE as STATE,a.CUSER as authorid,a.DOCDESCRIBE AS text,DOMTYPE,f.PCONTENT as CONTENT,a.AUTHOR AS AUTHOR,a.PUBTIME AS pubtime,a.IMGID AS imgid", + "FARM_DOC_AUDIT b left join FARM_DOC a on a.id=b.DOCID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID left join FARM_DOCTEXT f on f.id=b.TEXTID"); + query.addRule(new DBRule("b.PSTATE", "1", "=")); + if (typeids != null) { + query.addSqlRule(" and d.id in(" + typeids + ")"); + } else { + query.addSqlRule(" and 1=2"); + } + query.addSort(new DBSort("a.etime", "desc")); + query.setPagesize(pagesize); + DataResult result = null; + try { + result = query.search(); + } catch (SQLException e) { + e.printStackTrace(); + } + return result; + } + + @Override + public DataResult getMyAuditedByUser(String userid, int pagesize, int pagenum) { + DataQuery query = DataQuery.getInstance(pagenum, + "a.ID as docid,b.id as AUDITID,b.etime as ETIME,b.PCONTENT as AUDITCONTENT,d.NAME AS typename,a.TITLE AS title,b.PSTATE as STATE,a.CUSER as authorid,a.DOCDESCRIBE AS text,DOMTYPE,f.PCONTENT as CONTENT,a.AUTHOR AS AUTHOR,a.PUBTIME AS pubtime,a.IMGID AS imgid", + "FARM_DOC_AUDIT b left join FARM_DOC a on a.id=b.DOCID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID left join FARM_DOCTEXT f on f.id=b.TEXTID"); + query.addSqlRule(" and (b.PSTATE='2' or b.PSTATE='3')"); + query.addRule(new DBRule("a.CUSER", userid, "=")); + query.addSort(new DBSort("b.etime", "desc")); + query.setPagesize(pagesize); + DataResult result = null; + try { + result = query.search(); + } catch (SQLException e) { + e.printStackTrace(); + } + return result; + } + + @Override + @Transactional + public Map getStatNum() throws Exception { + // 知识总数、总人数、好评文档数、差评文档数、分类数量 + Map map = new HashMap<>(); + map.put("KNOWNUM", farmDocruninfoDao.getKnowsNum()); + map.put("USERNUM", userServiceImpl.getUsersNum()); + map.put("GOODKNOWNUM", farmDocruninfoDao.getGoodKnowsNum()); + map.put("BADKNOWNUM", farmDocruninfoDao.getBadKnowsNum()); + map.put("TYPESNUM", farmDoctypeDao.getTypesNum()); + return map; + } +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocTypeManagerImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocTypeManagerImpl.java new file mode 100644 index 0000000..06d2196 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocTypeManagerImpl.java @@ -0,0 +1,584 @@ +package com.farm.doc.server.impl; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Resource; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.authority.domain.Organization; +import com.farm.authority.service.OrganizationServiceInter; +import com.farm.authority.service.UserServiceInter; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.query.DataQuery.CACHE_UNIT; +import com.farm.core.sql.result.DataResult; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.FarmDocDaoInter; +import com.farm.doc.dao.FarmDocenjoyDaoInter; +import com.farm.doc.dao.FarmDocfileDaoInter; +import com.farm.doc.dao.FarmDocgroupDaoInter; +import com.farm.doc.dao.FarmDocmessageDaoInter; +import com.farm.doc.dao.FarmDocruninfoDaoInter; +import com.farm.doc.dao.FarmDocruninfoDetailDaoInter; +import com.farm.doc.dao.FarmDoctextDaoInter; +import com.farm.doc.dao.FarmDoctypeDaoInter; +import com.farm.doc.dao.FarmRfDoctextfileDaoInter; +import com.farm.doc.dao.FarmRfDoctypeDaoInter; +import com.farm.doc.dao.FarmtopDaoInter; +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.domain.ex.TypeBrief; +import com.farm.doc.server.FarmDocOperateRightInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.FarmFileManagerInter; +import com.farm.doc.server.plus.FarmTypePopServerInter; +import com.farm.doc.server.plus.domain.Doctypepop; +import com.farm.parameter.FarmParameterService; + +/** + * 文档分类管理 + * + * @author MAC_wd + */ +@Service +public class FarmDocTypeManagerImpl implements FarmDocTypeInter { + @Resource + private FarmDocDaoInter farmDocDao; + @Resource + private FarmDocfileDaoInter farmDocfileDao; + @Resource + private FarmDoctextDaoInter farmDoctextDao; + @Resource + private FarmRfDoctextfileDaoInter farmRfDoctextfileDao; + @Resource + private FarmRfDoctypeDaoInter farmRfDoctypeDao; + @Resource + private FarmDoctypeDaoInter farmDoctypeDao; + @Resource + private FarmDocmessageDaoInter farmDocmessageDao; + @Resource + private FarmDocruninfoDaoInter farmDocruninfoDao; + @Resource + private FarmDocenjoyDaoInter farmDocenjoyDao; + @Resource + private FarmDocOperateRightInter farmDocOperate; + @Resource + private FarmDocgroupDaoInter farmDocgroupDao; + @Resource + private FarmDocruninfoDetailDaoInter farmDocruninfoDetailDao; + @Resource + private FarmFileManagerInter farmFileServer; + @Resource + private FarmtopDaoInter farmtopDaoImpl; + @Resource + private OrganizationServiceInter organizationServiceImpl; + @Resource + private FarmTypePopServerInter farmTypePopServerImpl; + @Resource + private UserServiceInter userServiceImpl; + private static final Logger log = Logger.getLogger(FarmDocTypeManagerImpl.class); + + @Transactional + public FarmDoctype insertType(FarmDoctype entity, LoginUser user) { + entity.setCtime(TimeTool.getTimeDate14()); + entity.setEtime(TimeTool.getTimeDate14()); + entity.setCuser(user.getId()); + entity.setEuser(user.getId()); + entity.setCusername(user.getName()); + entity.setEusername(user.getName()); + entity.setReadpop("0"); + entity.setWritepop("0"); + entity.setAuditpop("0"); + if (entity.getParentid() == null || entity.getParentid().trim().length() <= 0) { + entity.setParentid("NONE"); + } + entity.setTreecode("NONE"); + entity = farmDoctypeDao.insertEntity(entity); + if (entity.getParentid().equals("NONE")) { + entity.setTreecode(entity.getId()); + } else { + entity.setTreecode(farmDoctypeDao.getEntity(entity.getParentid()).getTreecode() + entity.getId()); + } + return farmDoctypeDao.insertEntity(entity); + } + + @Transactional + public FarmDoctype editType(FarmDoctype entity, LoginUser user) { + FarmDoctype entity2 = farmDoctypeDao.getEntity(entity.getId()); + entity2.setEtime(TimeTool.getTimeDate14()); + entity2.setEuser(user.getId()); + entity2.setEusername(user.getName()); + entity2.setName(entity.getName()); + entity2.setTypemod(entity.getTypemod()); + entity2.setContentmod(entity.getContentmod()); + entity2.setSort(entity.getSort()); + entity2.setTags(entity.getTags()); + entity2.setType(entity.getType()); + entity2.setMetatitle(entity.getMetatitle()); + entity2.setMetakey(entity.getMetakey()); + entity2.setMetacontent(entity.getMetacontent()); + entity2.setLinkurl(entity.getLinkurl()); + entity2.setPcontent(entity.getPcontent()); + entity2.setPstate(entity.getPstate()); + farmDoctypeDao.editEntity(entity2); + return entity2; + } + + @Transactional + public void deleteType(String typeId, LoginUser user) { + // 删除分类中间表 + List rulesDelType = new ArrayList(); + rulesDelType.add(new DBRule("TYPEID", typeId, "=")); + farmRfDoctypeDao.deleteEntitys(rulesDelType); + farmTypePopServerImpl.delTypePop(typeId); + farmDoctypeDao.deleteEntity(farmDoctypeDao.getEntity(typeId)); + } + + @Transactional + public FarmDoctype getType(String id) { + if (id == null) { + return null; + } + return farmDoctypeDao.getEntity(id); + } + + @Override + @Transactional + public List getTypeAllParent(String typeid) { + String id = typeid; + List types = new ArrayList(); + while (id != null) { + FarmDoctype centity = farmDoctypeDao.getEntity(id); + if (centity == null || centity.getParentid() == null || centity.getParentid().trim().length() <= 0) { + id = null; + } else { + id = centity.getParentid(); + + } + if (centity != null) { + types.add(centity); + } + } + Collections.reverse(types); + return types; + } + + @Override + @Transactional + public List getTypeInfos(LoginUser user, String parentId) { + DataQuery query = null; + query = DataQuery.init(query, + "(SELECT a.NAME as NAME,a.readpop as READPOP,a.WRITEPOP as WRITEPOP, a.ID as ID, a.PARENTID as PARENTID, (SELECT COUNT(B1.ID) FROM FARM_DOC B1 LEFT JOIN FARM_RF_DOCTYPE B2 ON B1.ID = B2.DOCID LEFT JOIN FARM_DOCTYPE B3 ON B3.ID = B2.TYPEID WHERE B1.STATE='1' and B3.TREECODE LIKE CONCAT(A.TREECODE,'%') AND B1.STATE='1') AS NUM FROM farm_doctype AS a LEFT JOIN farm_doctype AS b ON b.ID = a.PARENTID WHERE 1 = 1 AND (a.TYPE = '1' OR a.TYPE = '3') AND a.PSTATE = '1' and (a.PARENTID='" + + parentId + "' or b.PARENTID='" + parentId + "') ORDER BY a.SORT ASC) AS e", + "NAME,ID,PARENTID,NUM,READPOP,WRITEPOP"); + query.setDistinct(true); + { + // 加载分类权限 + String typeids = null; + for (String id : getUserReadTypeIds(user)) { + if (typeids == null) { + typeids = "'" + id + "'"; + } else { + typeids = typeids + "," + "'" + id + "'"; + } + } + if (user != null) { + query.addSqlRule("and (READPOP='0' or (READPOP!='0' and ID in (" + typeids + ")))"); + } else { + query.addSqlRule("and READPOP='0'"); + } + } + query.setPagesize(1000); + query.setNoCount(); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + try { + return query.search().getObjectList(TypeBrief.class); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList(); + } + } + + @Override + @Transactional + public DataResult getTypeDocs(LoginUser user, String typeid, int pagesize, int currentPage) { + String userid = (user == null ? "none" : user.getId()); + String typeids = null; + for (String id : getUserReadTypeIds(user)) { + if (typeids == null) { + typeids = "'" + id + "'"; + } else { + typeids = typeids + "," + "'" + id + "'"; + } + } + FarmDoctype type = getType(typeid); + DataQuery query = DataQuery.init(new DataQuery(), + "farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID=b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID=a.ID LEFT JOIN farm_doctype d ON d.ID=c.TYPEID LEFT JOIN ALONE_AUTH_USER e ON e.ID = a.CUSER", + "a.ID as DOCID,a.DOMTYPE as DOMTYPE,a.TITLE AS title,a.DOCDESCRIBE AS DOCDESCRIBE,a.AUTHOR AS AUTHOR,a.PUBTIME AS PUBTIME,a.TAGKEY AS TAGKEY ,a.IMGID AS IMGID,b.VISITNUM AS VISITNUM,b.PRAISEYES AS PRAISEYES,b.PRAISENO AS PRAISENO,b.HOTNUM AS HOTNUM,b.EVALUATE as EVALUATE,b.ANSWERINGNUM as ANSWERINGNUM,d.id as TYPEID,d.NAME AS TYPENAME, e.ID as USERID, e.NAME as USERNAME, e.IMGID as USERIMGID"); + query.addSort(new DBSort("a.etime", "desc")); + query.setCurrentPage(currentPage); + query.addRule(new DBRule("a.STATE", "1", "=")); + query.addRule(new DBRule("DOMTYPE", "4", "!=")); + if (type != null) { + query.addRule(new DBRule("d.TREECODE", type.getTreecode(), "like-")); + } + if (user != null) { + query.addSqlRule("and (d.READPOP='0' or (d.READPOP!='0' and d.id in (" + typeids + ")))"); + } else { + query.addSqlRule("and d.READPOP='0'"); + } + // 文章三种情况判断 + // 1.文章阅读权限为公共 + // 2.文章的创建者为当前登录用户 + // 3.文章的阅读权限为小组,并且当前登陆用户为组内成员.(使用子查询处理) + query.addSqlRule("and (a.READPOP='1' or a.CUSER='" + userid + + "' OR (a.READPOP = '2' AND 0 < (SELECT count(e.ID) FROM farm_docgroup_user e WHERE e.PSTATE = 1 AND e.GROUPID = a.DOCGROUPID AND e.CUSER = '" + + userid + "')))"); + query.setPagesize(pagesize); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + DataResult docs = null; + try { + docs = query.search(); + } catch (SQLException e) { + log.error(e.toString()); + return DataResult.getInstance(); + } + for (Map map : docs.getResultList()) { + if (map.get("USERIMGID") != null && !map.get("USERIMGID").toString().isEmpty()) { + map.put("PHOTOURL", farmFileServer.getFileURL(map.get("USERIMGID").toString())); + } else { + map.put("PHOTOURL", farmFileServer.getFileURL("NONE")); + } + } + return docs; + } + + @Override + public List getTypePops(String typeid) { + List doctypepops = new ArrayList<>(); + for (FarmDoctype type : getTypeAllParent(typeid)) { + farmTypePopServerImpl.getTypePopsHandle(doctypepops, type.getReadpop(), type.getWritepop(), + type.getAuditpop(), type.getId()); + } + return doctypepops; + } + + @Override + @Transactional + public List getAllSubNode(String typeid) { + DataQuery query = DataQuery.getInstance(1, + "NAME,TYPEMOD,CONTENTMOD,SORT,TYPE,METATITLE,METAKEY,METACONTENT,LINKURL,ID,TAGS,CTIME,ETIME,CUSERNAME,CUSER,EUSERNAME,EUSER,PCONTENT,PSTATE,PARENTID,TREECODE,READPOP,WRITEPOP,AUDITPOP", + "FARM_DOCTYPE"); + query.addRule(new DBRule("TREECODE", farmDoctypeDao.getEntity(typeid).getTreecode(), "like-")); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + try { + return query.search().getObjectList(FarmDoctype.class); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + @Override + @Transactional + public List getPubTypes() { + DataQuery query = DataQuery.init(new DataQuery(), + "(SELECT a.NAME as NAME, a.ID as ID, a.PARENTID as PARENTID, (SELECT COUNT(B1.ID) FROM FARM_DOC B1 LEFT JOIN FARM_RF_DOCTYPE B2 ON B1.ID = B2.DOCID LEFT JOIN FARM_DOCTYPE B3 ON B3.ID = B2.TYPEID WHERE B1.STATE='1' and B3.TREECODE LIKE CONCAT(A.TREECODE,'%') AND B1.STATE='1') AS NUM FROM farm_doctype AS a WHERE 1 = 1 AND (TYPE = '1' OR TYPE = '3') AND PSTATE = '1' ORDER BY SORT ASC) AS e", + "NAME,ID,PARENTID,NUM"); + query.setPagesize(1000); + query.setNoCount(); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + try { + return query.search().getObjectList(TypeBrief.class); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList(); + } + } + + @Override + @Transactional + public List getTypes() { + DataQuery query = DataQuery.init(new DataQuery(), "FARM_DOCTYPE", + "ID,NAME,TYPE,PARENTID,READPOP,WRITEPOP,AUDITPOP"); + query.setPagesize(1000); + query.setNoCount(); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.immediately")), + CACHE_UNIT.second); + try { + return query.search().getObjectList(TypeBrief.class); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList(); + } + } + + @Override + public List getPopTypesForReadDoc(LoginUser user) { + DataQuery query = DataQuery.init(new DataQuery(), + "(SELECT a.NAME as NAME,a.SORT as SORT, a.ID as ID, a.READPOP as READPOP,a.WRITEPOP AS WRITEPOP, a.AUDITPOP AS AUDITPOP, a.PARENTID AS PARENTID, (SELECT COUNT(B1.ID) FROM FARM_DOC B1 LEFT JOIN FARM_RF_DOCTYPE B2 ON B1.ID = B2.DOCID LEFT JOIN FARM_DOCTYPE B3 ON B3.ID = B2.TYPEID WHERE B1.STATE='1' and B3.TREECODE LIKE CONCAT(A.TREECODE,'%') AND B1.STATE='1') AS NUM,f.oid as OID,f.FUNTYPE as FUNTYPE FROM farm_doctype AS a left join FARM_DOCTYPE_POP as f on f.TYPEID=a.ID WHERE 1 = 1 AND (TYPE = '1' OR TYPE = '3') AND PSTATE = '1' ) AS e", + "NAME,ID,PARENTID,NUM,OID,READPOP,AUDITPOP,WRITEPOP,FUNTYPE,SORT"); + query.setPagesize(1000); + query.setNoCount(); + if (user != null) { + query.addSqlRule("and ('1'!='" + user.getId() + "' )"); + } + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + query.addSort(new DBSort("SORT", "ASC")); + try { + DataResult result = query.search(); + // 1浏览、2编辑、3审核 + return getTypeLimit(result, user, "1"); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList(); + } + } + + @Override + public List getTypesForWriteDoc(LoginUser user) { + DataQuery query = DataQuery.init(new DataQuery(), + "(SELECT a.NAME as NAME, a.ID as ID,a.TYPE as type, a.READPOP as READPOP,a.WRITEPOP AS WRITEPOP, a.AUDITPOP AS AUDITPOP, a.PARENTID AS PARENTID, (SELECT COUNT(B1.ID) FROM FARM_DOC B1 LEFT JOIN FARM_RF_DOCTYPE B2 ON B1.ID = B2.DOCID LEFT JOIN FARM_DOCTYPE B3 ON B3.ID = B2.TYPEID WHERE B3.TREECODE LIKE CONCAT(A.TREECODE,'%') AND B1.STATE='1') AS NUM,f.oid as OID,f.FUNTYPE as FUNTYPE FROM farm_doctype AS a left join FARM_DOCTYPE_POP as f on f.TYPEID=a.ID WHERE (TYPE = '1' OR TYPE = '3') AND PSTATE = '1' ORDER BY SORT ASC) AS e", + "NAME,ID,PARENTID,NUM,OID,READPOP,TYPE,AUDITPOP,WRITEPOP,FUNTYPE"); + query.setPagesize(1000); + query.setNoCount(); + query.setDistinct(true); + if (user != null) { + query.addSqlRule("and ('1'!='" + user.getId() + "' )"); + } + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + try { + DataResult result = query.search(); + // 1浏览、2编辑、3审核 + return getTypeLimit(result, user, "2"); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList(); + } + } + + /** + * 配合getPubTypesForWriteDoc、getPubTypesForReadDoc方法完成分类权限查询的方法 + * + * @param result + * 中间结果集合 + * @param user + * 当前用户 + * @param type + * 1浏览、2编辑、3审核 + * @return + */ + private List getTypeLimit(DataResult result, LoginUser user, String type) { + Organization org = null; + if (user != null) { + org = userServiceImpl.getUserOrganization(user.getId()); + } + // 用来过滤重复分类的 + Set idset = new HashSet(); + // 做权限过滤 + List> newResult = new ArrayList<>(); + { + for (Map node : result.getResultList()) { + if (idset.contains((String) node.get("ID"))) { + // 过滤重复分类 + continue; + } + // READPOP,AUDITPOP,WRITEPOP + String marktitle = null; + if (type.equals("1")) { + marktitle = "READPOP"; + } + if (type.equals("2")) { + marktitle = "WRITEPOP"; + } + if (node.get(marktitle).equals("0") || node.get(marktitle).equals("2")) { + // 无权限任何人都可以访问 + newResult.add(node); + idset.add((String) node.get("ID")); + continue; + } + if (node.get(marktitle).equals("1") && user != null) { + // 如果有权限控制判断当前用户是否可以访问 + if (node.get("OID").equals(user.getId()) && node.get("FUNTYPE").equals(type)) { + // 该用户有权限 + newResult.add(node); + idset.add((String) node.get("ID")); + continue; + } + if (org != null && org.getTreecode().indexOf((String) node.get("OID")) >= 0 + && node.get("FUNTYPE").equals(type)) { + // 组织机构有权限 + newResult.add(node); + idset.add((String) node.get("ID")); + continue; + } + } + } + } + result.setResultList(newResult); + return result.getObjectList(TypeBrief.class); + } + + /* + * (non-Javadoc)获得用户所有(非阅读开放权限的)分类的ID(阅读) + * + * @see + * com.farm.doc.server.FarmDocTypeInter#getUserReadTypeIds(com.farm.core. + * auth.domain.LoginUser) + */ + @Override + @Transactional + public List getUserReadTypeIds(LoginUser user) { + if (user == null) { + return new ArrayList<>(); + } + List ids = new ArrayList<>(); + // 所有用户分类 + Set idset = new HashSet(); + // 获得所有用户分配到的分类权限(不包括公开的分类) + { + Organization org = null; + if (user != null) { + org = userServiceImpl.getUserOrganization(user.getId()); + } + DataQuery query = DataQuery.getInstance("1", "TYPEID,ID", "FARM_DOCTYPE_POP"); + query.setPagesize(1000); + query.setNoCount(); + query.addSqlRule("and FUNTYPE='1' "); + query.addSqlRule( + "and (OID ='" + user.getId() + "' or OID ='" + (org == null ? "none" : org.getId()) + "')"); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + try { + for (Map node : query.search().getResultList()) { + List list = getAllSubNode((String) node.get("TYPEID")); + for (FarmDoctype one : list) { + idset.add(one.getId()); + } + } + } catch (SQLException e) { + e.printStackTrace(); + return new ArrayList<>(); + } + } + for (String typeid : idset) { + ids.add(typeid); + } + return ids; + } + + @Override + @Transactional + public List getUserAuditTypeIds(String userid) { + if (userid == null) { + return new ArrayList<>(); + } + List ids = new ArrayList<>(); + // 所有用户分类 + Set idset = new HashSet(); + // 获得所有用户分配到的分类权限(不包括公开的分类) + { + Organization org = null; + String orgids = null; + if (userid != null) { + org = userServiceImpl.getUserOrganization(userid); + if (org != null) { + for (Organization node : organizationServiceImpl.getParentOrgs(org.getId())) { + if (orgids == null) { + orgids = "'" + node.getId() + "'"; + } else { + orgids = orgids + ",'" + node.getId() + "'"; + } + } + } + } + DataQuery query = DataQuery.getInstance("1", "TYPEID,ID", "FARM_DOCTYPE_POP"); + query.addSqlRule("and FUNTYPE='3' "); + query.addSqlRule( + "and (OID ='" + userid + "' " + (orgids == null ? "" : "or OID in (" + orgids + ")") + ")"); + try { + for (Map node : query.search().getResultList()) { + List list = getAllSubNode((String) node.get("TYPEID")); + for (FarmDoctype one : list) { + idset.add(one.getId()); + } + } + } catch (SQLException e) { + e.printStackTrace(); + return new ArrayList<>(); + } + } + for (String typeid : idset) { + ids.add(typeid); + } + return ids; + } + + @Override + public List getPopTypeAudtUserIds(String typeid) { + List ids = new ArrayList<>(); + // 找到分类的权限节点 + for (Doctypepop pop : getTypePops(typeid)) { + // 处理审核权限 + if (pop.getFuntype().equals("3")) { + // 查询所有审核人 + if (pop.getPoptype().equals("1")) { + ids.add(pop.getOid()); + } + // 查询所有审核机构 + if (pop.getPoptype().equals("2")) { + // 将机构转换为人 + List users = organizationServiceImpl.getOrgUsers(pop.getOid()); + for (String userid : users) { + ids.add(userid); + } + } + } + } + return ids; + } + + @Override + @Transactional + public List getTypesForUserRead(LoginUser user) { + // 获得所有无权限分类 + List> pubTypes = null; + List types = new ArrayList(); + DataQuery query = DataQuery.getInstance(1, "ID,NAME", "FARM_DOCTYPE").setPagesize(1000); + query.addRule(new DBRule("READPOP", "0", "=")); + query.setNoCount(); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + try { + pubTypes = query.search().getResultList(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + for (Map node : pubTypes) { + types.add((String) node.get("ID")); + } + if (user != null) { + // 获得用户的阅读权限分类 + List userTypes = getUserReadTypeIds(user); + if (userTypes != null) { + types.addAll(userTypes); + } + } + return types; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocgroupManagerImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocgroupManagerImpl.java new file mode 100644 index 0000000..394bb69 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocgroupManagerImpl.java @@ -0,0 +1,1135 @@ +package com.farm.doc.server.impl; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.apache.commons.beanutils.BeanUtils; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.authority.FarmAuthorityService; +import com.farm.authority.domain.User; +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.query.DataQuerys; +import com.farm.core.sql.query.DataQuery.CACHE_UNIT; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.result.ResultsHandle; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.FarmDocDaoInter; +import com.farm.doc.dao.FarmDocgroupDaoInter; +import com.farm.doc.dao.FarmDocgroupUserDaoInter; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDocgroup; +import com.farm.doc.domain.FarmDocgroupUser; +import com.farm.doc.domain.FarmDoctext; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.doc.domain.ex.GroupBrief; +import com.farm.doc.domain.ex.GroupEntire; +import com.farm.doc.exception.CanNoDeleteException; +import com.farm.doc.exception.NoGroupAuthForLicenceException; +import com.farm.doc.server.FarmDocManagerInter; +import com.farm.doc.server.FarmDocOperateRightInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.UsermessageServiceInter; +import com.farm.doc.server.FarmDocOperateRightInter.POP_TYPE; +import com.farm.parameter.FarmParameterService; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.doc.server.FarmDocmessageManagerInter; +import com.farm.doc.server.FarmFileManagerInter; + +/** + * 工作小组 + * + * @author MAC_wd + */ +@Service +public class FarmDocgroupManagerImpl implements FarmDocgroupManagerInter { + @Resource + private FarmDocgroupDaoInter farmDocgroupDao; + @Resource + private FarmDocgroupUserDaoInter farmDocgroupUserDao; + @Resource + private FarmDocmessageManagerInter farmDocmessageServer; + @Resource + private FarmDocDaoInter farmDocDao; + @Resource + private FarmDocManagerInter farmdocServer; + @Resource + private FarmDocOperateRightInter farmDocOperate; + @Resource + private FarmFileManagerInter farmFileServer; + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + @Resource + private UsermessageServiceInter usermessageServiceImpl; + + private static final Logger log = Logger.getLogger(FarmDocgroupManagerImpl.class); + + @Transactional + public FarmDocgroup editFarmDocgroupEntity(FarmDocgroup entity, LoginUser user) { + FarmDocgroup entity2 = farmDocgroupDao.getEntity(entity.getId()); + // entity2.setEuser(user.getId()); + // entity2.setEusername(user.getName()); + // entity2.setEtime(TimeTool.getTimeDate14()); + entity2.setPstate(entity.getPstate()); + entity2.setPcontent(entity.getPcontent()); + entity2.setGroupname(entity.getGroupname()); + entity2.setGroupnote(entity.getGroupnote()); + entity2.setGrouptag(entity.getGrouptag()); + entity2.setGroupimg(entity.getGroupimg()); + entity2.setJoincheck(entity.getJoincheck()); + farmDocgroupDao.editEntity(entity2); + return entity2; + } + + @Transactional + public void deleteFarmDocgroupEntity(String groupId, LoginUser user) { + List list = new ArrayList(); + list.add(new DBRule("GROUPID", groupId, "=")); + String homeDocId = farmDocgroupDao.getEntity(groupId).getHomedocid(); + if (homeDocId != null) { + try { + if (farmdocServer.getDocOnlyBean(homeDocId) != null) { + farmdocServer.deleteDocNoPop(homeDocId, user); + } + } catch (CanNoDeleteException e) { + throw new RuntimeException(e); + } + } + farmDocgroupUserDao.deleteEntitys(list); + { + List doclist = new ArrayList(); + doclist.add(new DBRule("DOCGROUPID", groupId, "=")); + // 释放所有文档 + for (Doc node : farmDocDao.selectEntitys(doclist)) { + farmDocOperate.flyDoc(node); + } + } + + farmDocgroupDao.deleteEntity(farmDocgroupDao.getEntity(groupId)); + } + + @Transactional + public FarmDocgroup getFarmDocgroupEntity(String id) { + if (id == null) { + return null; + } + FarmDocgroup group = farmDocgroupDao.getEntity(id); + return group; + } + + @Override + public DataQuery createFarmDocgroupQueryJoinUser(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, "farm_docgroup a left join FARM_DOCGROUP_USER b on b.GROUPID=a.id", + "a.id as ID,b.SHOWHOME as SHOWHOME, a.PSTATE as PSTATE,a.PCONTENT as PCONTENT,GROUPNAME,GROUPNOTE,GROUPTAG,GROUPIMG,JOINCHECK"); + return dbQuery; + } + + @Override + public DataQuery createFarmDocgroupQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, + "(select ID,(SELECT COUNT(a.id) FROM farm_doc a WHERE a.DOCGROUPID=farm_docgroup.ID ) as DOCNUM,PSTATE,PCONTENT,USERNUM,CUSERNAME,CTIME,GROUPNAME,GROUPNOTE,GROUPTAG,GROUPIMG,JOINCHECK from farm_docgroup) b ", + "ID,DOCNUM,PSTATE,PCONTENT,USERNUM,CUSERNAME,CTIME,GROUPNAME,GROUPNOTE,GROUPTAG,GROUPIMG,JOINCHECK"); + return dbQuery; + } + + @Transactional + public FarmDocgroupUser editFarmDocgroupUserEntity(FarmDocgroupUser entity, LoginUser user) { + FarmDocgroupUser entity2 = farmDocgroupUserDao.getEntity(entity.getId()); + // entity2.setEuser(user.getId()); + // entity2.setEusername(user.getName()); + // entity2.setEtime(TimeTool.getTimeDate14()); + entity2.setPstate(entity.getPstate()); + entity2.setPcontent(entity.getPcontent()); + entity2.setGroupid(entity.getGroupid()); + entity2.setUserid(entity.getUserid()); + entity2.setLeadis(entity.getLeadis()); + entity2.setEditis(entity.getEditis()); + entity2.setShowhome(entity.getShowhome()); + entity2.setShowsort(entity.getShowsort()); + farmDocgroupUserDao.editEntity(entity2); + return entity2; + } + + @Transactional + public void deleteFarmDocgroupUserEntity(String entity, LoginUser user) { + farmDocgroupUserDao.deleteEntity(farmDocgroupUserDao.getEntity(entity)); + } + + @Transactional + public FarmDocgroupUser getFarmDocgroupUserEntity(String id) { + if (id == null) { + return null; + } + return farmDocgroupUserDao.getEntity(id); + } + + @Override + public DataQuery createFarmDocgroupUserSimpleQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, + "farm_docgroup_user a left join alone_auth_user b on a.userid=b.id left join farm_docgroup c on a.groupid=c.id", + "a.id as id,a.PSTATE as PSTATE,GROUPID,b.name as username,LEADIS,EDITIS,SHOWHOME,SHOWSORT,c.groupname as groupname"); + return dbQuery; + } + + // ---------------------------------------------------------------------------------- + + public FarmDocgroupUserDaoInter getFarmDocgroupUserDao() { + return farmDocgroupUserDao; + } + + public FarmDocDaoInter getFarmDocDao() { + return farmDocDao; + } + + public FarmDocManagerInter getFarmdocServer() { + return farmdocServer; + } + + public void setFarmdocServer(FarmDocManagerInter farmdocServer) { + this.farmdocServer = farmdocServer; + } + + public void setFarmDocDao(FarmDocDaoInter farmDocDao) { + this.farmDocDao = farmDocDao; + } + + public FarmDocmessageManagerInter getFarmDocmessageServer() { + return farmDocmessageServer; + } + + public void setFarmDocmessageServer(FarmDocmessageManagerInter farmDocmessageServer) { + this.farmDocmessageServer = farmDocmessageServer; + } + + public void setFarmDocgroupUserDao(FarmDocgroupUserDaoInter farmDocgroupUserDao) { + this.farmDocgroupUserDao = farmDocgroupUserDao; + } + + public FarmFileManagerInter getFarmFileServer() { + return farmFileServer; + } + + public void setFarmFileServer(FarmFileManagerInter farmFileServer) { + this.farmFileServer = farmFileServer; + } + + public FarmDocgroupDaoInter getFarmDocgroupDao() { + return farmDocgroupDao; + } + + public void setFarmDocgroupDao(FarmDocgroupDaoInter farmDocgroupDao) { + this.farmDocgroupDao = farmDocgroupDao; + } + + public FarmDocOperateRightInter getFarmDocOperate() { + return farmDocOperate; + } + + public void setFarmDocOperate(FarmDocOperateRightInter farmDocOperate) { + this.farmDocOperate = farmDocOperate; + } + + @Override + @Transactional + public FarmDocgroup creatDocGroup(String groupname, String grouptag, String groupimg, boolean joincheck, + String groupnote, LoginUser currentUser) throws NoGroupAuthForLicenceException { + // String licence = FarmConstant.LICENCE; + // if (!MayCase.isCase(licence == null ? "NONE" : licence)) { + // FarmManager.instance().initLicence(currentUser); + // FarmConstant.LICENCE_FLAG="0"; + // throw new NoGroupAuthForLicenceException(); + // } + FarmDocgroup entity = new FarmDocgroup(); + entity.setCuser(currentUser.getId()); + entity.setCtime(TimeTool.getTimeDate14()); + entity.setCusername(currentUser.getName()); + entity.setEuser(currentUser.getId()); + entity.setEusername(currentUser.getName()); + entity.setEtime(TimeTool.getTimeDate14()); + entity.setPstate("1"); + entity.setGroupimg(groupimg); + if (groupimg.trim().length() <= 0) { + throw new RuntimeException("小组头像不能为空"); + } + farmFileServer.submitFile(groupimg); + entity.setGroupname(groupname); + entity.setGroupnote(groupnote); + entity.setUsernum(1); + entity.setGrouptag(grouptag); + entity.setJoincheck(joincheck ? "1" : "0"); + entity = farmDocgroupDao.insertEntity(entity); + // 将小组付给当前用户并设置为管理员 + FarmDocgroupUser goupuser = new FarmDocgroupUser(); + goupuser.setCuser(currentUser.getId()); + goupuser.setCtime(TimeTool.getTimeDate14()); + goupuser.setCusername(currentUser.getName()); + goupuser.setEuser(currentUser.getId()); + goupuser.setEusername(currentUser.getName()); + goupuser.setEtime(TimeTool.getTimeDate14()); + goupuser.setPstate("1"); + goupuser.setGroupid(entity.getId()); + goupuser.setUserid(currentUser.getId()); + goupuser.setLeadis("1"); + goupuser.setEditis("1"); + goupuser.setShowhome("1"); + goupuser.setShowsort(10); + farmDocgroupUserDao.insertEntity(goupuser); + { + // 创建小组首页文档 + DocEntire homedoc = new DocEntire(new Doc()); + // 标题、发布时间、内容类型是必填 texts中的TEXT1中存放超文本内容 + homedoc.getDoc().setTitle(entity.getGroupname()); + homedoc.getDoc().setPubtime(TimeTool.getTimeDate14()); + homedoc.getDoc().setDomtype("4"); + homedoc.getDoc().setWritepop(POP_TYPE.DOCGROUP.getValue()); + homedoc.getDoc().setReadpop(POP_TYPE.DOCGROUP.getValue()); + homedoc.getDoc().setDocgroupid(entity.getId()); + homedoc.getDoc().setState("1"); + FarmDoctext docText = new FarmDoctext(); + docText.setCtime(TimeTool.getTimeDate12()); + docText.setCuser(currentUser.getId()); + docText.setCusername(currentUser.getName()); + docText.setEtime(TimeTool.getTimeDate12()); + docText.setEuser(currentUser.getId()); + docText.setEusername(currentUser.getName()); + docText.setText1(groupnote); + homedoc.setTexts(docText); + // homedoc.setTexts("欢迎访问小组首页", currentUser); + homedoc = farmdocServer.createDoc(homedoc, currentUser); + entity.setHomedocid(homedoc.getDoc().getId()); + farmDocgroupDao.editEntity(entity); + } + return entity; + } + + @Override + @Transactional + public FarmDocgroup editDocGroup(String id, String groupname, String grouptag, String groupimg, boolean joincheck, + String groupnote, LoginUser currentUser) { + List rules = new ArrayList(); + rules.add(new DBRule("GROUPID", id, "=")); + rules.add(new DBRule("LEADIS", "1", "=")); + rules.add(new DBRule("USERID", currentUser.getId(), "=")); + if (farmDocgroupUserDao.selectEntitys(rules).size() <= 0) { + throw new RuntimeException("用户没有修改小组权限"); + } + FarmDocgroup entity2 = farmDocgroupDao.getEntity(id); + entity2.setEuser(currentUser.getId()); + entity2.setEusername(currentUser.getName()); + entity2.setEtime(TimeTool.getTimeDate14()); + entity2.setGroupname(groupname); + entity2.setGroupnote(groupnote); + entity2.setGrouptag(grouptag); + farmFileServer.cancelFile(entity2.getGroupimg()); + farmFileServer.submitFile(groupimg); + entity2.setGroupimg(groupimg); + entity2.setJoincheck(joincheck ? "1" : "0"); + farmDocgroupDao.editEntity(entity2); + return entity2; + } + + @Override + @Transactional + public boolean isJoinCheck(String groupid) { + return getFarmDocgroupEntity(groupid).getJoincheck().equals("1"); + } + + @Override + @Transactional + public FarmDocgroupUser applyGroup(String groupId, String joinUserId, String note, LoginUser currentUser) { + FarmDocgroup entity = farmDocgroupDao.getEntity(groupId); + FarmDocgroupUser goupuser = new FarmDocgroupUser(); + goupuser.setCuser(currentUser.getId()); + goupuser.setCtime(TimeTool.getTimeDate14()); + goupuser.setCusername(currentUser.getName()); + goupuser.setEuser(currentUser.getId()); + goupuser.setEusername(currentUser.getName()); + goupuser.setEtime(TimeTool.getTimeDate14()); + // 申请 + if (entity.getJoincheck().equals("1")) { + goupuser.setPstate("3"); + } else { + goupuser.setPstate("1"); + entity.setUsernum(getAllUserNoApplyByGroup(groupId).size() + 1); + farmDocgroupDao.editEntity(entity); + } + goupuser.setGroupid(groupId); + goupuser.setUserid(joinUserId); + goupuser.setLeadis("0"); + goupuser.setEditis("0"); + goupuser.setShowhome("1"); + goupuser.setShowsort(10); + goupuser.setApplynote(note); + farmDocgroupUserDao.insertEntity(goupuser); + // 发送消息给管理员 + // for (User node : getAllAdministratorByGroup(groupId)) { + // try { + // // 申请 + // if (entity.getJoincheck().equals("1")) { + // farmDocmessageServer.sendMessage(node.getId(), + // "有用户'" + currentUser.getName() + "'申请加入" + entity.getGroupname() + + // "小组,申请备注:" + note, + // "有用户'" + currentUser.getName() + "'申请加入" + entity.getGroupname() + + // "小组", "工作小组", + // currentUser); + // } else { + // farmDocmessageServer.sendMessage(node.getId(), + // "用户'" + currentUser.getName() + "'加入" + entity.getGroupname() + "小组", + // "有用户'" + currentUser.getName() + "'加入" + entity.getGroupname() + + // "小组", "工作小组", currentUser); + // } + // + // } catch (Exception e) { + // log.error("用户申请加入小组时发送站内消息失败" + e.getMessage()); + // } + // } + for (User node : getAllAdministratorByGroup(groupId)) { + try { + // 申请 + if (entity.getJoincheck().equals("1")) { + usermessageServiceImpl.sendMessage(node.getId(), + "有用户'" + currentUser.getName() + "'申请加入" + entity.getGroupname() + "小组,申请备注:" + note + "。请进入\"小组首页/成员管理\"进行审核。", + "有用户'" + currentUser.getName() + "'申请加入" + entity.getGroupname() + "小组", "工作小组", + currentUser); + } else { + usermessageServiceImpl.sendMessage(node.getId(), + "用户'" + currentUser.getName() + "'加入" + entity.getGroupname() + "小组", + "有用户'" + currentUser.getName() + "'加入" + entity.getGroupname() + "小组", "工作小组", currentUser); + } + } catch (Exception e) { + log.error("用户申请加入小组时发送站内消息失败" + e.getMessage()); + } + } + return goupuser; + } + + @Override + @Transactional + public void inviteGroup(String groupId, String joinUserId, boolean isLead, boolean isEdit, LoginUser currentUser) { + FarmDocgroupUser goupuser = new FarmDocgroupUser(); + goupuser.setCuser(currentUser.getId()); + goupuser.setCtime(TimeTool.getTimeDate14()); + goupuser.setCusername(currentUser.getName()); + goupuser.setEuser(currentUser.getId()); + goupuser.setEusername(currentUser.getName()); + goupuser.setEtime(TimeTool.getTimeDate14()); + // 邀请 + goupuser.setPstate("0"); + goupuser.setGroupid(groupId); + goupuser.setUserid(joinUserId); + goupuser.setLeadis(isLead ? "1" : "0"); + goupuser.setEditis(isEdit ? "1" : "0"); + goupuser.setShowhome("1"); + goupuser.setShowsort(10); + farmDocgroupUserDao.insertEntity(goupuser); + } + + @Override + @Transactional + public boolean isJoinGroupByUser(String groupId, String userId) { + List rules = new ArrayList(); + rules.add(new DBRule("GROUPID", groupId, "=")); + rules.add(new DBRule("USERID", userId, "=")); + if (farmDocgroupUserDao.selectEntitys(rules).size() <= 0) { + return false; + } + return true; + } + + @Override + @Transactional + public FarmDocgroupUser getFarmDocgroupUser(String groupId, String userId) { + List rules = new ArrayList(); + rules.add(new DBRule("GROUPID", groupId, "=")); + rules.add(new DBRule("USERID", userId, "=")); + List list = farmDocgroupUserDao.selectEntitys(rules); + if (list.size() > 0) { + return list.get(0); + } else { + return null; + } + + } + + @Override + @Transactional + public void leaveGroup(String groupID, String userId) { + List rules = new ArrayList(); + rules.add(new DBRule("GROUPID", groupID, "=")); + rules.add(new DBRule("USERID", userId, "=")); + FarmDocgroup group = farmDocgroupDao.getEntity(groupID); + { + // 更新成员数量 + group.setUsernum(getAllUserNoApplyByGroup(group.getId()).size() - 1); + farmDocgroupDao.editEntity(group); + } + farmDocgroupUserDao.deleteEntitys(rules); + LoginUser user = FarmAuthorityService.getInstance().getUserById(userId); + for (User node : getAllAdministratorByGroup(groupID)) { + try { + // 退出小组 + farmDocmessageServer.sendMessage(node.getId(), + "用户'" + user.getName() + "'退出" + group.getGroupname() + "小组", + "有用户'" + user.getName() + "'退出" + group.getGroupname() + "小组", "工作小组", user); + } catch (Exception e) { + log.error("用户退出小组时发送站内消息失败" + e.getMessage()); + } + } + } + + @Override + @Transactional + public List getAllAdministratorByGroup(String groupId) { + List list = null; + DataQuery query = DataQuery.getInstance(1, + "c.COMMENTS AS COMMENTS, c.CTIME AS CTIME, c.CUSER AS CUSER, c.ID AS ID, c.LOGINNAME AS LOGINNAME, c.LOGINTIME AS LOGINTIME, c. NAME AS NAME, c.STATE AS STATE, c.TYPE AS TYPE, c.IMGID AS IMGID", + " FARM_DOCGROUP a LEFT JOIN FARM_DOCGROUP_USER b ON a.ID = b.GROUPID LEFT JOIN ALONE_AUTH_USER c ON c.ID = b.USERID"); + query.setPagesize(1000); + query.setNoCount(); + query.addRule(new DBRule("a.id", groupId, "=")); + query.addRule(new DBRule("b.PSTATE", "1", "=")); + query.addRule(new DBRule("b.LEADIS", "1", "=")); + try { + list = query.search().getObjectList(User.class); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList<>(); + } + return list; + } + + @Override + @Transactional + public List getAllUserByGroup(String groupId) { + // 1在用,0邀请,3申请 + List rules = new ArrayList(); + rules.add(new DBRule("GROUPID", groupId, "=")); + return farmDocgroupUserDao.selectEntitys(rules); + } + + @Override + @Transactional + public List getAllUserNoApplyByGroup(String groupId) { + List list = null; + DataQuery query = DataQuery.getInstance(1, + "c.COMMENTS AS COMMENTS, c.CTIME AS CTIME, c.CUSER AS CUSER, c.ID AS ID, c.LOGINNAME AS LOGINNAME, c.LOGINTIME AS LOGINTIME, c. NAME AS NAME, c.STATE AS STATE, c.TYPE AS TYPE, c.IMGID AS IMGID", + " FARM_DOCGROUP a LEFT JOIN FARM_DOCGROUP_USER b ON a.ID = b.GROUPID LEFT JOIN ALONE_AUTH_USER c ON c.ID = b.USERID"); + query.setPagesize(1000); + query.setNoCount(); + query.addRule(new DBRule("a.id", groupId, "=")); + query.addRule(new DBRule("b.PSTATE", "1", "=")); + try { + list = query.search().getObjectList(User.class); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList<>(); + } + return list; + } + + @Override + @Transactional + public void agreeJoinApply(String groupUserId, LoginUser currentUser) { + FarmDocgroupUser gu = farmDocgroupUserDao.getEntity(groupUserId); + if (!isAdminForGroup(currentUser.getId(), gu.getGroupid())) { + throw new RuntimeException("没有操作权限"); + } + gu.setPstate("1"); + { + // 更新成员数量 + FarmDocgroup group = farmDocgroupDao.getEntity(gu.getGroupid()); + group.setUsernum(getAllUserNoApplyByGroup(group.getId()).size() + 1); + farmDocgroupDao.editEntity(group); + } + farmDocgroupUserDao.editEntity(gu); + try { + farmDocmessageServer.sendMessage(gu.getUserid(), "见主题", + "小组‘" + getFarmDocgroupEntity(gu.getGroupid()).getGroupname() + "’已经同意你的加入申请", null, currentUser); + } catch (Exception e) { + log.error("用户申请加入小组时发送站内消息失败" + e.getMessage()); + } + + } + + @Override + @Transactional + public void refuseJoinApply(String groupUserId, LoginUser currentUser) { + FarmDocgroupUser gu = farmDocgroupUserDao.getEntity(groupUserId); + if (!isAdminForGroup(currentUser.getId(), gu.getGroupid())) { + throw new RuntimeException("没有操作权限"); + } + farmDocgroupUserDao.deleteEntity(gu); + } + + @Override + @Transactional + public void leaveGroup(String groupUserId, LoginUser currentUser) { + FarmDocgroupUser gu = farmDocgroupUserDao.getEntity(groupUserId); + if (!isAdminForGroup(currentUser.getId(), gu.getGroupid())) { + throw new RuntimeException("没有操作权限"); + } + { + // 更新成员数量 + FarmDocgroup group = farmDocgroupDao.getEntity(gu.getGroupid()); + group.setUsernum(getAllUserNoApplyByGroup(group.getId()).size() - 1); + farmDocgroupDao.editEntity(group); + } + farmDocgroupUserDao.deleteEntity(gu); + } + + @Override + @Transactional + public void setAdminForGroup(String groupUserId, LoginUser currentUser) { + FarmDocgroupUser gu = farmDocgroupUserDao.getEntity(groupUserId); + if (!isAdminForGroup(currentUser.getId(), gu.getGroupid())) { + throw new RuntimeException("没有操作权限"); + } + gu.setLeadis("1"); + farmDocgroupUserDao.editEntity(gu); + } + + @Override + @Transactional + public void setEditorForGroup(String groupUserId, LoginUser currentUser) { + FarmDocgroupUser gu = farmDocgroupUserDao.getEntity(groupUserId); + if (!isAdminForGroup(currentUser.getId(), gu.getGroupid())) { + throw new RuntimeException("没有操作权限"); + } + gu.setEditis("1"); + farmDocgroupUserDao.editEntity(gu); + } + + @Override + @Transactional + public void wipeAdminFromGroup(String groupUserId, LoginUser currentUser) { + FarmDocgroupUser gu = farmDocgroupUserDao.getEntity(groupUserId); + if (!isAdminForGroup(currentUser.getId(), gu.getGroupid())) { + throw new RuntimeException("没有操作权限"); + } + gu.setLeadis("0"); + farmDocgroupUserDao.editEntity(gu); + } + + @Override + @Transactional + public void wipeEditorForGroup(String groupUserId, LoginUser currentUser) { + FarmDocgroupUser gu = farmDocgroupUserDao.getEntity(groupUserId); + if (!isAdminForGroup(currentUser.getId(), gu.getGroupid())) { + throw new RuntimeException("没有操作权限"); + } + gu.setEditis("0"); + farmDocgroupUserDao.editEntity(gu); + } + + @Override + @Transactional + public boolean isAdminForGroup(String userid, String groupId) { + FarmDocgroupUser groupUser = getFarmDocgroupUser(groupId, userid); + if (groupUser == null) { + return false; + } + if (groupUser.getLeadis().equals("1")) { + return true; + } + return false; + } + + @Override + @Transactional + public void setGroupHomeHide(String groupId, String userId) { + FarmDocgroupUser groupUser = getFarmDocgroupUser(groupId, userId); + groupUser.setShowhome("0"); + farmDocgroupUserDao.editEntity(groupUser); + } + + @Override + @Transactional + public void setGroupHomeShow(String groupId, String userId) { + FarmDocgroupUser groupUser = getFarmDocgroupUser(groupId, userId); + groupUser.setShowhome("1"); + farmDocgroupUserDao.editEntity(groupUser); + } + + @Override + @Transactional + public void setGroupSortUp(String groupId, String userId) { + List lists = getAllGroupUserByUser(userId); + Collections.sort(lists, new Comparator() { + @Override + public int compare(FarmDocgroupUser o1, FarmDocgroupUser o2) { + if (o1.getShowsort().compareTo(o2.getShowsort()) == 0) { + return o1.getCtime().compareTo(o2.getCtime()); + } else { + return o1.getShowsort().compareTo(o2.getShowsort()); + } + } + }); + int n = 0; + int index = 0; + for (FarmDocgroupUser node : lists) { + node.setShowsort(n); + if (node.getGroupid().equals(groupId)) { + index = n; + } + farmDocgroupUserDao.editEntity(node); + n++; + } + if (index == 0) { + return; + } + int temp = 0; + temp = lists.get(index).getShowsort(); + lists.get(index).setShowsort(lists.get(index - 1).getShowsort()); + lists.get(index - 1).setShowsort(temp); + farmDocgroupUserDao.editEntity(lists.get(index)); + farmDocgroupUserDao.editEntity(lists.get(index - 1)); + } + + @Override + @Transactional + public List getAllGroupUserByUser(String userId) { + List rules = new ArrayList(); + rules.add(new DBRule("USERID", userId, "=")); + return farmDocgroupUserDao.selectEntitys(rules); + } + + @Override + public List> getEditorGroupByUser(String userId) { + DataQuery query = DataQuery.getInstance("1", "b.groupNAME AS NAME,b.ID AS id", + "FARM_DOCGROUP_USER a LEFT JOIN farm_docgroup b ON a.GROUPID=b.ID"); + query.setPagesize(20); + DataResult result = null; + // /a.EDITIS='1' AND b.PSTATE='1' AND a.USERID='' + query.addRule(new DBRule("a.EDITIS", "1", "=")); + query.addRule(new DBRule("b.PSTATE", "1", "=")); + query.addRule(new DBRule("a.USERID", userId, "=")); + try { + result = query.search(); + } catch (SQLException e) { + log.error(e.getMessage()); + } + return result.getResultList(); + } + + @Override + @Transactional + public boolean isGroupEditor(String docgroupid, String userId) { + if (!isJoinGroupByUser(docgroupid, userId)) { + return false; + } + if (getFarmDocgroupUser(docgroupid, userId).getEditis().equals("1")) { + return true; + } + return false; + } + + @Override + public DataQuery getGroupNewDocQuery(DataQuery query, String groupId, LoginUser currentUser) { + String userid = "none"; + if (currentUser != null) { + userid = currentUser.getId(); + } + DataQuerys.wipeVirus(groupId); + StringBuffer sqlform = new StringBuffer(); + sqlform.append("(SELECT DISTINCT "); + sqlform.append( + "A.ID AS ID,B.EVALUATE as EVALUATE,ANSWERINGNUM, A.DOMTYPE AS DOMTYPE,A.ETIME as ETIME, A.TITLE AS TITLE, A.DOCDESCRIBE AS DOCDESCRIBE,A.AUTHOR AS AUTHOR, A.PUBTIME AS PUBTIME, A.TAGKEY AS TAGKEY, A.IMGID AS IMGID, B.VISITNUM AS VISITNUM, B.PRAISEYES AS PRAISEYES, B.PRAISENO AS PRAISENO, B.HOTNUM AS HOTNUM, D.NAME AS TYPENAME "); + sqlform.append( + " FROM farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID = b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID = a.ID LEFT JOIN farm_doctype d ON d.ID = c.TYPEID LEFT JOIN farm_docgroup_user e ON e.GROUPID=a.DOCGROUPID "); + sqlform.append(" WHERE 1 = 1 AND A.STATE = '1' AND DOCGROUPID = '" + groupId + + "' AND (a.READPOP = '1' OR (a.READPOP = '2' AND e.USERID = '" + userid + + "') OR (a.READPOP = '0' AND a.CUSER = '" + userid + "'))"); + sqlform.append(" ) "); + query = DataQuery.init(query, sqlform.toString() + " a", + "ID,DOMTYPE,TITLE,DOCDESCRIBE,AUTHOR,PUBTIME,ANSWERINGNUM,TAGKEY,IMGID, VISITNUM,PRAISEYES,PRAISENO,EVALUATE, HOTNUM, TYPENAME,ETIME"); + query.addSort(new DBSort("ETIME", "desc")); + query.setPagesize(10); + return query; + } + + @Override + public DataQuery getGroupGoodDocQuery(DataQuery query, String groupId, LoginUser currentUser) { + String userid = "none"; + if (currentUser != null) { + userid = currentUser.getId(); + } + DataQuerys.wipeVirus(groupId); + StringBuffer sqlform = new StringBuffer(); + sqlform.append("(SELECT DISTINCT "); + sqlform.append( + "A.ID AS ID,B.EVALUATE as EVALUATE,ANSWERINGNUM, A.DOMTYPE AS DOMTYPE,A.ETIME as ETIME, A.TITLE AS TITLE, A.DOCDESCRIBE AS DOCDESCRIBE,A.AUTHOR AS AUTHOR, A.PUBTIME AS PUBTIME, A.TAGKEY AS TAGKEY, A.IMGID AS IMGID, B.VISITNUM AS VISITNUM, B.PRAISEYES AS PRAISEYES, B.PRAISENO AS PRAISENO, B.HOTNUM AS HOTNUM, D.NAME AS TYPENAME "); + sqlform.append( + " FROM farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID = b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID = a.ID LEFT JOIN farm_doctype d ON d.ID = c.TYPEID LEFT JOIN farm_docgroup_user e ON e.GROUPID=a.DOCGROUPID "); + sqlform.append(" WHERE 1 = 1 AND A.STATE = '1' AND DOCGROUPID = '" + groupId + + "' AND (a.READPOP = '1' OR (a.READPOP = '2' AND e.USERID = '" + userid + + "') OR (a.READPOP = '0' AND a.CUSER = '" + userid + "'))"); + sqlform.append(" ) "); + query = DataQuery.init(query, sqlform.toString() + " a", + "ID,DOMTYPE,TITLE,DOCDESCRIBE,AUTHOR,PUBTIME,ANSWERINGNUM,TAGKEY,IMGID, VISITNUM,PRAISEYES,PRAISENO,EVALUATE, HOTNUM, TYPENAME,ETIME"); + query.addSort(new DBSort("EVALUATE", "desc")); + query.setPagesize(10); + return query; + } + + @Override + public DataQuery getGroupHotDocQuery(DataQuery query, String groupId, LoginUser currentUser) { + StringBuffer sqlform = new StringBuffer(); + String userid = "none"; + if (currentUser != null) { + userid = currentUser.getId(); + } + DataQuerys.wipeVirus(groupId); + sqlform.append("(SELECT DISTINCT "); + sqlform.append( + "A.ID AS ID,B.EVALUATE as EVALUATE, A.DOMTYPE AS DOMTYPE,ANSWERINGNUM,A.ETIME as ETIME, A.TITLE AS TITLE, A.DOCDESCRIBE AS DOCDESCRIBE,A.AUTHOR AS AUTHOR, A.PUBTIME AS PUBTIME, A.TAGKEY AS TAGKEY, A.IMGID AS IMGID, B.VISITNUM AS VISITNUM, B.PRAISEYES AS PRAISEYES, B.PRAISENO AS PRAISENO, B.HOTNUM AS HOTNUM, D.NAME AS TYPENAME "); + sqlform.append( + " FROM farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID = b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID = a.ID LEFT JOIN farm_doctype d ON d.ID = c.TYPEID LEFT JOIN farm_docgroup_user e ON e.GROUPID=a.DOCGROUPID "); + sqlform.append(" WHERE 1 = 1 AND A.STATE = '1' AND DOCGROUPID = '" + groupId + + "' AND (a.READPOP = '1' OR (a.READPOP = '2' AND e.USERID = '" + userid + + "') OR (a.READPOP = '0' AND a.CUSER = '" + userid + "'))"); + sqlform.append(" ) "); + query = DataQuery.init(query, sqlform.toString() + " a", + "ID,DOMTYPE,TITLE,DOCDESCRIBE,AUTHOR,PUBTIME,TAGKEY,IMGID,ANSWERINGNUM, VISITNUM,PRAISEYES,PRAISENO,EVALUATE, HOTNUM, TYPENAME,ETIME"); + query.addSort(new DBSort("HOTNUM", "desc")); + query.setPagesize(10); + return query; + } + + @Override + @Transactional + public int getGroupDocNum(String groupId) { + return farmDocgroupDao.getGroupDocNum(groupId); + } + + @Override + @Transactional + public FarmDocgroupUser editMinFarmDocgroupUserEntity(FarmDocgroupUser entity, LoginUser currentUser) { + FarmDocgroupUser entity2 = farmDocgroupUserDao.getEntity(entity.getId()); + entity2.setPstate(entity.getPstate()); + entity2.setLeadis(entity.getLeadis()); + entity2.setEditis(entity.getEditis()); + entity2.setShowhome(entity.getShowhome()); + // entity2.setShowsort(entity.getShowsort()); + // entity2.setEuser(user.getId()); + // entity2.setEusername(user.getName()); + // entity2.setEtime(TimeTool.getTimeDate14()); + // entity2.setPcontent(entity.getPcontent()); + // entity2.setGroupid(entity.getGroupid()); + // entity2.setUserid(entity.getUserid()); + farmDocgroupUserDao.editEntity(entity2); + return entity2; + } + + @Override + public DataQuery createUserGroupDocQuery(DataQuery query, String userid) { + StringBuffer sqlBuffer = new StringBuffer(); + sqlBuffer.append( + "SELECT A.ID AS ID,GROUPNAME,f.id as GROUPID, B.EVALUATE AS EVALUATE, A.DOMTYPE AS DOMTYPE, A.ETIME AS ETIME, A.TITLE AS TITLE, A.DOCDESCRIBE AS DOCDESCRIBE,"); + sqlBuffer.append( + "A.AUTHOR AS AUTHOR,e.SHOWHOME as SHOWHOME, A.PUBTIME AS PUBTIME, A.TAGKEY AS TAGKEY, A.IMGID AS IMGID, B.VISITNUM AS VISITNUM, B.PRAISEYES AS PRAISEYES, B.PRAISENO AS PRAISENO, B.HOTNUM AS HOTNUM, "); + sqlBuffer.append(" D.NAME AS TYPENAME, f.GROUPIMG AS groupIMG"); + sqlBuffer.append( + " FROM farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID = b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID = a.ID"); + sqlBuffer.append( + " LEFT JOIN farm_doctype d ON d.ID = c.TYPEID LEFT JOIN farm_docgroup_user e ON e.GROUPID = a.DOCGROUPID LEFT JOIN farm_docgroup f ON f.ID=e.GROUPID"); + sqlBuffer.append(" WHERE 1 = 1 AND A.STATE = '1' AND e.SHOWHOME ='1' AND e.USERID='" + userid + "'"); + sqlBuffer.append(" AND (a.READPOP = '1' OR (a.READPOP = '2' AND e.USERID = '" + userid + + "') OR (a.READPOP = '0' AND a.CUSER = '" + userid + "'))"); + query = DataQuery.init(query, "(" + sqlBuffer.toString() + ") a", + "ID,EVALUATE,DOMTYPE,ETIME,SHOWHOME,GROUPNAME,GROUPID,TITLE,DOCDESCRIBE,AUTHOR,PUBTIME,TAGKEY,IMGID,VISITNUM,PRAISEYES,PRAISENO,HOTNUM,TYPENAME,GROUPIMG"); + query.setPagesize(10); + return query; + } + + @Override + @Transactional + public FarmDocgroup editDocgroupJoinCheck(boolean isJoinCheck, String groupId, LoginUser currentUser) { + FarmDocgroup entity2 = farmDocgroupDao.getEntity(groupId); + entity2.setEuser(currentUser.getId()); + entity2.setEusername(currentUser.getName()); + entity2.setEtime(TimeTool.getTimeDate14()); + entity2.setJoincheck(isJoinCheck ? "1" : "0"); + farmDocgroupDao.editEntity(entity2); + return entity2; + } + + @Override + public DataQuery getGroupBadDocQuery(DataQuery query, String groupId, LoginUser currentUser) { + String userid = "none"; + if (currentUser != null) { + userid = currentUser.getId(); + } + DataQuerys.wipeVirus(groupId); + StringBuffer sqlform = new StringBuffer(); + sqlform.append("(SELECT DISTINCT "); + sqlform.append( + "A.ID AS ID,B.EVALUATE as EVALUATE,ANSWERINGNUM, A.DOMTYPE AS DOMTYPE,A.ETIME as ETIME, A.TITLE AS TITLE, A.DOCDESCRIBE AS DOCDESCRIBE,A.AUTHOR AS AUTHOR, A.PUBTIME AS PUBTIME, A.TAGKEY AS TAGKEY, A.IMGID AS IMGID, B.VISITNUM AS VISITNUM, B.PRAISEYES AS PRAISEYES, B.PRAISENO AS PRAISENO, B.HOTNUM AS HOTNUM, D.NAME AS TYPENAME "); + sqlform.append( + " FROM farm_doc a LEFT JOIN farm_docruninfo b ON a.RUNINFOID = b.ID LEFT JOIN farm_rf_doctype c ON c.DOCID = a.ID LEFT JOIN farm_doctype d ON d.ID = c.TYPEID LEFT JOIN farm_docgroup_user e ON e.GROUPID=a.DOCGROUPID "); + sqlform.append(" WHERE 1 = 1 AND A.STATE = '1' AND DOCGROUPID = '" + groupId + + "' AND (a.READPOP = '1' OR (a.READPOP = '2' AND e.USERID = '" + userid + + "') OR (a.READPOP = '0' AND a.CUSER = '" + userid + "'))"); + sqlform.append(" ) "); + query = DataQuery.init(query, sqlform.toString() + " a", + "ID,DOMTYPE,TITLE,DOCDESCRIBE,AUTHOR,PUBTIME,ANSWERINGNUM,TAGKEY,IMGID, VISITNUM,PRAISEYES,PRAISENO,EVALUATE, HOTNUM, TYPENAME,ETIME"); + query.addSort(new DBSort("EVALUATE", "asc")); + query.setPagesize(10); + return query; + } + + @Override + public DataQuery createFarmDocgroupQueryNuContainUser(DataQuery query, String userid) { + DataQuery dbQuery = DataQuery.init(query, + "farm_docgroup a LEFT JOIN FARM_DOCGROUP_USER b ON b.GROUPID=a.ID AND b.USERID='" + userid + "'", + "a.ID as ID,(SELECT COUNT(id) FROM farm_doc WHERE DOCGROUPID=a.ID ) as DOCNUM,a.PSTATE as PSTATE,a.PCONTENT as PCONTENT,a.USERNUM as USERNUM,a.CUSERNAME as CUSERNAME,a.CTIME as CTIME,a.GROUPNAME as GROUPNAME,a.GROUPNOTE as GROUPNOTE,a.GROUPTAG as GROUPTAG,a.GROUPIMG as GROUPIMG,a.JOINCHECK as JOINCHECK,b.USERID as USERID"); + dbQuery.addSqlRule(" and USERID is null"); + query.setNoCount(); + return dbQuery; + } + + @Override + public List getHotDocGroups(int num) { + return getHotDocGroups(num, null); + } + + @Override + public List getHotDocGroups(int num, LoginUser currentUser) { + DataQuery query = DataQuery.init(new DataQuery(), + "FARM_DOCGROUP as a left join FARM_DOCGROUP_USER as b on a.id=b.GROUPID and b.USERID='" + + (currentUser == null ? "NONE" : currentUser.getId()) + "'", + "a.ID AS ID, a.CTIME AS CTIME, a.ETIME AS ETIME, a.CUSERNAME AS CUSERNAME, a.CUSER AS CUSER, a.EUSERNAME AS EUSERNAME, a.EUSER AS EUSER, a.PSTATE AS PSTATE, a.PCONTENT AS PCONTENT, a.GROUPNAME AS GROUPNAME, a.GROUPNOTE AS GROUPNOTE, a.GROUPTAG AS GROUPTAG, a.GROUPIMG AS GROUPIMG, a.JOINCHECK AS JOINCHECK, a.USERNUM AS USERNUM, a.HOMEDOCID AS HOMEDOCID, b.USERID AS USERID"); + query.addSort(new DBSort("a.USERNUM", "desc")); + query.setCurrentPage(1); + query.setDistinct(true); + query.setPagesize(num); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.long")), + CACHE_UNIT.second); + try { + DataResult result = query.search(); + result.runHandle(new ResultsHandle() { + @Override + public void handle(Map row) { + row.put("IMGURL", farmFileServer.getFileURL(row.get("GROUPIMG").toString())); + if (row.get("USERID") != null && !row.get("USERID").toString().isEmpty()) { + row.put("USERJOIN", "1"); + } else { + row.put("USERJOIN", "0"); + } + } + }); + return result.getObjectList(GroupBrief.class); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList<>(); + } + } + + @Override + @Transactional + public GroupEntire getFarmDocgroup(String groupid) { + if (groupid == null) { + return null; + } + FarmDocgroup group = farmDocgroupDao.getEntity(groupid); + GroupEntire groupb = new GroupEntire(); + try { + BeanUtils.copyProperties(groupb, group); + } catch (Exception e) { + log.error(e.toString()); + return groupb; + } + groupb.setUsers(getAllUserNoApplyByGroup(groupid)); + groupb.setAdmins(getAllAdministratorByGroup(groupid)); + if (group.getGroupimg() != null && group.getGroupimg().trim().length() <= 0) { + group.setGroupimg(null); + } + if (group.getGroupimg() != null) { + groupb.setImgurl(farmFileServer.getFileURL(group.getGroupimg())); + } + if (group.getGrouptag() != null) { + String tags = group.getGrouptag(); + String[] tags1 = tags.trim().replaceAll(",", ",").replaceAll("、", ",").split(","); + groupb.setTags(Arrays.asList(tags1)); + } + return groupb; + } + + @Override + public DataResult getNewGroupDoc(LoginUser user, String gourpid, int pagesize, Integer pagenum) { + DataQuery query = DataQuery.init(new DataQuery(), + "FARM_DOC a LEFT JOIN farm_docruninfo b on a.RUNINFOID=b.ID left join FARM_RF_DOCTYPE f on a.id=f.docid left join FARM_DOCTYPE g on g.id=f.typeid left join FARM_DOCGROUP d on a.DOCGROUPID=d.ID left join FARM_DOCGROUP_USER c on c.GROUPID=d.ID and c.USERID='" + + (user == null ? "none" : user.getId()) + "' LEFT JOIN ALONE_AUTH_USER e ON e.ID = a.CUSER ", + "a.ID as DOCID,d.GROUPNAME as GROUPNAME,d.ID as GROUPID,d.GROUPIMG as GROUPIMG,a.DOMTYPE as DOMTYPE,a.TITLE AS title,a.DOCDESCRIBE AS DOCDESCRIBE,a.AUTHOR AS AUTHOR,a.PUBTIME AS PUBTIME,a.TAGKEY AS TAGKEY ,a.IMGID AS IMGID,b.VISITNUM AS VISITNUM,b.PRAISEYES AS PRAISEYES,b.PRAISENO AS PRAISENO,b.HOTNUM AS HOTNUM,b.EVALUATE as EVALUATE,b.ANSWERINGNUM as ANSWERINGNUM, E.ID AS USERID, E.NAME AS USERNAME, E.IMGID AS USERIMGID"); + query.addSort(new DBSort("a.etime", "desc")); + query.setCurrentPage(pagenum); + query.setDistinct(true); + query.addRule(new DBRule("a.STATE", "1", "=")); + if (gourpid != null) { + query.addRule(new DBRule("a.DOCGROUPID", gourpid, "=")); + } + query.addRule(new DBRule("DOMTYPE", "4", "!=")); + // 文章三种情况判断 + // 1.文章阅读权限为公共 + // 2.文章的创建者为当前登录用户 + // 3.文章的阅读权限为小组,并且当前登陆用户为组内成员.(使用子查询处理) + // 4.判断该用户有无分类权限 + String typeids = null; + for (String id : farmDocTypeManagerImpl.getUserReadTypeIds(user)) { + if (typeids == null) { + typeids = "'" + id + "'"; + } else { + typeids = typeids + "," + "'" + id + "'"; + } + } + if (user != null) { + query.addSqlRule("and (g.READPOP='0' or (g.READPOP!='0' and g.id in (" + typeids + ")))"); + } else { + query.addSqlRule("and g.READPOP='0'"); + } + query.addSqlRule( + " and a.DOCGROUPID is not null AND ( a.READPOP = '1' OR ( a.READPOP = '2' AND d.JOINCHECK = '0' ) OR ( a.READPOP = '2' AND d.JOINCHECK = '1' AND c.PSTATE = '1' ))"); + query.setPagesize(pagesize); + try { + DataResult result = query.search(); + result.runHandle(new ResultsHandle() { + @Override + public void handle(Map row) { + row.put("IMGURL", farmFileServer.getFileURL((String)row.get("GROUPIMG"))); + row.put("PHOTOURL", farmFileServer.getFileURL((String)row.get("USERIMGID"))); + } + }); + return result; + } catch (SQLException e) { + log.error(e.toString()); + return DataResult.getInstance(); + } + } + + @Override + public DataResult getGroupUser(String groupid, SearchType isApply, SearchType isAdmin, SearchType isEditor, + int page, int pagesize) { + DataQuery query = DataQuery.getInstance(page, + "A.ID AS GROUPUSERID, b.NAME as name,b.ID as ID,b.IMGID as IMGID,a.PSTATE as PSTATE,a.GROUPID as GROUPID,a.LEADIS as LEADIS,a.EDITIS as EDITIS,a.APPLYNOTE as APPLYNOTE", + "FARM_DOCGROUP_USER a left join ALONE_AUTH_USER b on a.userid=b.id"); + query.setPagesize(pagesize); + + if (isApply.equals(SearchType.yes)) { + query.addRule(new DBRule("PSTATE", "3", "=")); + } + if (isApply.equals(SearchType.no)) { + query.addRule(new DBRule("PSTATE", "1", "=")); + } + if (isAdmin.equals(SearchType.no)) { + query.addRule(new DBRule("LEADIS", "0", "=")); + } + if (isAdmin.equals(SearchType.yes)) { + query.addRule(new DBRule("LEADIS", "1", "=")); + } + if (isEditor.equals(SearchType.yes)) { + query.addRule(new DBRule("EDITIS", "1", "=")); + } + if (isEditor.equals(SearchType.no)) { + query.addRule(new DBRule("EDITIS", "0", "=")); + } + query.addRule(new DBRule("GROUPID", groupid, "=")); + query.addSort(new DBSort("LEADIS", "desc")); + DataResult result = null; + try { + result = query.search(); + } catch (SQLException e) { + log.error(e); + return DataResult.getInstance(); + } + return result; + } + + @Override + @Transactional + public boolean isAuditing(String groupId, String userid) { + FarmDocgroupUser du = getFarmDocgroupUser(groupId, userid); + if (du == null) { + return false; + } + if (du.getPstate().equals("3")) { + return true; + } + return false; + } + + @Override + public DataResult getGroupsByUser(String userid, int pagesize, Integer pagenum) { + DataQuery query = DataQuery.init(new DataQuery(), + "FARM_DOCGROUP as a left join FARM_DOCGROUP_USER as b on a.id=b.GROUPID", + "a.ID AS ID, a.CTIME AS CTIME, a.ETIME AS ETIME, a.CUSERNAME AS CUSERNAME, a.CUSER AS CUSER, a.EUSERNAME AS EUSERNAME, a.EUSER AS EUSER, a.PSTATE AS PSTATE, a.PCONTENT AS PCONTENT, a.GROUPNAME AS GROUPNAME, a.GROUPNOTE AS GROUPNOTE, a.GROUPTAG AS GROUPTAG, a.GROUPIMG AS GROUPIMG, a.JOINCHECK AS JOINCHECK, a.USERNUM AS USERNUM, a.HOMEDOCID AS HOMEDOCID, b.USERID AS USERID"); + query.addSort(new DBSort("a.USERNUM", "desc")); + query.addRule(new DBRule("b.USERID", userid, "=")); + query.setCurrentPage(pagenum); + query.setDistinct(true); + query.setPagesize(pagesize); + try { + DataResult result = query.search(); + result.runHandle(new ResultsHandle() { + @Override + public void handle(Map row) { + row.put("IMGURL", farmFileServer.getFileURL(row.get("GROUPIMG").toString())); + if (row.get("USERID") != null && !row.get("USERID").toString().isEmpty()) { + row.put("USERJOIN", "1"); + } else { + row.put("USERJOIN", "0"); + } + } + }); + return result; + } catch (SQLException e) { + log.error(e.toString()); + return DataResult.getInstance(); + } + } + + @Override + public DataResult getGroups(int pagesize, Integer pagenum) { + DataQuery query = DataQuery.init(new DataQuery(), "FARM_DOCGROUP as a ", + "a.ID AS ID, a.CTIME AS CTIME, a.ETIME AS ETIME, a.CUSERNAME AS CUSERNAME, a.CUSER AS CUSER, a.EUSERNAME AS EUSERNAME, a.EUSER AS EUSER, a.PSTATE AS PSTATE, a.PCONTENT AS PCONTENT, a.GROUPNAME AS GROUPNAME, a.GROUPNOTE AS GROUPNOTE, a.GROUPTAG AS GROUPTAG, a.GROUPIMG AS GROUPIMG, a.JOINCHECK AS JOINCHECK, a.USERNUM AS USERNUM, a.HOMEDOCID AS HOMEDOCID"); + query.addSort(new DBSort("a.USERNUM", "desc")); + query.setCurrentPage(pagenum); + query.setDistinct(true); + query.setPagesize(pagesize); + try { + DataResult result = query.search(); + result.runHandle(new ResultsHandle() { + @Override + public void handle(Map row) { + row.put("IMGURL", farmFileServer.getFileURL(row.get("GROUPIMG").toString())); + if (row.get("USERID") != null && !row.get("USERID").toString().isEmpty()) { + row.put("USERJOIN", "1"); + } else { + row.put("USERJOIN", "0"); + } + } + }); + return result; + } catch (SQLException e) { + log.error(e.toString()); + return DataResult.getInstance(); + } + } + + @Override + @Transactional + public List getAllGroup() { + return farmDocgroupDao.selectEntitys(null); + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocmessageManagerImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocmessageManagerImpl.java new file mode 100644 index 0000000..1e5b6b0 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmDocmessageManagerImpl.java @@ -0,0 +1,283 @@ +package com.farm.doc.server.impl; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.FarmDocDaoInter; +import com.farm.doc.dao.FarmDocmessageDaoInter; +import com.farm.doc.dao.FarmDocruninfoDaoInter; +import com.farm.doc.domain.Doc; +import com.farm.doc.domain.FarmDocmessage; +import com.farm.doc.domain.FarmDocruninfo; +import com.farm.doc.server.FarmDocRunInfoInter; +import com.farm.doc.server.FarmDocmessageManagerInter; +import com.farm.doc.server.UsermessageServiceInter; +import com.farm.doc.server.commons.DocMessageCache; + +/** + * 留言板 + * + * @author MAC_wd + */ +@Service +public class FarmDocmessageManagerImpl implements FarmDocmessageManagerInter { + @Resource + private FarmDocmessageDaoInter farmDocmessageDao; + @Resource + private FarmDocruninfoDaoInter farmDocruninfoDao; + @Resource + private FarmDocDaoInter farmDocDao; + @Resource + private FarmDocRunInfoInter farmDocRunInfoImpl; + @Resource + private UsermessageServiceInter usermessageServiceImpl; + // private static final Logger log = Logger + // .getLogger(FarmDocmessageManagerImpl.class); + private final static Logger log = Logger.getLogger(FarmDocmessageManagerImpl.class); + + @Transactional + public FarmDocmessage sendMessage(String readUserId, String text, String title, String note, String appId, + LoginUser sendUser) { + FarmDocmessage message = new FarmDocmessage(); + message.setCtime(TimeTool.getTimeDate14()); + message.setCuser(sendUser.getId()); + message.setCusername(sendUser.getName()); + message.setAppid(appId); + message.setContent(text); + message.setPcontent(note); + message.setPstate("1"); + message.setReadstate("0"); + message.setReaduserid(readUserId); + message.setTitle(title); + return farmDocmessageDao.insertEntity(message); + } + + @Transactional + public FarmDocmessage reSendMessage(String messageId, String text, LoginUser sendUser) { + FarmDocmessage obMes = farmDocmessageDao.getEntity(messageId); + FarmDocmessage message = new FarmDocmessage(); + message.setCtime(TimeTool.getTimeDate14()); + message.setCuser(sendUser.getId()); + message.setCusername(sendUser.getName()); + message.setAppid(obMes.getAppid()); + message.setContent(text); + message.setPcontent(obMes.getPcontent()); + message.setPstate("1"); + message.setReadstate("0"); + message.setReaduserid(obMes.getCuser()); + message.setTitle(obMes.getTitle()); + return farmDocmessageDao.insertEntity(message); + } + + @Transactional + public void deleteMessage(String entity, LoginUser user) { + farmDocmessageDao.deleteEntity(farmDocmessageDao.getEntity(entity)); + } + + @Transactional + public FarmDocmessage getMessage(String id) { + if (id == null) { + return null; + } + return farmDocmessageDao.getEntity(id); + } + + @Transactional + public FarmDocmessage readMessage(String id) { + if (id == null) { + return null; + } + FarmDocmessage obMes = farmDocmessageDao.getEntity(id); + obMes.setReadstate("1"); + farmDocmessageDao.editEntity(obMes); + return obMes; + } + + @Override + public DataQuery createMessageQuery(DataQuery query) { + DataQuery dbQuery = DataQuery.init(query, "farm_docmessage a left join alone_auth_user c on c.id=a.READUSERID ", + "a.id as id,a.CTIME as CTIME,a.CUSERNAME as CUSERNAME,a.CUSER as CUSER,a.PSTATE as PSTATE,a.PCONTENT as PCONTENT,a.READUSERID as READUSERID,c.name as READUSERNAME,a.CONTENT as CONTENT,a.TITLE as TITLE,a.APPID as APPID,a.READSTATE as READSTATE"); + return dbQuery; + } + + // ---------------------------------------------------------------------------------- + public FarmDocmessageDaoInter getfarmDocmessageDao() { + return farmDocmessageDao; + } + + public void setfarmDocmessageDao(FarmDocmessageDaoInter dao) { + this.farmDocmessageDao = dao; + } + + public FarmDocruninfoDaoInter getFarmDocruninfoDao() { + return farmDocruninfoDao; + } + + public void setFarmDocruninfoDao(FarmDocruninfoDaoInter farmDocruninfoDao) { + this.farmDocruninfoDao = farmDocruninfoDao; + } + + public FarmDocDaoInter getFarmDocDao() { + return farmDocDao; + } + + public void setFarmDocDao(FarmDocDaoInter farmDocDao) { + this.farmDocDao = farmDocDao; + } + + @Override + public FarmDocmessage sendMessage(String readUserId, String text, String title, String note, LoginUser sendUser) { + return sendMessage(readUserId, text, title, note, null, sendUser); + } + + @Override + public int getNoReadMessageNum(LoginUser user) { + return farmDocmessageDao.getNoReadMessageNum(user.getId()); + } + + @Override + @Transactional + public FarmDocmessage sendAnswering(String content, String title, String mark, String appid, LoginUser sendUser) { + FarmDocmessage message = new FarmDocmessage(); + message.setCtime(TimeTool.getTimeDate14()); + message.setCuser(sendUser.getId()); + message.setCusername(sendUser.getName()); + message.setAppid(appid); + message.setContent(content); + message.setPcontent(mark); + message.setPstate("1"); + message.setReadstate("0"); + message.setTitle(title); + message.setReaduserid("NONE"); + // 如果是文档就刷新文档的用量信息 + Doc doc = farmDocDao.getEntity(appid); + if (doc != null) { + FarmDocruninfo info = farmDocruninfoDao.getEntity(doc.getRuninfoid()); + int num = farmDocmessageDao.getAppMessageNum(appid); + info.setAnsweringnum(num + 1); + farmDocruninfoDao.editEntity(info); + } + // 发送消息给知识创建者和关注者 + usermessageServiceImpl.sendMessage(farmDocRunInfoImpl.getDocJoinUserIds(appid), + "知识" + doc.getTitle() + "收到一条评论:" + + content, + "收到一条知识评论"); + return farmDocmessageDao.insertEntity(message); + } + + @Override + public DataResult getMessages(String docid, int num, int pagesize) { + DataQuery dbQuery = DataQuery.init(new DataQuery(), + "FARM_DOCMESSAGE A " + "LEFT JOIN ALONE_AUTH_USER C ON C.ID=A.READUSERID " + + "LEFT JOIN ALONE_AUTH_USER D ON A.CUSER = D.ID", + "A.ID AS ID,A.CTIME AS CTIME,A.CUSERNAME AS CUSERNAME,A.CUSER AS CUSER," + + "A.PSTATE AS PSTATE,A.PCONTENT AS PCONTENT,A.READUSERID AS READUSERID," + + "C.NAME AS READUSERNAME,A.CONTENT AS CONTENT,A.TITLE AS TITLE,A.APPID AS APPID," + + "A.READSTATE AS READSTATE, D.IMGID AS IMGID, " + + "A.PRAISNUM AS PRAISNUM, A.CRITCISMNUM AS CRITCISMNUM"); + dbQuery.addRule(new DBRule("APPID", docid, "=")); + dbQuery.addSqlRule(" AND A.PARENTID IS NULL "); + dbQuery.addSort(new DBSort("CTIME", "DESC")); + dbQuery.setCurrentPage(num); + dbQuery.setPagesize(pagesize); + DataResult result = null; + try { + result = dbQuery.search(); + } catch (SQLException e) { + log.error(e.toString()); + return DataResult.getInstance(); + } + return result; + } + + @Override + @Transactional + public FarmDocmessage approveOf(String id, LoginUser loginUser) { + FarmDocmessage entity = farmDocmessageDao.getEntity(id); + if (!DocMessageCache.getInstance().add(loginUser.getId(), entity.getAppid(), entity.getId())) { + return entity; + } + + entity.setPraisnum(entity.getPraisnum() + 1); + farmDocmessageDao.editEntity(entity); + return entity; + } + + @Override + @Transactional + public FarmDocmessage oppose(String id, LoginUser loginUser) { + FarmDocmessage entity = farmDocmessageDao.getEntity(id); + if (!DocMessageCache.getInstance().add(loginUser.getId(), entity.getAppid(), entity.getId())) { + return entity; + } + + entity.setCritcismnum(entity.getCritcismnum() + 1); + farmDocmessageDao.editEntity(entity); + return entity; + } + + @Override + @Transactional + public void reply(String content, String appid, String messageId, LoginUser loginUser) { + FarmDocmessage entity = new FarmDocmessage(); + entity.setCtime(TimeTool.getTimeDate14()); + entity.setCuser(loginUser.getId()); + entity.setCusername(loginUser.getName()); + entity.setPstate("1"); + entity.setPcontent(""); + entity.setReadstate("1"); + entity.setTitle("回复"); + entity.setReaduserid(loginUser.getId()); + entity.setContent(content); + entity.setAppid(appid); + entity.setPraisnum(0); + entity.setCritcismnum(0); + entity.setParentid(messageId); + // 如果是文档就刷新文档的用量信息 + Doc doc = farmDocDao.getEntity(entity.getAppid()); + if (doc != null) { + FarmDocruninfo info = farmDocruninfoDao.getEntity(doc.getRuninfoid()); + int num = farmDocmessageDao.getAppMessageNum(entity.getAppid()); + info.setAnsweringnum(num + 1); + farmDocruninfoDao.editEntity(info); + } + farmDocmessageDao.insertEntity(entity); + FarmDocmessage parentMessage = farmDocmessageDao.getEntity(entity.getParentid()); + usermessageServiceImpl.sendMessage(parentMessage.getCuser(), + "知识" + doc.getTitle() + + "收到一条回复:" + content, + "收到一条评论回复"); + } + + @Override + public List> getReplys(String docid, String docMessageId) { + try { + DataQuery dbQuery = DataQuery.init(new DataQuery(), "FARM_DOCMESSAGE A ", + "A.ID AS ID, A.CONTENT AS CONTENT,CTIME,CUSERNAME,CUSER"); + + dbQuery.addRule(new DBRule("APPID", docid, "=")); + dbQuery.addRule(new DBRule("PARENTID", docMessageId, "=")); + dbQuery.addSort(new DBSort("CTIME", "DESC")); + dbQuery.setCurrentPage(1); + dbQuery.setPagesize(1000); + return dbQuery.search().getResultList(); + } catch (SQLException e) { + log.error(e.toString()); + return new ArrayList>(); + } + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmFileIndexManagerImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmFileIndexManagerImpl.java new file mode 100644 index 0000000..f990274 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmFileIndexManagerImpl.java @@ -0,0 +1,96 @@ +package com.farm.doc.server.impl; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Resource; +import javax.transaction.Transactional; + +import org.springframework.stereotype.Service; + +import com.farm.doc.domain.FarmDocfile; +import com.farm.doc.domain.FarmDocgroup; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.doc.domain.ex.TypeBrief; +import com.farm.doc.server.FarmDocIndexInter; +import com.farm.doc.server.FarmDocTypeInter; +import com.farm.doc.server.FarmDocgroupManagerInter; +import com.farm.doc.server.FarmFileIndexManagerInter; +import com.farm.doc.server.FarmFileManagerInter; + +@Service +public class FarmFileIndexManagerImpl implements FarmFileIndexManagerInter { + + @Resource + private FarmDocIndexInter farmDocIndexManagerImpl; + @Resource + private FarmFileManagerInter farmFileManagerImpl; + @Resource + private FarmDocTypeInter farmDocTypeManagerImpl; + @Resource + private FarmDocgroupManagerInter farmDocgroupManagerImpl; + + @Override + @Transactional + public void addFileLuceneIndex(String fileid, DocEntire doc, String text) { + farmDocIndexManagerImpl.delLuceneIndex(doc, fileid); + farmDocIndexManagerImpl.addLuceneIndex(fileid, farmFileManagerImpl.getFile(fileid).getName(), text, doc); + } + + @Override + @Transactional + public void delFileLucenneIndex(String fileid, DocEntire doc) { + farmDocIndexManagerImpl.delLuceneIndex(doc, fileid); + } + + @Override + @Transactional + public void delFileLucenneIndexs(List originalfiles, List newfiles, DocEntire doc) { + for (FarmDocfile file : originalfiles) { + boolean isHave = false; + for (FarmDocfile filenew : newfiles) { + if (file.getId().equals(filenew.getId())) { + isHave = true; + } + } + if (!isHave) { + delFileLucenneIndex(file.getId(), doc); + } + } + } + + @Override + @Transactional + public void delFileLucenneIndex(String fileid) { + // 在所有分类和小组中删除该知识 + List types = farmDocTypeManagerImpl.getPubTypes(); + List types_str = new ArrayList<>(); + for (TypeBrief type : types) { + types_str.add(type.getId()); + } + List groups = farmDocgroupManagerImpl.getAllGroup(); + List groups_str = new ArrayList<>(); + for (FarmDocgroup group : groups) { + groups_str.add(group.getId()); + } + farmDocIndexManagerImpl.delLuceneIndex(fileid, types_str, groups_str); + } + + @Override + public void handleFileLucenneIndexBymoveType(DocEntire oldDoce, DocEntire newdoc) { + // 判断知识是否为资源文件,非资源知识不处理 + if (!newdoc.getDoc().getDomtype().equals("5")) { + return; + } + // 判断是否移动了分类,未移动分类不处理 + if (oldDoce.getType().getId().equals(newdoc.getType().getId())) { + return; + } + // 判断新的分类是否是被限制访问权限的,被限制的分类需要删除索引 + if (!newdoc.getType().getReadpop().equals("0")) { + for (FarmDocfile file : oldDoce.getFiles()) { + delFileLucenneIndex(file.getId(), oldDoce); + } + } + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmFileManagerImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmFileManagerImpl.java new file mode 100644 index 0000000..a3241f0 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmFileManagerImpl.java @@ -0,0 +1,267 @@ +package com.farm.doc.server.impl; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.annotation.Resource; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.FarmDocfileDaoInter; +import com.farm.doc.dao.FarmRfDoctextfileDaoInter; +import com.farm.doc.domain.FarmDocfile; +import com.farm.doc.domain.FarmRfDoctextfile; +import com.farm.doc.server.FarmFileManagerInter; +import com.farm.doc.server.commons.DocumentConfig; +import com.farm.doc.server.commons.FarmDocFiles; +import com.farm.parameter.FarmParameterService; + +@Service +public class FarmFileManagerImpl implements FarmFileManagerInter { + @Resource + private FarmDocfileDaoInter farmDocfileDao; + @Resource + private FarmRfDoctextfileDaoInter farmRfDoctextfileDao; + private static final Logger log = Logger.getLogger(FarmFileManagerImpl.class); + /** + * 附件信息缓存 + */ + private static final Map fileCatch = new HashMap(); + + @Override + @Transactional + public String saveFile(File file, FILE_TYPE type, String title, LoginUser user) { + String exName = FarmDocFiles.getExName(title); + if (exName.trim().toUpperCase().replace(".", "").equals("ZIP")) { + type = FILE_TYPE.RESOURCE_ZIP; + } + String userId = null; + String userName = null; + if (user == null || user.getName() == null) { + userId = "none"; + userName = "none"; + } else { + userId = user.getId(); + userName = user.getName(); + } + FarmDocfile docfile = new FarmDocfile(FarmDocFiles.generateDir(), + UUID.randomUUID().toString().replaceAll("-", ""), type.getValue(), title, file.getName(), + TimeTool.getTimeDate14(), TimeTool.getTimeDate14(), userName, userId, userName, userId, "0", null, + exName, Float.valueOf(String.valueOf(file.length()))); + if (user == null || user.getName() == null) { + docfile.setCusername("none"); + docfile.setEusername("none"); + } + FarmDocFiles.copyFile(file, FarmDocFiles.getFileDirPath() + docfile.getDir()); + docfile = farmDocfileDao.insertEntity(docfile); + + return docfile.getId(); + } + + public String saveFile(InputStream inStream, String filename, String title, FILE_TYPE type, LoginUser user) { + String exName = FarmDocFiles.getExName(title); + if (exName.trim().toUpperCase().replace(".", "").equals("ZIP")) { + type = FILE_TYPE.RESOURCE_ZIP; + } + String userId = null; + String userName = null; + if (user == null || user.getName() == null) { + userId = "none"; + userName = "none"; + } else { + userId = user.getId(); + userName = user.getName(); + } + FarmDocfile docfile = new FarmDocfile(FarmDocFiles.generateDir(), + UUID.randomUUID().toString().replaceAll("-", ""), type.getValue(), title, filename, + TimeTool.getTimeDate14(), TimeTool.getTimeDate14(), userName, userId, userName, userId, "0", null, + exName, Float.valueOf(String.valueOf(0))); + if (user == null || user.getName() == null) { + docfile.setCusername("none"); + docfile.setEusername("none"); + } + long length = FarmDocFiles.saveFile(inStream, filename, + DocumentConfig.getString("config.doc.dir") + docfile.getDir()); + docfile.setLen(Float.valueOf(String.valueOf(length))); + docfile = farmDocfileDao.insertEntity(docfile); + return docfile.getId(); + } + + @Override + public String getFileURL(String fileid) { + String url = DocumentConfig.getString("config.doc.download.url") + fileid; + return url; + } + + @Override + @Transactional + public FarmDocfile getFile(String fileid) { + if (fileCatch.containsKey(fileid)) { + log.debug("load file from catch"); + return fileCatch.get(fileid); + } + FarmDocfile file = farmDocfileDao.getEntity(fileid); + if (file == null) { + return null; + } + file.setFile(new File(FarmDocFiles.getFileDirPath() + File.separator + file.getDir() + file.getFilename())); + // 如果文件是大小是0的话就刷新文件大小 + if (file.getLen() == 0) { + file.setLen(Float.valueOf(String.valueOf(file.getFile().length()))); + if (file.getLen() == 0) { + file.setLen(Float.valueOf(-1)); + } + farmDocfileDao.editEntity(file); + } + if (fileCatch.size() < 10000) { + fileCatch.put(fileid, file); + } + return file; + } + + @Override + public File getNoneImg() { + String imgpath = FarmParameterService.getInstance().getParameter("config.doc.none.img.path"); + return new File(FarmParameterService.getInstance().getParameter("farm.constant.webroot.path") + File.separator + + imgpath.replaceAll("\\\\", File.separator).replaceAll("//", File.separator)); + } + + @Override + @Transactional + public void submitFile(String fileId) { + FarmDocfile file = farmDocfileDao.getEntity(fileId); + file.setPstate("1"); + file.setEtime(TimeTool.getTimeDate14()); + farmDocfileDao.editEntity(file); + } + + @Override + @Transactional + public void cancelFile(String fileId) { + FarmDocfile file = farmDocfileDao.getEntity(fileId); + if (file == null) { + return; + } + file.setPstate("0"); + farmDocfileDao.editEntity(file); + } + + @Override + @Transactional + public void delFile(String fileId, LoginUser user) { + FarmDocfile docfile = farmDocfileDao.getEntity(fileId); + if (docfile == null) { + return; + } + File file = this.getFile(fileId).getFile(); + farmDocfileDao.deleteEntity(docfile); + if (file.exists()) { + if (file.delete()) { + log.info("删除成功!"); + } else { + log.error("文件删除失败,未能删除请手动删除!"); + } + } + } + + @Override + @Transactional + public FarmDocfile openFile(String exname, String content, LoginUser user) { + FILE_TYPE type = FILE_TYPE.OHTER; + String filename = UUID.randomUUID().toString(); + FarmDocfile docfile = new FarmDocfile(FarmDocFiles.generateDir(), + UUID.randomUUID().toString().replaceAll("-", ""), type.getValue(), filename + "." + exname, + filename + ".tmp", TimeTool.getTimeDate14(), TimeTool.getTimeDate14(), user.getName(), user.getId(), + user.getName(), user.getId(), "0", content, exname, Float.valueOf(0)); + + File file = new File(FarmDocFiles.getFileDirPath() + docfile.getDir() + File.separator + docfile.getFilename()); + try { + if (!file.createNewFile()) { + throw new RuntimeException("文件创建失败!"); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + docfile = farmDocfileDao.insertEntity(docfile); + docfile.setFile(file); + return docfile; + } + + @Override + @Transactional + public void addFileForDoc(String docid, String fileId, LoginUser user) { + farmRfDoctextfileDao.insertEntity(new FarmRfDoctextfile(docid, fileId)); + } + + @Override + @Transactional + public void delFileForDoc(String docid, String fileId, LoginUser user) { + List list = new ArrayList(); + list.add(new DBRule("FILEID", fileId, "=")); + list.add(new DBRule("DOCID", docid, "=")); + farmRfDoctextfileDao.deleteEntitys(list); + } + + @Override + public List getAllFileForDoc(String docid) { + List refiles = farmDocfileDao.getEntityByDocId(docid); + for (FarmDocfile file : refiles) { + file = getFile(file.getId()); + } + return refiles; + } + + @Override + public List getAllTypeFileForDoc(String docid, String exname) { + List refiles = farmDocfileDao.getEntityByDocId(docid); + List newrefiles = new ArrayList(); + for (FarmDocfile file : refiles) { + if (file.getExname().toUpperCase().equals(exname.toUpperCase())) { + file = getFile(file.getId()); + newrefiles.add(file); + } + } + return newrefiles; + } + + @Override + public boolean containFileByDoc(String docid, String fileId) { + List list = farmDocfileDao.getEntityByDocId(docid); + for (FarmDocfile node : list) { + if (node.getId().equals(fileId)) { + return true; + } + } + return false; + } + + @Override + public void delAllFileForDoc(String docid, String exname, LoginUser aloneUser) { + List refiles = farmDocfileDao.getEntityByDocId(docid); + for (FarmDocfile file : refiles) { + if (file.getExname().toUpperCase().equals(exname.toUpperCase())) { + delFileForDoc(docid, file.getId(), aloneUser); + } + } + + } + + @Override + @Transactional + public void delFileForDoc(String docid, LoginUser user) { + List list = new ArrayList(); + list.add(new DBRule("DOCID", docid, "=")); + farmRfDoctextfileDao.deleteEntitys(list); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmtopServiceImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmtopServiceImpl.java new file mode 100644 index 0000000..17d162e --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/FarmtopServiceImpl.java @@ -0,0 +1,104 @@ +package com.farm.doc.server.impl; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.FarmtopDaoInter; +import com.farm.doc.domain.Farmtop; +import com.farm.doc.server.FarmtopServiceInter; + +/* * + *功能:置顶文档服务层实现类 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Service +public class FarmtopServiceImpl implements FarmtopServiceInter { + @Resource + private FarmtopDaoInter farmtopDaoImpl; + + + @Override + @Transactional + public Farmtop insertFarmtopEntity(Farmtop entity, LoginUser user) { + entity.setCtime(TimeTool.getTimeDate14()); + entity.setCuser(user.getId()); + entity.setCusername(user.getName()); + entity.setPstate("1"); + return farmtopDaoImpl.insertEntity(entity); + } + + @Override + @Transactional + public Farmtop editFarmtopEntity(Farmtop entity, LoginUser user) { + Farmtop entity2 = farmtopDaoImpl.getEntity(entity.getId()); + entity2.setSort(entity.getSort()); + entity2.setDocid(entity.getDocid()); + entity2.setPcontent(entity.getPcontent()); + farmtopDaoImpl.editEntity(entity2); + return entity2; + } + + @Override + @Transactional + public void deleteFarmtopEntity(String id, LoginUser user) { + + farmtopDaoImpl.deleteEntity(farmtopDaoImpl.getEntity(id)); + } + + @Override + @Transactional + public Farmtop getFarmtopEntity(String id) { + + if (id == null) { + return null; + } + return farmtopDaoImpl.getEntity(id); + } + + @Override + @Transactional + public DataQuery createFarmtopSimpleQuery(DataQuery query) { + DataQuery dbQuery = DataQuery + .init(query, + "FARM_TOP TOP " + + "LEFT JOIN FARM_DOC A ON TOP.DOCID = A.ID and a.STATE='1'" + + "LEFT JOIN FARM_RF_DOCTYPE B ON B.DOCID =A.ID " + + "LEFT JOIN FARM_DOCTYPE C ON C.ID=B.TYPEID " + + "LEFT JOIN FARM_DOCGROUP D ON D.ID=A.DOCGROUPID " + + "LEFT JOIN FARM_DOCRUNINFO DOCRUNINFO ON A.RUNINFOID = DOCRUNINFO.ID", + "TOP.ID AS ID, TOP.SORT AS SORT, A.DOCDESCRIBE AS DOCDESCRIBE,A.WRITEPOP AS WRITEPOP," + + "A.READPOP AS READPOP,A.TITLE AS TITLE,A.AUTHOR AS AUTHOR,A.PUBTIME AS PUBTIME," + + "A.DOMTYPE AS DOMTYPE,A.SHORTTITLE AS SHORTTITLE,A.TAGKEY AS TAGKEY,A.STATE AS STATE," + + "D.GROUPNAME AS GROUPNAME, DOCRUNINFO.VISITNUM AS VISITNUM, DOCRUNINFO.ANSWERINGNUM AS ANSWERINGNUM, " + + "A.IMGID AS IMGID, A.ID AS DOCID"); + return dbQuery; + + } + + + @Override + public DataQuery docTopChooseDocList(DataQuery query) { + DataQuery dbQuery = DataQuery + .init(query, + "FARM_DOC A " + + "LEFT JOIN FARM_RF_DOCTYPE B ON B.DOCID =A.ID " + + "LEFT JOIN FARM_DOCTYPE C ON C.ID=B.TYPEID " + + "LEFT JOIN farm_docgroup d ON d.ID=a.DOCGROUPID", + "A.ID AS ID,A.DOCDESCRIBE as DOCDESCRIBE,A.WRITEPOP as WRITEPOP,A.READPOP as READPOP,A.TITLE AS TITLE,A.AUTHOR AS AUTHOR,A.PUBTIME AS PUBTIME,A.DOMTYPE AS DOMTYPE,A.SHORTTITLE AS SHORTTITLE,A.TAGKEY AS TAGKEY,A.STATE AS STATE,D.GROUPNAME AS GROUPNAME "); + + dbQuery.addSqlRule(" AND NOT EXISTS (SELECT 1 FROM FARM_TOP TOP_ WHERE A.ID = TOP_.DOCID) "); + return dbQuery; + + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/UsermessageServiceImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/UsermessageServiceImpl.java new file mode 100644 index 0000000..57615fa --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/UsermessageServiceImpl.java @@ -0,0 +1,159 @@ +package com.farm.doc.server.impl; + +import java.sql.SQLException; +import java.util.List; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DBSort; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.result.DataResult; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.UsermessageDaoInter; +import com.farm.doc.domain.Usermessage; +import com.farm.doc.server.UsermessageServiceInter; + +/* * + *功能:用户消息服务层实现类 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Service +public class UsermessageServiceImpl implements UsermessageServiceInter { + @Resource + private UsermessageDaoInter usermessageDaoImpl; + @Override + @Transactional + public Usermessage insertUsermessageEntity(Usermessage entity, LoginUser user) { + entity.setCtime(TimeTool.getTimeDate12()); + entity.setCuser(user.getId()); + entity.setCusername(user.getName()); + entity.setPstate("1"); + return usermessageDaoImpl.insertEntity(entity); + } + + @Override + @Transactional + public Usermessage editUsermessageEntity(Usermessage entity, LoginUser user) { + Usermessage entity2 = usermessageDaoImpl.getEntity(entity.getId()); + entity2.setContent(entity.getContent()); + entity2.setReadstate(entity.getReadstate()); + entity2.setReaduserid(entity.getReaduserid()); + entity2.setTitle(entity.getTitle()); + usermessageDaoImpl.editEntity(entity2); + return entity2; + } + + @Override + @Transactional + public void deleteUsermessageEntity(String id, LoginUser user) { + + usermessageDaoImpl.deleteEntity(usermessageDaoImpl.getEntity(id)); + } + + @Override + @Transactional + public Usermessage getUsermessageEntity(String id) { + + if (id == null) { + return null; + } + return usermessageDaoImpl.getEntity(id); + } + + @Override + @Transactional + public DataQuery createUsermessageSimpleQuery(DataQuery query) { + + DataQuery dbQuery = DataQuery.init(query, + "FARM_USERMESSAGE USERMESSAGE " + "LEFT JOIN ALONE_AUTH_USER USER ON USERMESSAGE.READUSERID = USER.ID", + "USERMESSAGE.ID AS ID, USERMESSAGE.CTIME AS USERMESSAGECTIME, USERMESSAGE.READUSERID AS READUSERID,USERMESSAGE.CONTENT AS CONTENT," + + "USERMESSAGE.TITLE AS TITLE,USERMESSAGE.READSTATE AS READSTATE,USERMESSAGE.PCONTENT AS PCONTENT," + + "USERMESSAGE.PSTATE AS PSTATE,USERMESSAGE.CUSERNAME AS CUSERNAME,USERMESSAGE.CUSER AS CUSER," + + "USERMESSAGE.CTIME AS CTIME, USER.NAME AS READUSERNAME"); + return dbQuery; + } + + // ---------------------------------------------------------------------------------- + public UsermessageDaoInter getUsermessageDaoImpl() { + return usermessageDaoImpl; + } + + public void setUsermessageDaoImpl(UsermessageDaoInter dao) { + this.usermessageDaoImpl = dao; + } + + @Override + @Transactional + public void setRead(String id) { + Usermessage entity = usermessageDaoImpl.getEntity(id); + entity.setReadstate("1"); + } + + @Override + @Transactional + public void sendMessage(String readUserId, String text, String title, String note, LoginUser sendUser) { + Usermessage message = new Usermessage(); + message.setContent(text); + message.setCtime(TimeTool.getTimeDate14()); + if (sendUser != null) { + message.setCuser(sendUser.getId()); + message.setCusername(sendUser.getName()); + } else { + message.setCuser("SYS"); + message.setCusername("系统消息"); + } + if (note != null) { + message.setPcontent(note); + } + message.setPstate("1"); + message.setReadstate("0"); + message.setReaduserid(readUserId); + message.setTitle(title); + usermessageDaoImpl.insertEntity(message); + } + + @Override + @Transactional + public void sendMessage(String readUserId, String text, String title, LoginUser sendUser) { + sendMessage(readUserId, text, title, null, sendUser); + } + + @Override + @Transactional + public void sendMessage(String readUserId, String text, String title) { + sendMessage(readUserId, text, title, null, null); + } + + @Override + @Transactional + public void sendMessage(List userids, String text, String title) { + for (String id : userids) { + sendMessage(id, text, title); + } + } + + @Override + public DataResult getMyMessageByUser(String userId, int pageSize, Integer currPage) { + DataQuery query = createUsermessageSimpleQuery(null); + query.addRule(new DBRule("USERMESSAGE.READUSERID", userId, "=")); + query.addSort(new DBSort("USERMESSAGE.CTIME", "DESC")); + query.setCurrentPage(currPage); + query.setPagesize(pageSize); + try { + return query.search(); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/server/impl/WeburlServiceImpl.java b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/WeburlServiceImpl.java new file mode 100644 index 0000000..c78016e --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/server/impl/WeburlServiceImpl.java @@ -0,0 +1,146 @@ +package com.farm.doc.server.impl; + +import java.sql.SQLException; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.farm.core.auth.domain.LoginUser; +import com.farm.core.sql.query.DBRule; +import com.farm.core.sql.query.DataQuery; +import com.farm.core.sql.query.DataQuery.CACHE_UNIT; +import com.farm.core.sql.result.DataResult; +import com.farm.core.sql.result.ResultsHandle; +import com.farm.core.time.TimeTool; +import com.farm.doc.dao.WeburlDaoInter; +import com.farm.doc.domain.Weburl; +import com.farm.doc.server.FarmFileManagerInter; +import com.farm.doc.server.WeburlServiceInter; +import com.farm.doc.server.commons.DocumentConfig; +import com.farm.parameter.FarmParameterService; + +/* * + *功能:推荐服务服务层实现类 + *详细: + * + *版本:v0.1 + *作者:FarmCode代码工程 + *日期:20150707114057 + *说明: + */ +@Service +public class WeburlServiceImpl implements WeburlServiceInter { + @Resource + private WeburlDaoInter weburlDaoImpl; + @Resource + private FarmFileManagerInter farmFileServer; + + @Override + @Transactional + public Weburl insertWeburlEntity(Weburl entity, LoginUser user) { + entity.setCuser(user.getId()); + entity.setCtime(TimeTool.getTimeDate14()); + entity.setCusername(user.getName()); + entity.setEuser(user.getId()); + entity.setEusername(user.getName()); + entity.setEtime(TimeTool.getTimeDate14()); + entity.setPstate("1"); + return weburlDaoImpl.insertEntity(entity); + } + + @Override + @Transactional + public Weburl editWeburlEntity(Weburl entity, LoginUser user) { + Weburl entity2 = weburlDaoImpl.getEntity(entity.getId()); + entity2.setWebname(entity.getWebname()); + entity2.setUrl(entity.getUrl()); + entity2.setEusername(user.getName()); + entity2.setEuser(user.getId()); + entity2.setEtime(TimeTool.getTimeDate12()); + entity2.setFileid(entity.getFileid()); + weburlDaoImpl.editEntity(entity2); + return entity2; + } + + @Override + @Transactional + public void deleteWeburlEntity(String id, LoginUser user) { + + weburlDaoImpl.deleteEntity(weburlDaoImpl.getEntity(id)); + } + + @Override + @Transactional + public Weburl getWeburlEntity(String id) { + + if (id == null) { + return null; + } + return weburlDaoImpl.getEntity(id); + } + + @Override + @Transactional + public DataQuery createWeburlSimpleQuery(DataQuery query) { + + DataQuery dbQuery = DataQuery + .init(query, "FARM_WEBURL", + "ID,WEBNAME,URL,CTIME,ETIME,CUSERNAME,CUSER,EUSERNAME,EUSER,PCONTENT,PSTATE,SORT,FILEID"); + return dbQuery; + } + + // ---------------------------------------------------------------------------------- + public WeburlDaoInter getWeburlDaoImpl() { + return weburlDaoImpl; + } + + public void setWeburlDaoImpl(WeburlDaoInter dao) { + this.weburlDaoImpl = dao; + } + + @Override + @Transactional + public List> getList() { + try { + DataQuery query = createWeburlSimpleQuery(null); + query.setNoCount(); + query.setPagesize(100); + query.setCache(Integer.valueOf(FarmParameterService.getInstance().getParameter("config.wcp.cache.brief")), + CACHE_UNIT.second); + DataResult result = query.search(); + result.runHandle(new ResultsHandle() { + @Override + public void handle(Map row) { + if(row.get("FILEID") != null && !row.get("FILEID").toString().isEmpty()){ + String imgUrl = DocumentConfig.getString("config.doc.download.url") + row.get("FILEID"); + row.put("IMGURL", imgUrl); + }else{ + row.put("IMGURL", "text/img/none.png"); + } + } + }); + List> list = result.getResultList(); + return list; + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + @Override + @Transactional + public void delImg(String imgid) { + //清空图片字段 + List list = weburlDaoImpl.selectEntitys(new DBRule("FILEID", imgid, "=").getDBRules()); + for(Weburl weburl : list){ + weburl.setFileid(null); + } + + //删除附件表和附件 + farmFileServer.delFile(imgid, null); + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/util/ArticleController .java b/src/wcp-doc/src/main/java/com/farm/doc/util/ArticleController .java new file mode 100644 index 0000000..143fb89 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/util/ArticleController .java @@ -0,0 +1,40 @@ +package com.example.fulltextsearch.controller; + +import com.example.fulltextsearch.model.Article; +import com.example.fulltextsearch.service.ArticleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +//创建控制器 +//创建一个控制器来处理HTTP请求: +@RestController +@RequestMapping("/articles") +public class ArticleController { + + // 声明一个私有常量,用于注入ArticleService对象 + private final ArticleService articleService; + + // 构造方法,用于通过依赖注入的方式初始化articleService + @Autowired + public ArticleController(ArticleService articleService) { + this.articleService = articleService; + } + + // 处理POST请求,用于添加新的文章 + // @RequestBody注解表示从请求体中获取Article对象 + @PostMapping + public Article addArticle(@RequestBody Article article) { + // 调用articleService的saveArticle方法保存文章,并返回保存后的文章对象 + return articleService.saveArticle(article); + } + + // 处理GET请求,用于根据关键词搜索文章 + // @RequestParam注解表示从请求参数中获取名为"keyword"的参数值 + @GetMapping("/search") + public List
searchArticles(@RequestParam String keyword) { + // 调用articleService的searchArticles方法搜索文章,并返回搜索结果列表 + return articleService.searchArticles(keyword); + } +} + diff --git a/src/wcp-doc/src/main/java/com/farm/doc/util/DocTagUtils.java b/src/wcp-doc/src/main/java/com/farm/doc/util/DocTagUtils.java new file mode 100644 index 0000000..0e5b2d5 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/util/DocTagUtils.java @@ -0,0 +1,21 @@ +package com.farm.doc.util; + +import java.util.List; + +import com.farm.lucene.face.WordAnalyzerFace; + +public class DocTagUtils { + public static String getTags(String text) { + String tag = ""; + List taglist = WordAnalyzerFace + .parseHtmlWordCaseForSortList(HtmlUtils.HtmlRemoveTag(text)); + for (Object[] Object : taglist.size() > 10 ? taglist.subList(0, 10) + : taglist) { + if (tag != null) { + tag = tag + ","; + } + tag = tag + Object[0]; + } + return tag; + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/util/DocToString.java b/src/wcp-doc/src/main/java/com/farm/doc/util/DocToString.java new file mode 100644 index 0000000..73e3153 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/util/DocToString.java @@ -0,0 +1,18 @@ +package com.farm.doc.util; + +import java.io.File; +import java.util.List; + +public class DocToString { + + public static String getText(List files) { + StringBuffer str = new StringBuffer(); + str.append(getTextByDoc(files)); + return str.toString(); + } + + public static String getTextByDoc(Object obj) { + return null; + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/util/HtmlUtils.java b/src/wcp-doc/src/main/java/com/farm/doc/util/HtmlUtils.java new file mode 100644 index 0000000..595629d --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/util/HtmlUtils.java @@ -0,0 +1,51 @@ +package com.farm.doc.util; + +import java.util.regex.Pattern; + +public class HtmlUtils { + /** + * 删除Html标签 + * + * @param inputString + * @return + */ + public static String HtmlRemoveTag(String html) { + if (html == null) + return null; + String htmlStr = html; // 含html标签的字符串 + String textStr = ""; + java.util.regex.Pattern p_script; + java.util.regex.Matcher m_script; + java.util.regex.Pattern p_style; + java.util.regex.Matcher m_style; + java.util.regex.Pattern p_html; + java.util.regex.Matcher m_html; + + try { + String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义script的正则表达式{或]*?>[\\s\\S]*?<\\/script> + // } + String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或]*?>[\\s\\S]*?<\\/style> + // } + String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式 + + p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE); + m_script = p_script.matcher(htmlStr); + htmlStr = m_script.replaceAll(""); // 过滤script标签 + + p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE); + m_style = p_style.matcher(htmlStr); + htmlStr = m_style.replaceAll(""); // 过滤style标签 + + p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE); + m_html = p_html.matcher(htmlStr); + htmlStr = m_html.replaceAll(""); // 过滤html标签 + + textStr = htmlStr; + + } catch (Exception e) { + // System.err.println("Html2Text: " + e.getMessage()); + } + + return textStr.replaceAll("\\s*", "");// 返回文本字符串 + } +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/util/LuceneDocUtil.java b/src/wcp-doc/src/main/java/com/farm/doc/util/LuceneDocUtil.java new file mode 100644 index 0000000..69b21c2 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/util/LuceneDocUtil.java @@ -0,0 +1,58 @@ +package com.farm.doc.util; + +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; + +import com.farm.doc.domain.FarmDoctype; +import com.farm.doc.domain.ex.DocEntire; +import com.farm.lucene.adapter.DocMap; + +/** + * 生成全文检索时辅助生成索引元数据对象 + * + * @author Administrator + * + */ +public class LuceneDocUtil { + public static DocMap getDocMap(DocEntire doc) { + String text = ""; + if (doc.getTexts() != null) { + text = doc.getTexts().getText1(); + } + text = HtmlUtils.HtmlRemoveTag(text); + DocMap map = new DocMap(doc.getDoc().getId()); + String typeAll = ""; + // 拼接所有上级分类用于索引 + if (doc.getCurrenttypes() != null) { + for (FarmDoctype node : doc.getCurrenttypes()) { + if (typeAll.equals("")) { + typeAll = node.getName(); + } else { + typeAll = typeAll + "/" + node.getName(); + } + } + map.put("TYPENAME", typeAll, Store.YES, Index.ANALYZED); + map.put("TYPEID", doc.getType().getId(), Store.YES, Index.NO); + } + map.put("TAGKEY", doc.getDoc().getTagkey(), Store.YES, Index.ANALYZED); + map.put("TITLE", doc.getDoc().getTitle(), Store.YES, Index.ANALYZED); + map.put("AUTHOR", doc.getDoc().getAuthor(), Store.YES, Index.ANALYZED); + map.put("DOCDESCRIBE", doc.getDoc().getDocdescribe(), Store.YES, Index.ANALYZED); + map.put("VISITNUM", "0", Store.YES, Index.ANALYZED); + map.put("PUBTIME", doc.getDoc().getPubtime(), Store.YES, Index.ANALYZED); + map.put("USERID", doc.getDoc().getCuser(), Store.YES, Index.ANALYZED); + map.put("DOMTYPE", doc.getDoc().getDomtype(), Store.YES, Index.ANALYZED); + map.put("TEXT", text, Store.YES, Index.ANALYZED); + map.put("DOCID", doc.getDoc().getId(), Store.YES, Index.ANALYZED); + return map; + } + + public static DocMap convertFileMap(DocMap docmap, String fileId, String title, String text) { + docmap.put("DOCID",docmap.getValue("ID"), Store.YES, Index.ANALYZED); + docmap.put("ID", fileId, Store.YES, Index.ANALYZED); + docmap.put("DOMTYPE", "file", Store.YES, Index.ANALYZED); + docmap.put("TEXT", text, Store.YES, Index.ANALYZED); + docmap.put("TITLE", title, Store.YES, Index.ANALYZED); + return docmap; + } +} \ No newline at end of file diff --git a/src/wcp-doc/src/main/java/com/farm/doc/util/MailSender.java b/src/wcp-doc/src/main/java/com/farm/doc/util/MailSender.java new file mode 100644 index 0000000..13b4100 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/util/MailSender.java @@ -0,0 +1,237 @@ +package com.farm.doc.util; + +import java.util.*; +import javax.mail.*; +import javax.mail.internet.*; +import javax.activation.*; + +public class MailSender { + public MimeMessage mimeMsg; // 要发送的email信息 + private Session session; + private Properties props; + + private String username = ""; + private String password = ""; + + private Multipart mp; // 存放邮件的title 内容和附件 + + public MailSender(MailSenderConf conf) { + setSmtpHost(conf.getStmp()); + username = conf.getUsername(); + password = conf.getPassword(); + createMimeMessage(); + } + + /** + * + * @param hostName + */ + public void setSmtpHost(String hostName) { + System.out.println("mail.stmp.host= " + hostName); + if (props == null) { + props = System.getProperties(); + } + props.put("mail.smtp.host", hostName); + } + + public boolean createMimeMessage() { + try { + System.out.println("Session begin-----------"); + session = Session.getInstance(props, null); + } catch (Exception e) { + System.out.println("Session.getInstance faild!" + e); + return false; + } + System.out.println("MimeMEssage begin---------!"); + try { + mimeMsg = new MimeMessage(session); + mp = new MimeMultipart(); + return true; + } catch (Exception e) { + System.out.println("MimeMessage fiald! " + e.toString()); + return false; + } + } + + /** + * + * @param need + */ + public void setNeedAuth(boolean need) { + System.out.println(":mail.smtp.auth=" + need); + if (props == null) { + props = System.getProperties(); + } + if (need) { + props.put("mail.smtp.auth", "true"); + } else { + props.put("mail.smtp.auth", "false"); + } + } + + /** + * + * @param name + * @param pass + */ + public void setNamePass(String name, String pass) { + username = name; + password = pass; + } + + /** + * + * @param mailSubject + * @return boolean + */ + public boolean setSubject(String mailSubject) { + System.out.println("set title begin."); + try { + if (!mailSubject.equals("") && mailSubject != null) { + mimeMsg.setSubject(mailSubject); + } + return true; + } catch (Exception e) { + System.out.println("set Title faild!"); + return false; + } + } + + /** + * 添加附件.. + * + * @param filename + * @return + */ + public boolean addFileAffix(String filename) { + System.out.println("增加附件.."); + if (filename.equals("") || filename == null) { + return false; + } + String file[]; + file = filename.split(";"); + System.out.println("你有 " + file.length + " 个附件!"); + try { + for (int i = 0; i < file.length; i++) { + BodyPart bp = new MimeBodyPart(); + FileDataSource fileds = new FileDataSource(file[i]); + bp.setDataHandler(new DataHandler(fileds)); + bp.setFileName(fileds.getName()); + mp.addBodyPart(bp); + } + return true; + } catch (Exception e) { + System.err.println("增加附件: " + filename + "--faild!" + e); + return false; + } + } + + /** + * + * @param from + * @return + */ + public boolean setFrom(String from) { + System.out.println("Set From ."); + try { + mimeMsg.setFrom(new InternetAddress(from)); + return true; + } catch (Exception e) { + return false; + } + } + + /** + * + * @param to + * @return + */ + public boolean setTo(String to) { + System.out.println("Set to."); + if (to == null || to.equals("")) { + return false; + } + try { + mimeMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); + return true; + } catch (Exception e) { + return false; + } + } + + public boolean setCopyTo(String copyto) { + if (copyto.equals("") || copyto == null) { + return false; + } + try { + String copy[]; + copy = copyto.split(";"); + for (int i = 0; i < copy.length; i++) { + mimeMsg.setRecipients(Message.RecipientType.TO, (Address[]) InternetAddress.parse(copy[i])); + } + return true; + } catch (Exception e) { + return false; + } + } + + /** + * 设置信的内容! + * + * @param mailBody + * @return boolean + */ + public boolean setBody(String mailBody) { + try { + BodyPart bp = new MimeBodyPart(); + bp.setContent("" + mailBody, + "text/html;charset=GB2312"); + mp.addBodyPart(bp); + return true; + } catch (Exception e) { + System.out.println("Set context Faild! " + e); + return false; + } + } + + /** + * + * @param htmlpath + * @return boolean + */ + public boolean setHtml(String htmlpath) { + try { + if (!htmlpath.equals("") || htmlpath != null) { + BodyPart mbp = new MimeBodyPart(); + DataSource ds = new FileDataSource(htmlpath); + mbp.setDataHandler(new DataHandler(ds)); + mbp.setHeader("Context-ID", "meme"); + mp.addBodyPart(mbp); + } + return true; + } catch (Exception e) { + System.err.println("Set Html Faild!" + e); + return false; + } + } + + public boolean setOut() { + try { + mimeMsg.setContent(mp); + mimeMsg.saveChanges(); + System.out.println("正在SendMail."); + Session mailSession = session.getInstance(props, null); + Transport tp = mailSession.getTransport("smtp"); + tp.connect((String) props.getProperty("mail.stmp.host"), username, password); + tp.sendMessage(mimeMsg, mimeMsg.getRecipients(Message.RecipientType.TO)); + // tp.sendMessage(mimeMsg,mimeMsg.getRecipients(Message.RecipientType.CC)); + System.out.println("Send Mail 成功.."); + tp.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + +} diff --git a/src/wcp-doc/src/main/java/com/farm/doc/util/MailSenderConf.java b/src/wcp-doc/src/main/java/com/farm/doc/util/MailSenderConf.java new file mode 100644 index 0000000..d42af86 --- /dev/null +++ b/src/wcp-doc/src/main/java/com/farm/doc/util/MailSenderConf.java @@ -0,0 +1,58 @@ +package com.farm.doc.util; + +import com.farm.core.ParameterService; +import com.farm.parameter.FarmParameterService; + +public class MailSenderConf { + private String stmp; + private String username; + private String password; + private boolean isEnable = true; + + public MailSenderConf(String stmp, String username, String password) { + this.stmp = stmp; + this.username = username; + this.password = password; + } + + public static MailSenderConf getBaseConf() { + ParameterService confServer = FarmParameterService.getInstance(); + MailSenderConf conf = new MailSenderConf(confServer.getParameter("config.mail.stmp"), + confServer.getParameter("config.mail.username"), confServer.getParameter("config.mail.password")); + conf.isEnable = confServer.getParameter("config.mail.enable").toUpperCase().equals("TRUE"); + return conf; + } + + public String getStmp() { + return stmp; + } + + public void setStmp(String stmp) { + this.stmp = stmp; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isEnable() { + return isEnable; + } + + public void setEnable(boolean isEnable) { + this.isEnable = isEnable; + } + +} diff --git a/src/wcp-doc/src/test/java/org/test/doc/SendMail.java b/src/wcp-doc/src/test/java/org/test/doc/SendMail.java new file mode 100644 index 0000000..2a80f08 --- /dev/null +++ b/src/wcp-doc/src/test/java/org/test/doc/SendMail.java @@ -0,0 +1,21 @@ +package org.test.doc; + +import com.farm.doc.util.MailSender; +import com.farm.doc.util.MailSenderConf; + +public class SendMail { + public static void main(String[] args) { + MailSender mailsender = new MailSender(new MailSenderConf("smtp.ym.163.com", "wangd@sdkeji.com", "23485815")); + mailsender.setFrom("wangd@sdkeji.com"); + mailsender.setSubject("asdfasdf"); + mailsender.setBody("aasdfasdfasdf"); + mailsender.setTo("wangd@sdkeji.com"); + mailsender.setNeedAuth(true); + boolean b = mailsender.setOut(); + if (b) { + System.out.println("\n邮件发送成功!!!!!"); + } else { + System.out.println("邮件发送失败!!!!"); + } + } +}