From db4f2b0687c4473eab7279d30ca04671d4098cdb Mon Sep 17 00:00:00 2001 From: zhenggm Date: Mon, 4 Jul 2022 22:04:09 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4+js?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- smtweb-framework/bpm/.gitignore | 28 + smtweb-framework/bpm/doc/SwBody.puml | 10 + smtweb-framework/bpm/doc/TODO.md | 4 + smtweb-framework/bpm/doc/TODO20210714.md | 11 + smtweb-framework/bpm/doc/smt_asp20201229.txt | 6 + smtweb-framework/bpm/doc/trans.sql | 26 + smtweb-framework/bpm/doc/update20210907.sql | 75 + smtweb-framework/bpm/doc/update20211122.sql | 6 + smtweb-framework/bpm/doc/版本修改说明.md | 8 + smtweb-framework/bpm/pom.xml | 216 +++ .../smtweb/system/bpm/spring/BpmApplication.java | 14 + .../system/bpm/spring/BpmAutoConfiguration.java | 19 + .../cc/smtweb/system/bpm/spring/BpmConfigBean.java | 14 + .../system/bpm/spring/config/FileConfig.java | 26 + .../spring/controller/FileDownloadController.java | 185 +++ .../spring/controller/FileUploadController.java | 157 +++ .../system/bpm/spring/dao/ImageAttachDao.java | 63 + .../smtweb/system/bpm/spring/dao/SysAttachDao.java | 114 ++ .../system/bpm/spring/entity/AttachPathPO.java | 13 + .../system/bpm/spring/entity/FileDataVO.java | 8 + .../system/bpm/spring/entity/UploadDataVO.java | 15 + .../java/cc/smtweb/system/bpm/util/BeanUtil.java | 120 ++ .../cc/smtweb/system/bpm/util/CodeGenUtil.java | 111 ++ .../cc/smtweb/system/bpm/util/CodeGenerator.java | 201 +++ .../cc/smtweb/system/bpm/util/FileDynPath.java | 106 ++ .../cc/smtweb/system/bpm/util/FileFixPath.java | 51 + .../smtweb/system/bpm/util/FilePathGenerator.java | 132 ++ .../cc/smtweb/system/bpm/util/FilePathInfo.java | 48 + .../smtweb/system/bpm/util/ITreeDataHandler.java | 45 + .../system/bpm/util/ITreeDataLevelHandler.java | 6 + .../java/cc/smtweb/system/bpm/util/IdeaUtil.java | 73 + .../smtweb/system/bpm/util/MemMultipartFile.java | 79 ++ .../java/cc/smtweb/system/bpm/util/ThumbImage.java | 109 ++ .../cc/smtweb/system/bpm/util/TreeDataUtil.java | 217 +++ .../java/cc/smtweb/system/bpm/util/XmlUtil.java | 88 ++ .../java/cc/smtweb/system/bpm/util/YamlUtil.java | 112 ++ .../bpm/web/design/db/ModelCatalogCache.java | 55 + .../bpm/web/design/db/ModelCatalogService.java | 29 + .../bpm/web/design/db/ModelCatalogTreeHandler.java | 200 +++ .../bpm/web/design/db/ModelCatalogTreeHelper.java | 34 + .../web/design/db/ModelDatabaseComboHandler.java | 25 + .../bpm/web/design/db/ModelDatabaseService.java | 30 + .../bpm/web/design/db/ModelProjectCache.java | 48 + .../bpm/web/design/db/ModelProjectService.java | 31 + .../bpm/web/design/db/ModelTableComboHandler.java | 31 + .../bpm/web/design/db/ModelTableSaveHanlder.java | 20 + .../bpm/web/design/db/ModelTableService.java | 47 + .../system/bpm/web/design/flow/FlowConst.java | 93 ++ .../system/bpm/web/design/flow/ModelProc.java | 90 ++ .../system/bpm/web/design/flow/ModelProcCache.java | 59 + .../bpm/web/design/flow/ModelProcService.java | 102 ++ .../bpm/web/design/flow/define/ActivityInfo.java | 35 + .../bpm/web/design/flow/define/HandlerInfo.java | 19 + .../bpm/web/design/flow/define/ProcInfo.java | 23 + .../bpm/web/design/flow/define/SignInfo.java | 17 + .../bpm/web/design/flow/define/TransInfo.java | 23 + .../bpm/web/design/form/CodeBuildHandler.java | 183 +++ .../system/bpm/web/design/form/ModelForm.java | 210 +++ .../system/bpm/web/design/form/ModelFormCache.java | 86 ++ .../bpm/web/design/form/ModelFormHelper.java | 499 +++++++ .../bpm/web/design/form/ModelFormLoadHandler.java | 102 ++ .../bpm/web/design/form/ModelFormSaveHandler.java | 135 ++ .../bpm/web/design/form/ModelFormService.java | 177 +++ .../bpm/web/design/form/define/PageDataset.java | 137 ++ .../web/design/form/define/PageDatasetDynCond.java | 25 + .../design/form/define/PageDatasetEnumData.java | 9 + .../web/design/form/define/PageDatasetField.java | 41 + .../web/design/form/define/PageDatasetFilter.java | 20 + .../design/form/define/PageDatasetSortField.java | 9 + .../bpm/web/design/form/define/PageDatasets.java | 57 + .../bpm/web/design/form/define/PageModel.java | 15 + .../system/bpm/web/design/preview/MenuVO.java | 52 + .../web/design/preview/PreviewMenuTreeService.java | 53 + .../web/engine/dynPage/AbstractDynPageHandler.java | 54 + .../bpm/web/engine/dynPage/DynPageDelHandler.java | 156 +++ .../bpm/web/engine/dynPage/DynPageHelper.java | 238 ++++ .../bpm/web/engine/dynPage/DynPageListHandler.java | 75 + .../bpm/web/engine/dynPage/DynPageLoadHandler.java | 109 ++ .../bpm/web/engine/dynPage/DynPageProvider.java | 36 + .../bpm/web/engine/dynPage/DynPageSaveHandler.java | 270 ++++ .../bpm/web/engine/dynPage/DynPageService.java | 70 + .../system/bpm/web/engine/dynPage/DynRetBean.java | 35 + .../system/bpm/web/engine/flow/FlowInstance.java | 65 + .../system/bpm/web/engine/flow/FlowService.java | 15 + .../web/engine/flow/define/CandidateEntity.java | 57 + .../bpm/web/engine/flow/define/CareEntity.java | 49 + .../bpm/web/engine/flow/define/CommentEntity.java | 65 + .../bpm/web/engine/flow/define/ProcinstEntity.java | 129 ++ .../bpm/web/engine/flow/define/SignEntity.java | 74 + .../bpm/web/engine/flow/define/TaskEntity.java | 161 +++ .../bpm/web/engine/flow/define/TaskRelEntity.java | 49 + .../smtweb/system/bpm/web/login/AuthService.java | 86 ++ .../cc/smtweb/system/bpm/web/login/LoginAckVO.java | 11 + .../cc/smtweb/system/bpm/web/login/LoginVO.java | 12 + .../cc/smtweb/system/bpm/web/login/MenuPO.java | 29 + .../cc/smtweb/system/bpm/web/login/UserPO.java | 28 + .../smtweb/system/bpm/web/sys/user/area/Area.java | 109 ++ .../system/bpm/web/sys/user/area/AreaCache.java | 42 + .../system/bpm/web/sys/user/area/AreaHandler.java | 35 + .../system/bpm/web/sys/user/area/AreaService.java | 39 + .../src/main/resources/META-INF/spring.factories | 2 + .../bpm/src/main/resources/codegen/ts/dataset.ts | 730 ++++++++++ .../bpm/src/main/resources/codegen/ts/events.ts | 13 + .../bpm/src/main/resources/codegen/ts/formatter.ts | 28 + .../bpm/src/main/resources/codegen/ts/page.less | 14 + .../src/main/resources/codegen/ts/page.types.ts | 5 + .../src/main/resources/codegen/vm/dataset.ts.vm | 2 + .../bpm/src/main/resources/codegen/vm/events.ts.vm | 6 + .../bpm/src/main/resources/codegen/vm/index.vue.vm | 62 + .../bpm/src/main/resources/codegen/vm/router.ts.vm | 17 + .../codegen/vm/server/CardService.java.vm | 37 + .../codegen/vm/server/ListService.java.vm | 28 + .../codegen/vm/server/TreeService.java.vm | 30 + .../resources/codegen/vm/server/entity.java.vm | 23 + .../main/resources/codegen/vm/server/event.js.vm | 28 + .../bpm/src/main/resources/config/application.yaml | 43 + .../bpm/src/main/resources/config/logback.xml | 9 + .../main/resources/static/event/defaultEvent.js | 87 ++ .../bpm/src/main/resources/static/index.html | 14 + .../src/main/resources/static/template/demo.ftl | 5 + .../static/template/incModel/inc_filter.ftl | 76 ++ .../static/template/incModel/inc_form.ftl | 33 + .../static/template/incModel/inc_grid_opt.ftl | 67 + .../static/template/incModel/inc_model.ftl | 28 + .../src/main/resources/static/template/index.yaml | 35 + .../main/resources/static/template/java_bean.ftl | 42 + .../main/resources/static/template/java_cache.ftl | 51 + .../resources/static/template/java_service.ftl | 30 + .../main/resources/static/template/js_event.ftl | 17 + .../main/resources/static/template/model_card.ftl | 116 ++ .../main/resources/static/template/model_list.ftl | 392 ++++++ .../resources/static/template/model_simple.ftl | 45 + .../java/cc/smtweb/system/bpm/test/BpmTest.java | 38 + .../cc/smtweb/system/bpm/test/BuildJavaBean.java | 54 + .../java/cc/smtweb/system/bpm/test/HexTest.java | 36 + .../cc/smtweb/system/bpm/test/ModelFormTest.java | 98 ++ .../java/cc/smtweb/system/bpm/test/SpelTest.java | 41 + .../java/cc/smtweb/system/bpm/test/TestMain.java | 110 ++ .../java/cc/smtweb/system/bpm/test/ToolTest.java | 54 + .../system/bpm/test/TreeDataBuilderTest.java | 97 ++ .../bpm/src/test/resources/code/index.vue | 116 ++ .../bpm/src/test/resources/code/index.vue.tmp | 119 ++ .../bpm/src/test/resources/code/list.xml | 18 + .../bpm/src/test/resources/db/smt_uc.json | 1 + .../bpm/src/test/resources/template/index.vm | 63 + .../src/test/resources/ui/508660168293093376.json | 1115 +++++++++++++++ smtweb-framework/core/pom.xml | 207 +++ .../cc/smtweb/framework/core/CoreApplication.java | 11 + .../smtweb/framework/core/annotation/SwAttr.java | 16 + .../smtweb/framework/core/annotation/SwBean.java | 22 + .../smtweb/framework/core/annotation/SwBody.java | 15 + .../smtweb/framework/core/annotation/SwColumn.java | 38 + .../framework/core/annotation/SwConstruct.java | 20 + .../framework/core/annotation/SwDestroy.java | 20 + .../smtweb/framework/core/annotation/SwParam.java | 18 + .../smtweb/framework/core/annotation/SwPerm.java | 21 + .../framework/core/annotation/SwScheduling.java | 30 + .../smtweb/framework/core/cache/AbstractCache.java | 515 +++++++ .../smtweb/framework/core/cache/CacheManager.java | 110 ++ .../cc/smtweb/framework/core/cache/ISwCache.java | 24 + .../smtweb/framework/core/cache/SessionCache.java | 36 + .../core/cache/redis/RedisBroadcastEvent.java | 24 + .../core/cache/redis/RedisPooledObjectFactory.java | 39 + .../framework/core/cache/redis/RedisSysTask.java | 61 + .../smtweb/framework/core/common/AbstractEnum.java | 106 ++ .../cc/smtweb/framework/core/common/IntEnum.java | 12 + .../java/cc/smtweb/framework/core/common/R.java | 118 ++ .../cc/smtweb/framework/core/common/StrEnum.java | 30 + .../cc/smtweb/framework/core/common/SwConsts.java | 19 + .../cc/smtweb/framework/core/common/SwIpAddr.java | 9 + .../cc/smtweb/framework/core/common/SwMap.java | 116 ++ .../java/cc/smtweb/framework/core/db/DbEngine.java | 278 ++++ .../cc/smtweb/framework/core/db/EntityDao.java | 367 +++++ .../cc/smtweb/framework/core/db/EntityHelper.java | 193 +++ .../framework/core/db/cache/EntityCache.java | 66 + .../core/db/cache/ModelDatabaseCache.java | 46 + .../core/db/config/DbEngineConfiguration.java | 41 + .../core/db/config/YamlPropertyLoaderFactory.java | 23 + .../framework/core/db/dao/AbstractEntityDao.java | 399 ++++++ .../framework/core/db/dao/EntityColumnForeign.java | 26 + .../framework/core/db/impl/DatabaseUtil.java | 556 ++++++++ .../core/db/impl/DefaultDatabaseInfoImpl.java | 365 +++++ .../framework/core/db/impl/DefaultEntity.java | 86 ++ .../framework/core/db/impl/IDatabaseInfo.java | 37 + .../smtweb/framework/core/db/jdbc/AbsDbWorker.java | 13 + .../smtweb/framework/core/db/jdbc/IDbWorker.java | 15 + .../smtweb/framework/core/db/jdbc/JdbcEngine.java | 508 +++++++ .../core/db/jdbc/MapPropertyRowMapper.java | 39 + .../core/db/jdbc/SwMapPropertyRowMapper.java | 59 + .../db/sqlbuilder/AbstractSelectSqlBuilder.java | 129 ++ .../db/sqlbuilder/AbstractUpdateSqlBuilder.java | 20 + .../core/db/sqlbuilder/InsertSqlBuilder.java | 38 + .../core/db/sqlbuilder/SelectSqlBuilder.java | 95 ++ .../core/db/sqlbuilder/SqlFieldValue.java | 14 + .../framework/core/db/sqlbuilder/SqlJoinField.java | 14 + .../framework/core/db/sqlbuilder/SqlJoinTable.java | 39 + .../core/db/sqlbuilder/SqlWhereValue.java | 13 + .../smtweb/framework/core/db/vo/ModelDatabase.java | 95 ++ .../cc/smtweb/framework/core/db/vo/ModelIndex.java | 25 + .../smtweb/framework/core/db/vo/ModelLinkName.java | 20 + .../core/exception/BindParamException.java | 32 + .../framework/core/exception/BizException.java | 29 + .../framework/core/exception/ExceptionMessage.java | 102 ++ .../framework/core/exception/SwException.java | 53 + .../framework/core/mvc/ISchedulerWakeup.java | 15 + .../core/mvc/config/GlobalExceptionHandler.java | 88 ++ .../framework/core/mvc/config/WebMvcConfig.java | 132 ++ .../core/mvc/controller/ApiConfigBean.java | 21 + .../core/mvc/controller/DefaultPageController.java | 29 + .../mvc/controller/access/ControllerAccess.java | 69 + .../core/mvc/controller/access/IMethodAccess.java | 50 + .../core/mvc/controller/access/MethodAccess.java | 117 ++ .../core/mvc/controller/binder/BeanContext.java | 47 + .../core/mvc/controller/binder/ParamEditor.java | 40 + .../binder/bean/AbstractContextEditor.java | 16 + .../mvc/controller/binder/bean/BeanEditor.java | 15 + .../binder/bean/HttpServletRequestEditor.java | 12 + .../mvc/controller/binder/bean/NullEditor.java | 14 + .../mvc/controller/binder/bean/SwIpAddrEditor.java | 34 + .../controller/binder/body/SwMapBodyEditor.java | 69 + .../binder/param/AbstractNumberEditor.java | 46 + .../binder/param/AbstractParameterEditor.java | 109 ++ .../binder/param/AbstractRequestEditor.java | 16 + .../mvc/controller/binder/param/BooleanEditor.java | 30 + .../mvc/controller/binder/param/ByteEditor.java | 24 + .../mvc/controller/binder/param/CharEditor.java | 29 + .../mvc/controller/binder/param/DoubleEditor.java | 25 + .../mvc/controller/binder/param/LongEditor.java | 25 + .../mvc/controller/binder/param/TimeEditor.java | 35 + .../controller/binder/param/TimestampEditor.java | 57 + .../controller/binder/path/PathParamEditor.java | 14 + .../core/mvc/controller/scan/BeanManager.java | 161 +++ .../core/mvc/controller/scan/ClassParser.java | 173 +++ .../core/mvc/controller/scan/IScanAction.java | 18 + .../mvc/controller/scan/IScanActionBuilder.java | 12 + .../core/mvc/controller/scan/MethodParser.java | 159 +++ .../core/mvc/controller/scan/PackageScanner.java | 180 +++ .../core/mvc/controller/scan/ScanContext.java | 115 ++ .../framework/core/mvc/realm/IRealmLoader.java | 18 + .../realm/exception/AuthenticationException.java | 7 + .../realm/exception/AuthorizationException.java | 9 + .../realm/exception/UnauthenticatedException.java | 7 + .../realm/interceptor/AbstractPermInterceptor.java | 109 ++ .../interceptor/AuthorizationInterceptor.java | 42 + .../core/mvc/realm/service/PermCheckItem.java | 21 + .../core/mvc/realm/service/PermChecker.java | 35 + .../framework/core/mvc/scheduler/AbstractJob.java | 59 + .../core/mvc/scheduler/AbstractJobQueue.java | 72 + .../core/mvc/scheduler/FixedTimerTask.java | 19 + .../core/mvc/scheduler/SchedulerPoint.java | 40 + .../core/mvc/scheduler/SchedulerTaskManager.java | 97 ++ .../core/mvc/scheduler/job/GroupJobQueue.java | 82 ++ .../core/mvc/scheduler/job/SimpleJob.java | 19 + .../core/mvc/scheduler/job/SimpleJobQueue.java | 22 + .../core/mvc/service/AbstractCompProvider.java | 21 + .../core/mvc/service/AbstractDelHandler.java | 53 + .../core/mvc/service/AbstractHandler.java | 17 + .../core/mvc/service/AbstractListHandler.java | 235 ++++ .../core/mvc/service/AbstractLoadHandler.java | 32 + .../core/mvc/service/DefaultComboHandler.java | 84 ++ .../core/mvc/service/DefaultListHandler.java | 73 + .../core/mvc/service/DefaultLoadHandler.java | 36 + .../core/mvc/service/DefaultSaveHandler.java | 176 +++ .../framework/core/mvc/service/IDataProvider.java | 8 + .../smtweb/framework/core/mvc/service/IWorker.java | 11 + .../framework/core/mvc/service/SqlNamedPara.java | 30 + .../smtweb/framework/core/mvc/service/SqlPara.java | 36 + .../framework/core/mvc/service/SwListData.java | 36 + .../framework/core/mvc/service/TreeHelper.java | 132 ++ .../core/mvc/service/list/FooterField.java | 57 + .../framework/core/mvc/variable/ICalcVar.java | 18 + .../framework/core/mvc/variable/SwVariable.java | 26 + .../core/mvc/variable/SwVariableFactory.java | 45 + .../framework/core/session/SessionManager.java | 73 + .../smtweb/framework/core/session/SessionUtil.java | 109 ++ .../core/session/UserSessionArgumentResolver.java | 26 + .../framework/core/systask/SysTaskManager.java | 40 + .../framework/core/systask/WebStartedEvent.java | 4 + .../cc/smtweb/framework/core/util/CommUtil.java | 140 ++ .../cc/smtweb/framework/core/util/IpAddrUtil.java | 101 ++ .../cc/smtweb/framework/core/util/JsonUtil.java | 296 ++++ .../cc/smtweb/framework/core/util/NumberUtil.java | 621 +++++++++ .../cc/smtweb/framework/core/util/SpringUtil.java | 42 + .../smtweb/framework/core/util/VariableUtil.java | 65 + .../core/util/jackson/BaseBeanSerializer.java | 23 + .../core/util/jackson/DateDeserializer.java | 30 + .../core/util/jackson/LongDeserializer.java | 25 + .../core/util/jackson/LongSerializer.java | 19 + .../core/util/jackson/NullSerializer.java | 15 + .../core/util/jackson/TimestampDeserializer.java | 29 + .../smtweb/framework/core/util/kryo/KryoTool.java | 78 ++ .../com/serotonin/timer/AbstractTimerTrigger.java | 25 + .../java/com/serotonin/timer/CronExpression.java | 1444 ++++++++++++++++++++ .../java/com/serotonin/timer/FixedRateTrigger.java | 49 + .../com/serotonin/timer/ModelTimeoutClient.java | 9 + .../java/com/serotonin/timer/ModelTimeoutTask.java | 34 + .../com/serotonin/timer/NonConcurrentTask.java | 49 + .../java/com/serotonin/timer/OneTimeTrigger.java | 28 + .../java/com/serotonin/timer/RealTimeTimer.java | 320 +++++ .../java/com/serotonin/timer/SystemTimeSource.java | 12 + .../main/java/com/serotonin/timer/TaskQueue.java | 148 ++ .../main/java/com/serotonin/timer/TimeSource.java | 11 + .../main/java/com/serotonin/timer/TimerTask.java | 167 +++ .../timer/sync/SingleExecutorSingleWaiter.java | 137 ++ .../com/serotonin/timer/sync/Synchronizer.java | 235 ++++ .../src/main/resources/META-INF/spring.factories | 2 + .../src/main/resources/config/application-dev.yaml | 61 + .../main/resources/config/application-prod.yaml | 52 + .../cc/smtweb/framework/test/DaoTransTest.java | 30 + .../cc/smtweb/framework/test/NamedJdbcTest.java | 30 + .../cc/smtweb/framework/test/SqlBuilderTest.java | 69 + .../java/cc/smtweb/framework/test/ToolEnum2Js.java | 118 ++ smtweb-framework/sw-framework-core/doc/TODO.mk | 8 - smtweb-framework/sw-framework-core/pom.xml | 207 --- .../cc/smtweb/framework/core/CoreApplication.java | 11 - .../core/CoreApplicationStartedListener.java | 37 - .../framework/core/CoreAutoConfiguration.java | 33 - .../smtweb/framework/core/annotation/SwAction.java | 21 - .../smtweb/framework/core/annotation/SwAttr.java | 16 - .../smtweb/framework/core/annotation/SwBean.java | 22 - .../smtweb/framework/core/annotation/SwBody.java | 15 - .../smtweb/framework/core/annotation/SwCache.java | 26 - .../smtweb/framework/core/annotation/SwColumn.java | 38 - .../framework/core/annotation/SwColumnForeign.java | 21 - .../framework/core/annotation/SwConstruct.java | 20 - .../framework/core/annotation/SwDestroy.java | 20 - .../framework/core/annotation/SwHeaderParam.java | 16 - .../smtweb/framework/core/annotation/SwParam.java | 18 - .../framework/core/annotation/SwPathParam.java | 16 - .../smtweb/framework/core/annotation/SwPerm.java | 21 - .../framework/core/annotation/SwScheduling.java | 30 - .../framework/core/annotation/SwService.java | 16 - .../smtweb/framework/core/annotation/SwTable.java | 17 - .../smtweb/framework/core/cache/AbstractCache.java | 515 ------- .../framework/core/cache/AbstractEntityCache.java | 54 - .../smtweb/framework/core/cache/CacheManager.java | 110 -- .../cc/smtweb/framework/core/cache/ISwCache.java | 24 - .../smtweb/framework/core/cache/SessionCache.java | 36 - .../framework/core/cache/SessionCacheFactory.java | 51 - .../core/cache/redis/RedisBroadcastEvent.java | 24 - .../core/cache/redis/RedisConnection.java | 300 ---- .../framework/core/cache/redis/RedisManager.java | 220 --- .../core/cache/redis/RedisPooledObjectFactory.java | 39 - .../framework/core/cache/redis/RedisSysTask.java | 61 - .../core/cache/redis/config/RedisConfig.java | 64 - .../smtweb/framework/core/common/AbstractEnum.java | 106 -- .../cc/smtweb/framework/core/common/IntEnum.java | 12 - .../java/cc/smtweb/framework/core/common/R.java | 118 -- .../cc/smtweb/framework/core/common/StrEnum.java | 30 - .../cc/smtweb/framework/core/common/SwConsts.java | 19 - .../cc/smtweb/framework/core/common/SwEnum.java | 290 ---- .../cc/smtweb/framework/core/common/SwIpAddr.java | 9 - .../cc/smtweb/framework/core/common/SwMap.java | 116 -- .../java/cc/smtweb/framework/core/db/DbEngine.java | 278 ---- .../cc/smtweb/framework/core/db/EntityDao.java | 367 ----- .../cc/smtweb/framework/core/db/EntityHelper.java | 193 --- .../framework/core/db/cache/EntityCache.java | 66 - .../core/db/cache/ModelDatabaseCache.java | 46 - .../framework/core/db/cache/ModelTableCache.java | 123 -- .../core/db/config/DbEngineConfiguration.java | 41 - .../core/db/config/YamlPropertyLoaderFactory.java | 23 - .../framework/core/db/dao/AbstractEntityDao.java | 399 ------ .../smtweb/framework/core/db/dao/EntityColumn.java | 66 - .../framework/core/db/dao/EntityColumnForeign.java | 26 - .../cc/smtweb/framework/core/db/impl/BaseBean.java | 103 -- .../framework/core/db/impl/DatabaseUtil.java | 556 -------- .../core/db/impl/DefaultDatabaseInfoImpl.java | 365 ----- .../framework/core/db/impl/DefaultEntity.java | 86 -- .../framework/core/db/impl/IDatabaseInfo.java | 37 - .../cc/smtweb/framework/core/db/impl/UtilTime.java | 158 --- .../smtweb/framework/core/db/jdbc/AbsDbWorker.java | 13 - .../core/db/jdbc/BaseBeanPropertyRowMapper.java | 40 - .../smtweb/framework/core/db/jdbc/IDbWorker.java | 15 - .../smtweb/framework/core/db/jdbc/IdGenerator.java | 134 -- .../smtweb/framework/core/db/jdbc/JdbcEngine.java | 508 ------- .../smtweb/framework/core/db/jdbc/JdbcTrans.java | 87 -- .../core/db/jdbc/MapPropertyRowMapper.java | 39 - .../core/db/jdbc/SwMapPropertyRowMapper.java | 59 - .../db/sqlbuilder/AbstractSelectSqlBuilder.java | 129 -- .../db/sqlbuilder/AbstractUpdateSqlBuilder.java | 20 - .../core/db/sqlbuilder/DeleteSqlBuilder.java | 33 - .../core/db/sqlbuilder/DirectSelectSqlBuilder.java | 20 - .../core/db/sqlbuilder/InsertSqlBuilder.java | 38 - .../core/db/sqlbuilder/SelectSqlBuilder.java | 95 -- .../framework/core/db/sqlbuilder/SqlBuilder.java | 84 -- .../core/db/sqlbuilder/SqlFieldValue.java | 14 - .../framework/core/db/sqlbuilder/SqlJoinField.java | 14 - .../framework/core/db/sqlbuilder/SqlJoinTable.java | 39 - .../core/db/sqlbuilder/SqlWhereValue.java | 13 - .../core/db/sqlbuilder/UpdateSqlBuilder.java | 55 - .../cc/smtweb/framework/core/db/vo/ModelCache.java | 28 - .../smtweb/framework/core/db/vo/ModelCatalog.java | 96 -- .../smtweb/framework/core/db/vo/ModelDatabase.java | 95 -- .../cc/smtweb/framework/core/db/vo/ModelField.java | 41 - .../cc/smtweb/framework/core/db/vo/ModelIndex.java | 25 - .../smtweb/framework/core/db/vo/ModelLinkName.java | 20 - .../smtweb/framework/core/db/vo/ModelProject.java | 96 -- .../cc/smtweb/framework/core/db/vo/ModelTable.java | 282 ---- .../core/exception/BindBeanException.java | 39 - .../core/exception/BindParamException.java | 32 - .../framework/core/exception/BizException.java | 29 - .../framework/core/exception/DbException.java | 31 - .../framework/core/exception/ExceptionMessage.java | 102 -- .../core/exception/JsonParseException.java | 7 - .../framework/core/exception/SwException.java | 53 - .../framework/core/mvc/ISchedulerWakeup.java | 15 - .../framework/core/mvc/SchedulerManager.java | 29 - .../core/mvc/config/ControllerConfig.java | 24 - .../core/mvc/config/GlobalExceptionHandler.java | 88 -- .../config/SettingsEnvironmentPostProcessor.java | 58 - .../framework/core/mvc/config/WebMvcConfig.java | 132 -- .../core/mvc/controller/ApiConfigBean.java | 21 - .../core/mvc/controller/ApiController.java | 60 - .../core/mvc/controller/DefaultPageController.java | 29 - .../core/mvc/controller/IActionManager.java | 7 - .../core/mvc/controller/IBeanContext.java | 8 - .../framework/core/mvc/controller/IEditor.java | 27 - .../core/mvc/controller/MethodAccessManager.java | 105 -- .../mvc/controller/access/BindFieldAccess.java | 27 - .../mvc/controller/access/ControllerAccess.java | 69 - .../core/mvc/controller/access/FieldAccess.java | 39 - .../core/mvc/controller/access/IBeanAccess.java | 5 - .../core/mvc/controller/access/IMethodAccess.java | 50 - .../core/mvc/controller/access/MethodAccess.java | 117 -- .../mvc/controller/access/MethodParamAccess.java | 42 - .../controller/access/SchedulerMethodAccess.java | 21 - .../controller/access/SingletonFieldAccess.java | 20 - .../core/mvc/controller/binder/BeanContext.java | 47 - .../core/mvc/controller/binder/CacheEditor.java | 26 - .../core/mvc/controller/binder/ParamEditor.java | 40 - .../core/mvc/controller/binder/WebDataBinder.java | 225 --- .../controller/binder/attr/AbstractAttrEditor.java | 20 - .../mvc/controller/binder/attr/BeanAttrEditor.java | 14 - .../binder/bean/AbstractContextEditor.java | 16 - .../mvc/controller/binder/bean/BeanEditor.java | 15 - .../binder/bean/HttpServletRequestEditor.java | 12 - .../mvc/controller/binder/bean/NullEditor.java | 14 - .../mvc/controller/binder/bean/SwIpAddrEditor.java | 34 - .../controller/binder/bean/UserSessionEditor.java | 13 - .../mvc/controller/binder/body/BeanBodyEditor.java | 82 -- .../core/mvc/controller/binder/body/BeanUtil.java | 160 --- .../controller/binder/body/StringBodyEditor.java | 18 - .../controller/binder/body/SwMapBodyEditor.java | 69 - .../binder/param/AbstractNumberEditor.java | 46 - .../binder/param/AbstractParameterEditor.java | 109 -- .../binder/param/AbstractRequestEditor.java | 16 - .../controller/binder/param/BeanTypeEditor.java | 14 - .../mvc/controller/binder/param/BooleanEditor.java | 30 - .../mvc/controller/binder/param/ByteEditor.java | 24 - .../mvc/controller/binder/param/CharEditor.java | 29 - .../mvc/controller/binder/param/DateEditor.java | 53 - .../mvc/controller/binder/param/DoubleEditor.java | 25 - .../mvc/controller/binder/param/FloatEditor.java | 25 - .../mvc/controller/binder/param/IntegerEditor.java | 24 - .../mvc/controller/binder/param/LongEditor.java | 25 - .../mvc/controller/binder/param/ShortEditor.java | 25 - .../mvc/controller/binder/param/StringEditor.java | 17 - .../mvc/controller/binder/param/TimeEditor.java | 35 - .../controller/binder/param/TimestampEditor.java | 57 - .../controller/binder/path/PathParamEditor.java | 14 - .../mvc/controller/scan/ApplicationScanner.java | 73 - .../core/mvc/controller/scan/BeanManager.java | 161 --- .../core/mvc/controller/scan/ClassParser.java | 173 --- .../core/mvc/controller/scan/IScanAction.java | 18 - .../mvc/controller/scan/IScanActionBuilder.java | 12 - .../core/mvc/controller/scan/MethodParser.java | 159 --- .../core/mvc/controller/scan/PackageScanner.java | 180 --- .../core/mvc/controller/scan/ScanContext.java | 115 -- .../core/mvc/controller/scan/UrlMaker.java | 95 -- .../framework/core/mvc/realm/IRealmLoader.java | 18 - .../realm/exception/AuthenticationException.java | 7 - .../realm/exception/AuthorizationException.java | 9 - .../mvc/realm/exception/ForbiddenException.java | 7 - .../realm/exception/UnauthenticatedException.java | 7 - .../realm/exception/UnknownAccountException.java | 7 - .../realm/interceptor/AbstractPermInterceptor.java | 109 -- .../interceptor/AuthorizationInterceptor.java | 42 - .../mvc/realm/interceptor/PermInterceptor.java | 25 - .../core/mvc/realm/service/PermCheckItem.java | 21 - .../core/mvc/realm/service/PermChecker.java | 35 - .../framework/core/mvc/scheduler/AbstractJob.java | 59 - .../core/mvc/scheduler/AbstractJobExecutor.java | 85 -- .../core/mvc/scheduler/AbstractJobQueue.java | 72 - .../core/mvc/scheduler/CronTimerTask.java | 30 - .../core/mvc/scheduler/FixedTimerTask.java | 19 - .../core/mvc/scheduler/SchedulerPoint.java | 40 - .../core/mvc/scheduler/SchedulerTaskManager.java | 97 -- .../framework/core/mvc/scheduler/job/GroupJob.java | 19 - .../core/mvc/scheduler/job/GroupJobQueue.java | 82 -- .../core/mvc/scheduler/job/LocalJobExecutor.java | 23 - .../core/mvc/scheduler/job/RedisJobExecutor.java | 70 - .../core/mvc/scheduler/job/SimpleJob.java | 19 - .../core/mvc/scheduler/job/SimpleJobQueue.java | 22 - .../core/mvc/service/AbstractCompProvider.java | 21 - .../core/mvc/service/AbstractCompService.java | 96 -- .../core/mvc/service/AbstractDelHandler.java | 53 - .../core/mvc/service/AbstractHandler.java | 17 - .../core/mvc/service/AbstractListHandler.java | 235 ---- .../core/mvc/service/AbstractLoadHandler.java | 32 - .../core/mvc/service/AbstractSaveHandler.java | 87 -- .../core/mvc/service/AbstractTreeHandler.java | 67 - .../core/mvc/service/DefaultComboHandler.java | 84 -- .../core/mvc/service/DefaultDelHandler.java | 46 - .../core/mvc/service/DefaultListHandler.java | 73 - .../core/mvc/service/DefaultLoadHandler.java | 36 - .../core/mvc/service/DefaultProvider.java | 31 - .../core/mvc/service/DefaultSaveHandler.java | 176 --- .../framework/core/mvc/service/IDataProvider.java | 8 - .../smtweb/framework/core/mvc/service/IWorker.java | 11 - .../framework/core/mvc/service/SqlNamedPara.java | 30 - .../smtweb/framework/core/mvc/service/SqlPara.java | 36 - .../framework/core/mvc/service/SwListData.java | 36 - .../framework/core/mvc/service/TreeHelper.java | 132 -- .../core/mvc/service/list/FooterField.java | 57 - .../framework/core/mvc/variable/ICalcVar.java | 18 - .../framework/core/mvc/variable/SwVariable.java | 26 - .../core/mvc/variable/SwVariableFactory.java | 45 - .../framework/core/session/SessionManager.java | 73 - .../smtweb/framework/core/session/SessionUtil.java | 109 -- .../smtweb/framework/core/session/UserSession.java | 31 - .../core/session/UserSessionArgumentResolver.java | 26 - .../cc/smtweb/framework/core/systask/ISysTask.java | 8 - .../framework/core/systask/SysTaskManager.java | 40 - .../framework/core/systask/TaskStartEvent.java | 4 - .../framework/core/systask/WebStartedEvent.java | 4 - .../cc/smtweb/framework/core/util/CommUtil.java | 140 -- .../cc/smtweb/framework/core/util/DateUtil.java | 319 ----- .../cc/smtweb/framework/core/util/FileUtil.java | 7 + .../cc/smtweb/framework/core/util/IpAddrUtil.java | 101 -- .../cc/smtweb/framework/core/util/JsonUtil.java | 296 ---- .../cc/smtweb/framework/core/util/MapUtil.java | 221 --- .../cc/smtweb/framework/core/util/NumberUtil.java | 621 --------- .../cc/smtweb/framework/core/util/SpringUtil.java | 42 - .../cc/smtweb/framework/core/util/SqlUtil.java | 18 - .../smtweb/framework/core/util/VariableUtil.java | 65 - .../core/util/jackson/BaseBeanSerializer.java | 23 - .../core/util/jackson/DateDeserializer.java | 30 - .../core/util/jackson/DateSerializer.java | 70 - .../core/util/jackson/LongDeserializer.java | 25 - .../core/util/jackson/LongSerializer.java | 19 - .../core/util/jackson/NullSerializer.java | 15 - .../core/util/jackson/TimeSerializer.java | 61 - .../core/util/jackson/TimestampDeserializer.java | 29 - .../smtweb/framework/core/util/kryo/KryoTool.java | 78 -- .../java/com/serotonin/timer/AbstractTimer.java | 54 - .../com/serotonin/timer/AbstractTimerTrigger.java | 25 - .../java/com/serotonin/timer/CronExpression.java | 1444 -------------------- .../java/com/serotonin/timer/CronTimerTrigger.java | 34 - .../timer/ExecutionRejectedException.java | 12 - .../com/serotonin/timer/FixedDelayTrigger.java | 32 - .../java/com/serotonin/timer/FixedRateTrigger.java | 49 - .../com/serotonin/timer/ModelTimeoutClient.java | 9 - .../java/com/serotonin/timer/ModelTimeoutTask.java | 34 - .../java/com/serotonin/timer/NamedRunnable.java | 32 - .../com/serotonin/timer/NonConcurrentTask.java | 49 - .../java/com/serotonin/timer/OneTimeTrigger.java | 28 - .../java/com/serotonin/timer/RealTimeTimer.java | 320 ----- .../serotonin/timer/ScheduledNamedRunnable.java | 33 - .../com/serotonin/timer/ScheduledRunnable.java | 8 - .../com/serotonin/timer/SimulationTimeSource.java | 13 - .../java/com/serotonin/timer/SimulationTimer.java | 194 --- .../java/com/serotonin/timer/SystemTimeSource.java | 12 - .../main/java/com/serotonin/timer/TaskQueue.java | 148 -- .../main/java/com/serotonin/timer/TimeSource.java | 11 - .../main/java/com/serotonin/timer/TimeoutTask.java | 30 - .../main/java/com/serotonin/timer/TimerTask.java | 167 --- .../main/java/com/serotonin/timer/TimerThread.java | 124 -- .../java/com/serotonin/timer/TimerTrigger.java | 80 -- .../com/serotonin/timer/sync/AsyncJobSink.java | 99 -- .../timer/sync/SingleExecutorSingleWaiter.java | 137 -- .../com/serotonin/timer/sync/Synchronizer.java | 235 ---- .../src/main/resources/META-INF/spring.factories | 2 - .../src/main/resources/config/application-dev.yaml | 61 - .../main/resources/config/application-prod.yaml | 52 - .../src/main/resources/config/application.yaml | 3 - .../cc/smtweb/framework/test/DaoTransTest.java | 30 - .../java/cc/smtweb/framework/test/JsonTest.java | 33 - .../cc/smtweb/framework/test/NamedJdbcTest.java | 30 - .../cc/smtweb/framework/test/SqlBuilderTest.java | 69 - .../java/cc/smtweb/framework/test/TestMain.java | 23 - .../java/cc/smtweb/framework/test/ToolEnum2Js.java | 118 -- .../target/classes/META-INF/spring.factories | 2 - .../target/classes/config/application-dev.yaml | 61 - .../target/classes/config/application-prod.yaml | 52 - .../target/classes/config/application.yaml | 3 - .../compile/default-compile/createdFiles.lst | 296 ---- .../compile/default-compile/inputFiles.lst | 256 ---- smtweb-framework/sw-system-bpm/.gitignore | 28 - smtweb-framework/sw-system-bpm/doc/SwBody.puml | 10 - smtweb-framework/sw-system-bpm/doc/TODO.md | 4 - smtweb-framework/sw-system-bpm/doc/TODO20210714.md | 11 - .../sw-system-bpm/doc/smt_asp20201229.txt | 6 - smtweb-framework/sw-system-bpm/doc/trans.sql | 26 - .../sw-system-bpm/doc/update20210907.sql | 75 - .../sw-system-bpm/doc/update20211122.sql | 6 - .../sw-system-bpm/doc/版本修改说明.md | 8 - smtweb-framework/sw-system-bpm/pom.xml | 216 --- .../smtweb/system/bpm/spring/BpmApplication.java | 14 - .../system/bpm/spring/BpmAutoConfiguration.java | 19 - .../cc/smtweb/system/bpm/spring/BpmConfigBean.java | 14 - .../system/bpm/spring/config/FileConfig.java | 26 - .../spring/controller/FileDownloadController.java | 185 --- .../spring/controller/FileUploadController.java | 157 --- .../system/bpm/spring/dao/ImageAttachDao.java | 63 - .../smtweb/system/bpm/spring/dao/SysAttachDao.java | 114 -- .../system/bpm/spring/entity/AttachPathPO.java | 13 - .../system/bpm/spring/entity/FileDataVO.java | 8 - .../system/bpm/spring/entity/UploadDataVO.java | 15 - .../java/cc/smtweb/system/bpm/util/BeanUtil.java | 120 -- .../cc/smtweb/system/bpm/util/CodeGenUtil.java | 111 -- .../cc/smtweb/system/bpm/util/CodeGenerator.java | 201 --- .../cc/smtweb/system/bpm/util/FileDynPath.java | 106 -- .../cc/smtweb/system/bpm/util/FileFixPath.java | 51 - .../smtweb/system/bpm/util/FilePathGenerator.java | 132 -- .../cc/smtweb/system/bpm/util/FilePathInfo.java | 48 - .../smtweb/system/bpm/util/ITreeDataHandler.java | 45 - .../system/bpm/util/ITreeDataLevelHandler.java | 6 - .../java/cc/smtweb/system/bpm/util/IdeaUtil.java | 73 - .../smtweb/system/bpm/util/MemMultipartFile.java | 79 -- .../java/cc/smtweb/system/bpm/util/ThumbImage.java | 109 -- .../cc/smtweb/system/bpm/util/TreeDataUtil.java | 217 --- .../java/cc/smtweb/system/bpm/util/XmlUtil.java | 88 -- .../java/cc/smtweb/system/bpm/util/YamlUtil.java | 112 -- .../bpm/web/design/db/ModelCatalogCache.java | 55 - .../bpm/web/design/db/ModelCatalogService.java | 29 - .../bpm/web/design/db/ModelCatalogTreeHandler.java | 200 --- .../bpm/web/design/db/ModelCatalogTreeHelper.java | 34 - .../web/design/db/ModelDatabaseComboHandler.java | 25 - .../bpm/web/design/db/ModelDatabaseService.java | 30 - .../bpm/web/design/db/ModelProjectCache.java | 48 - .../bpm/web/design/db/ModelProjectService.java | 31 - .../bpm/web/design/db/ModelTableComboHandler.java | 31 - .../bpm/web/design/db/ModelTableSaveHanlder.java | 20 - .../bpm/web/design/db/ModelTableService.java | 47 - .../system/bpm/web/design/flow/FlowConst.java | 93 -- .../system/bpm/web/design/flow/ModelProc.java | 90 -- .../system/bpm/web/design/flow/ModelProcCache.java | 59 - .../bpm/web/design/flow/ModelProcService.java | 102 -- .../bpm/web/design/flow/define/ActivityInfo.java | 35 - .../bpm/web/design/flow/define/HandlerInfo.java | 19 - .../bpm/web/design/flow/define/ProcInfo.java | 23 - .../bpm/web/design/flow/define/SignInfo.java | 17 - .../bpm/web/design/flow/define/TransInfo.java | 23 - .../bpm/web/design/form/CodeBuildHandler.java | 197 --- .../system/bpm/web/design/form/ModelForm.java | 210 --- .../system/bpm/web/design/form/ModelFormCache.java | 86 -- .../bpm/web/design/form/ModelFormHelper.java | 475 ------- .../bpm/web/design/form/ModelFormLoadHandler.java | 63 - .../bpm/web/design/form/ModelFormSaveHandler.java | 135 -- .../bpm/web/design/form/ModelFormService.java | 167 --- .../bpm/web/design/form/define/PageDataset.java | 137 -- .../web/design/form/define/PageDatasetDynCond.java | 25 - .../design/form/define/PageDatasetEnumData.java | 9 - .../web/design/form/define/PageDatasetField.java | 41 - .../web/design/form/define/PageDatasetFilter.java | 20 - .../design/form/define/PageDatasetSortField.java | 9 - .../bpm/web/design/form/define/PageDatasets.java | 57 - .../bpm/web/design/form/define/PageModel.java | 15 - .../system/bpm/web/design/preview/MenuVO.java | 52 - .../web/design/preview/PreviewMenuTreeService.java | 53 - .../web/engine/dynPage/AbstractDynPageHandler.java | 54 - .../bpm/web/engine/dynPage/DynPageDelHandler.java | 156 --- .../bpm/web/engine/dynPage/DynPageHelper.java | 238 ---- .../bpm/web/engine/dynPage/DynPageListHandler.java | 75 - .../bpm/web/engine/dynPage/DynPageLoadHandler.java | 109 -- .../bpm/web/engine/dynPage/DynPageProvider.java | 36 - .../bpm/web/engine/dynPage/DynPageSaveHandler.java | 270 ---- .../bpm/web/engine/dynPage/DynPageService.java | 70 - .../system/bpm/web/engine/dynPage/DynRetBean.java | 35 - .../system/bpm/web/engine/flow/FlowInstance.java | 65 - .../system/bpm/web/engine/flow/FlowService.java | 15 - .../web/engine/flow/define/CandidateEntity.java | 57 - .../bpm/web/engine/flow/define/CareEntity.java | 49 - .../bpm/web/engine/flow/define/CommentEntity.java | 65 - .../bpm/web/engine/flow/define/ProcinstEntity.java | 129 -- .../bpm/web/engine/flow/define/SignEntity.java | 74 - .../bpm/web/engine/flow/define/TaskEntity.java | 161 --- .../bpm/web/engine/flow/define/TaskRelEntity.java | 49 - .../smtweb/system/bpm/web/login/AuthService.java | 86 -- .../cc/smtweb/system/bpm/web/login/LoginAckVO.java | 11 - .../cc/smtweb/system/bpm/web/login/LoginVO.java | 12 - .../cc/smtweb/system/bpm/web/login/MenuPO.java | 29 - .../cc/smtweb/system/bpm/web/login/UserPO.java | 28 - .../smtweb/system/bpm/web/sys/user/area/Area.java | 109 -- .../system/bpm/web/sys/user/area/AreaCache.java | 42 - .../system/bpm/web/sys/user/area/AreaHandler.java | 35 - .../system/bpm/web/sys/user/area/AreaService.java | 39 - .../src/main/resources/META-INF/spring.factories | 2 - .../src/main/resources/codegen/ts/dataset.ts | 730 ---------- .../src/main/resources/codegen/ts/events.ts | 13 - .../src/main/resources/codegen/ts/formatter.ts | 28 - .../src/main/resources/codegen/ts/page.less | 14 - .../src/main/resources/codegen/ts/page.types.ts | 5 - .../src/main/resources/codegen/vm/dataset.ts.vm | 2 - .../src/main/resources/codegen/vm/events.ts.vm | 6 - .../src/main/resources/codegen/vm/index.vue.vm | 62 - .../src/main/resources/codegen/vm/router.ts.vm | 17 - .../codegen/vm/server/CardService.java.vm | 37 - .../codegen/vm/server/ListService.java.vm | 28 - .../codegen/vm/server/TreeService.java.vm | 30 - .../resources/codegen/vm/server/entity.java.vm | 23 - .../main/resources/codegen/vm/server/event.js.vm | 28 - .../src/main/resources/config/application.yaml | 43 - .../src/main/resources/config/logback.xml | 9 - .../main/resources/static/event/defaultEvent.js | 87 -- .../src/main/resources/static/index.html | 14 - .../src/main/resources/static/template/demo.ftl | 5 - .../static/template/incModel/inc_filter.ftl | 76 -- .../static/template/incModel/inc_form.ftl | 33 - .../static/template/incModel/inc_grid_opt.ftl | 67 - .../static/template/incModel/inc_model.ftl | 28 - .../src/main/resources/static/template/index.yaml | 35 - .../main/resources/static/template/java_bean.ftl | 42 - .../main/resources/static/template/java_cache.ftl | 51 - .../resources/static/template/java_service.ftl | 30 - .../main/resources/static/template/js_event.ftl | 17 - .../main/resources/static/template/model_card.ftl | 116 -- .../main/resources/static/template/model_list.ftl | 392 ------ .../resources/static/template/model_simple.ftl | 45 - .../java/cc/smtweb/system/bpm/test/BpmTest.java | 38 - .../cc/smtweb/system/bpm/test/BuildJavaBean.java | 54 - .../java/cc/smtweb/system/bpm/test/HexTest.java | 36 - .../cc/smtweb/system/bpm/test/ModelFormTest.java | 98 -- .../java/cc/smtweb/system/bpm/test/SpelTest.java | 41 - .../java/cc/smtweb/system/bpm/test/TestMain.java | 18 - .../java/cc/smtweb/system/bpm/test/ToolTest.java | 54 - .../system/bpm/test/TreeDataBuilderTest.java | 97 -- .../src/test/resources/code/index.vue | 116 -- .../src/test/resources/code/index.vue.tmp | 119 -- .../sw-system-bpm/src/test/resources/code/list.xml | 18 - .../src/test/resources/db/smt_uc.json | 1 - .../src/test/resources/template/index.vm | 63 - .../src/test/resources/ui/508660168293093376.json | 1115 --------------- 733 files changed, 25535 insertions(+), 32245 deletions(-) create mode 100644 smtweb-framework/bpm/.gitignore create mode 100644 smtweb-framework/bpm/doc/SwBody.puml create mode 100644 smtweb-framework/bpm/doc/TODO.md create mode 100644 smtweb-framework/bpm/doc/TODO20210714.md create mode 100644 smtweb-framework/bpm/doc/smt_asp20201229.txt create mode 100644 smtweb-framework/bpm/doc/trans.sql create mode 100644 smtweb-framework/bpm/doc/update20210907.sql create mode 100644 smtweb-framework/bpm/doc/update20211122.sql create mode 100644 smtweb-framework/bpm/doc/版本修改说明.md create mode 100644 smtweb-framework/bpm/pom.xml create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenUtil.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileFixPath.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseComboHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableComboHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableSaveHanlder.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ActivityInfo.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/HandlerInfo.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/SignInfo.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/TransInfo.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetDynCond.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetEnumData.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetField.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetSortField.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageModel.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageLoadHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageProvider.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageSaveHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynRetBean.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CandidateEntity.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CareEntity.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CommentEntity.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/ProcinstEntity.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/SignEntity.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskRelEntity.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/AuthService.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginAckVO.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginVO.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/MenuPO.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/UserPO.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/Area.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaCache.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaHandler.java create mode 100644 smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaService.java create mode 100644 smtweb-framework/bpm/src/main/resources/META-INF/spring.factories create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/ts/dataset.ts create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/ts/events.ts create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/ts/formatter.ts create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/ts/page.less create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/ts/page.types.ts create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/dataset.ts.vm create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/events.ts.vm create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/index.vue.vm create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/router.ts.vm create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/server/CardService.java.vm create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/server/ListService.java.vm create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/server/TreeService.java.vm create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/server/entity.java.vm create mode 100644 smtweb-framework/bpm/src/main/resources/codegen/vm/server/event.js.vm create mode 100644 smtweb-framework/bpm/src/main/resources/config/application.yaml create mode 100644 smtweb-framework/bpm/src/main/resources/config/logback.xml create mode 100644 smtweb-framework/bpm/src/main/resources/static/event/defaultEvent.js create mode 100644 smtweb-framework/bpm/src/main/resources/static/index.html create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/demo.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_filter.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_form.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_grid_opt.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_model.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/index.yaml create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/java_bean.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/java_cache.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/java_service.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/js_event.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/model_card.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/model_list.ftl create mode 100644 smtweb-framework/bpm/src/main/resources/static/template/model_simple.ftl create mode 100644 smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/BpmTest.java create mode 100644 smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/BuildJavaBean.java create mode 100644 smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/HexTest.java create mode 100644 smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/ModelFormTest.java create mode 100644 smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/SpelTest.java create mode 100644 smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/TestMain.java create mode 100644 smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/ToolTest.java create mode 100644 smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/TreeDataBuilderTest.java create mode 100644 smtweb-framework/bpm/src/test/resources/code/index.vue create mode 100644 smtweb-framework/bpm/src/test/resources/code/index.vue.tmp create mode 100644 smtweb-framework/bpm/src/test/resources/code/list.xml create mode 100644 smtweb-framework/bpm/src/test/resources/db/smt_uc.json create mode 100644 smtweb-framework/bpm/src/test/resources/template/index.vm create mode 100644 smtweb-framework/bpm/src/test/resources/ui/508660168293093376.json create mode 100644 smtweb-framework/core/pom.xml create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplication.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwAttr.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwBean.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwBody.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwColumn.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwConstruct.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwDestroy.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwParam.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwPerm.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwScheduling.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/CacheManager.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/ISwCache.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/SessionCache.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisBroadcastEvent.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisPooledObjectFactory.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisSysTask.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/AbstractEnum.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/IntEnum.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/R.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/StrEnum.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwIpAddr.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwMap.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityDao.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/cache/EntityCache.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/config/DbEngineConfiguration.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/config/YamlPropertyLoaderFactory.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumnForeign.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultDatabaseInfoImpl.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultEntity.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/AbsDbWorker.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/IDbWorker.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/MapPropertyRowMapper.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/SwMapPropertyRowMapper.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractSelectSqlBuilder.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractUpdateSqlBuilder.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/InsertSqlBuilder.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SelectSqlBuilder.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlFieldValue.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinField.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinTable.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlWhereValue.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelDatabase.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelIndex.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelLinkName.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/BindParamException.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/BizException.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/ExceptionMessage.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/SwException.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/ISchedulerWakeup.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/GlobalExceptionHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiConfigBean.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/DefaultPageController.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/ControllerAccess.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IMethodAccess.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodAccess.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/BeanContext.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/ParamEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/AbstractContextEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/BeanEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/HttpServletRequestEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/NullEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/SwIpAddrEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractNumberEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractParameterEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractRequestEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BooleanEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ByteEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/CharEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DoubleEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/LongEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimeEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimestampEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/path/PathParamEditor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/BeanManager.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ClassParser.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanAction.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanActionBuilder.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/MethodParser.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/PackageScanner.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ScanContext.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/IRealmLoader.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthenticationException.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthorizationException.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnauthenticatedException.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AbstractPermInterceptor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AuthorizationInterceptor.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermCheckItem.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermChecker.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJob.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobQueue.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/FixedTimerTask.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerPoint.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerTaskManager.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJobQueue.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJob.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJobQueue.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompProvider.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractDelHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractListHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractLoadHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultComboHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultListHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultLoadHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultSaveHandler.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/IDataProvider.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/IWorker.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlNamedPara.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlPara.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SwListData.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/list/FooterField.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/ICalcVar.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariable.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariableFactory.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionManager.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/UserSessionArgumentResolver.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysTaskManager.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/WebStartedEvent.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/CommUtil.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/IpAddrUtil.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/JsonUtil.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/NumberUtil.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/SpringUtil.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/VariableUtil.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/BaseBeanSerializer.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/DateDeserializer.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/LongDeserializer.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/LongSerializer.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/NullSerializer.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/TimestampDeserializer.java create mode 100644 smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/kryo/KryoTool.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/AbstractTimerTrigger.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/CronExpression.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/FixedRateTrigger.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/ModelTimeoutClient.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/ModelTimeoutTask.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/NonConcurrentTask.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/OneTimeTrigger.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/RealTimeTimer.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/SystemTimeSource.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/TaskQueue.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/TimeSource.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/TimerTask.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java create mode 100644 smtweb-framework/core/src/main/java/com/serotonin/timer/sync/Synchronizer.java create mode 100644 smtweb-framework/core/src/main/resources/META-INF/spring.factories create mode 100644 smtweb-framework/core/src/main/resources/config/application-dev.yaml create mode 100644 smtweb-framework/core/src/main/resources/config/application-prod.yaml create mode 100644 smtweb-framework/core/src/test/java/cc/smtweb/framework/test/DaoTransTest.java create mode 100644 smtweb-framework/core/src/test/java/cc/smtweb/framework/test/NamedJdbcTest.java create mode 100644 smtweb-framework/core/src/test/java/cc/smtweb/framework/test/SqlBuilderTest.java create mode 100644 smtweb-framework/core/src/test/java/cc/smtweb/framework/test/ToolEnum2Js.java delete mode 100644 smtweb-framework/sw-framework-core/doc/TODO.mk delete mode 100644 smtweb-framework/sw-framework-core/pom.xml delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplication.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreAutoConfiguration.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwAction.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwAttr.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwBean.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwBody.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwColumn.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwColumnForeign.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwConstruct.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwDestroy.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwHeaderParam.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwParam.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwPathParam.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwPerm.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwScheduling.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwService.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwTable.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractEntityCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/CacheManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/ISwCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/SessionCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/SessionCacheFactory.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisBroadcastEvent.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisConnection.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisPooledObjectFactory.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisSysTask.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/config/RedisConfig.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/AbstractEnum.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/IntEnum.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/R.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/StrEnum.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwIpAddr.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwMap.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/EntityDao.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/EntityCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelTableCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/config/DbEngineConfiguration.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/config/YamlPropertyLoaderFactory.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumn.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumnForeign.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/BaseBean.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultDatabaseInfoImpl.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultEntity.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/UtilTime.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/AbsDbWorker.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/BaseBeanPropertyRowMapper.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/IDbWorker.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/IdGenerator.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcTrans.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/MapPropertyRowMapper.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/SwMapPropertyRowMapper.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractSelectSqlBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractUpdateSqlBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/DeleteSqlBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/DirectSelectSqlBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/InsertSqlBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SelectSqlBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlFieldValue.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinField.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinTable.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlWhereValue.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/UpdateSqlBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelCache.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelCatalog.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelDatabase.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelField.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelIndex.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelLinkName.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelProject.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelTable.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BindBeanException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BindParamException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BizException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/DbException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/ExceptionMessage.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/JsonParseException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/SwException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/ISchedulerWakeup.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/SchedulerManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/ControllerConfig.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/GlobalExceptionHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/SettingsEnvironmentPostProcessor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiConfigBean.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiController.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/DefaultPageController.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IActionManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IBeanContext.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/MethodAccessManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/BindFieldAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/ControllerAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/FieldAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IBeanAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IMethodAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodParamAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/SchedulerMethodAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/SingletonFieldAccess.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/BeanContext.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/CacheEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/ParamEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/WebDataBinder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/attr/AbstractAttrEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/attr/BeanAttrEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/AbstractContextEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/BeanEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/HttpServletRequestEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/NullEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/SwIpAddrEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/UserSessionEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/BeanBodyEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/BeanUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/StringBodyEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractNumberEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractParameterEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractRequestEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BeanTypeEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BooleanEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ByteEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/CharEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DateEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DoubleEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/FloatEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/IntegerEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/LongEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ShortEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/StringEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimeEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimestampEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/path/PathParamEditor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ApplicationScanner.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/BeanManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ClassParser.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanAction.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanActionBuilder.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/MethodParser.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/PackageScanner.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ScanContext.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/UrlMaker.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/IRealmLoader.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthenticationException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthorizationException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/ForbiddenException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnauthenticatedException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnknownAccountException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AbstractPermInterceptor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AuthorizationInterceptor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/PermInterceptor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermCheckItem.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermChecker.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJob.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobExecutor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobQueue.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/CronTimerTask.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/FixedTimerTask.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerPoint.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerTaskManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJob.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJobQueue.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/LocalJobExecutor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/RedisJobExecutor.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJob.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJobQueue.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompProvider.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompService.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractDelHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractListHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractLoadHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractSaveHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractTreeHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultComboHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultDelHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultListHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultLoadHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultProvider.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultSaveHandler.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/IDataProvider.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/IWorker.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlNamedPara.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlPara.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SwListData.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/list/FooterField.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/ICalcVar.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariable.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariableFactory.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/SessionManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/UserSession.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/UserSessionArgumentResolver.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/ISysTask.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/SysTaskManager.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/TaskStartEvent.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/WebStartedEvent.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/CommUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/DateUtil.java create mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/FileUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/IpAddrUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/JsonUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/MapUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/NumberUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/SpringUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/SqlUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/VariableUtil.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/BaseBeanSerializer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/DateDeserializer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/DateSerializer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/LongDeserializer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/LongSerializer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/NullSerializer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/TimeSerializer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/TimestampDeserializer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/kryo/KryoTool.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/AbstractTimer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/AbstractTimerTrigger.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/CronExpression.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/CronTimerTrigger.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ExecutionRejectedException.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/FixedDelayTrigger.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/FixedRateTrigger.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ModelTimeoutClient.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ModelTimeoutTask.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/NamedRunnable.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/NonConcurrentTask.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/OneTimeTrigger.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/RealTimeTimer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ScheduledNamedRunnable.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ScheduledRunnable.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SimulationTimeSource.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SimulationTimer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SystemTimeSource.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TaskQueue.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimeSource.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimeoutTask.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerTask.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerThread.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerTrigger.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/AsyncJobSink.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/Synchronizer.java delete mode 100644 smtweb-framework/sw-framework-core/src/main/resources/META-INF/spring.factories delete mode 100644 smtweb-framework/sw-framework-core/src/main/resources/config/application-dev.yaml delete mode 100644 smtweb-framework/sw-framework-core/src/main/resources/config/application-prod.yaml delete mode 100644 smtweb-framework/sw-framework-core/src/main/resources/config/application.yaml delete mode 100644 smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/DaoTransTest.java delete mode 100644 smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/JsonTest.java delete mode 100644 smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/NamedJdbcTest.java delete mode 100644 smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/SqlBuilderTest.java delete mode 100644 smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/TestMain.java delete mode 100644 smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/ToolEnum2Js.java delete mode 100644 smtweb-framework/sw-framework-core/target/classes/META-INF/spring.factories delete mode 100644 smtweb-framework/sw-framework-core/target/classes/config/application-dev.yaml delete mode 100644 smtweb-framework/sw-framework-core/target/classes/config/application-prod.yaml delete mode 100644 smtweb-framework/sw-framework-core/target/classes/config/application.yaml delete mode 100644 smtweb-framework/sw-framework-core/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst delete mode 100644 smtweb-framework/sw-framework-core/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst delete mode 100644 smtweb-framework/sw-system-bpm/.gitignore delete mode 100644 smtweb-framework/sw-system-bpm/doc/SwBody.puml delete mode 100644 smtweb-framework/sw-system-bpm/doc/TODO.md delete mode 100644 smtweb-framework/sw-system-bpm/doc/TODO20210714.md delete mode 100644 smtweb-framework/sw-system-bpm/doc/smt_asp20201229.txt delete mode 100644 smtweb-framework/sw-system-bpm/doc/trans.sql delete mode 100644 smtweb-framework/sw-system-bpm/doc/update20210907.sql delete mode 100644 smtweb-framework/sw-system-bpm/doc/update20211122.sql delete mode 100644 smtweb-framework/sw-system-bpm/doc/版本修改说明.md delete mode 100644 smtweb-framework/sw-system-bpm/pom.xml delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenUtil.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FileFixPath.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseComboHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableComboHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableSaveHanlder.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ActivityInfo.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/HandlerInfo.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/SignInfo.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/TransInfo.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetDynCond.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetEnumData.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetField.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetSortField.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageModel.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageLoadHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageProvider.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageSaveHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynRetBean.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CandidateEntity.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CareEntity.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CommentEntity.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/ProcinstEntity.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/SignEntity.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskRelEntity.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/AuthService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginAckVO.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginVO.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/MenuPO.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/UserPO.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/Area.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaCache.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaHandler.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaService.java delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/META-INF/spring.factories delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/dataset.ts delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/events.ts delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/formatter.ts delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/page.less delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/page.types.ts delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/dataset.ts.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/events.ts.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/index.vue.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/router.ts.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/CardService.java.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/ListService.java.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/TreeService.java.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/entity.java.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/event.js.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/config/application.yaml delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/config/logback.xml delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/event/defaultEvent.js delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/index.html delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/demo.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_filter.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_form.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_grid_opt.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_model.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/index.yaml delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_bean.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_cache.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_service.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/js_event.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_card.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_list.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_simple.ftl delete mode 100644 smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/BpmTest.java delete mode 100644 smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/BuildJavaBean.java delete mode 100644 smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/HexTest.java delete mode 100644 smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/ModelFormTest.java delete mode 100644 smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/SpelTest.java delete mode 100644 smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/TestMain.java delete mode 100644 smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/ToolTest.java delete mode 100644 smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/TreeDataBuilderTest.java delete mode 100644 smtweb-framework/sw-system-bpm/src/test/resources/code/index.vue delete mode 100644 smtweb-framework/sw-system-bpm/src/test/resources/code/index.vue.tmp delete mode 100644 smtweb-framework/sw-system-bpm/src/test/resources/code/list.xml delete mode 100644 smtweb-framework/sw-system-bpm/src/test/resources/db/smt_uc.json delete mode 100644 smtweb-framework/sw-system-bpm/src/test/resources/template/index.vm delete mode 100644 smtweb-framework/sw-system-bpm/src/test/resources/ui/508660168293093376.json diff --git a/smtweb-framework/bpm/.gitignore b/smtweb-framework/bpm/.gitignore new file mode 100644 index 0000000..29fde54 --- /dev/null +++ b/smtweb-framework/bpm/.gitignore @@ -0,0 +1,28 @@ +# ---> Java +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +.idea/ +*.iml +target diff --git a/smtweb-framework/bpm/doc/SwBody.puml b/smtweb-framework/bpm/doc/SwBody.puml new file mode 100644 index 0000000..27862c3 --- /dev/null +++ b/smtweb-framework/bpm/doc/SwBody.puml @@ -0,0 +1,10 @@ +@startuml +(*) --> "check input" +If "input is verbose" then +--> [Yes] "turn on verbosity" +--> "run command" +else +--> "run command" +Endif +--> (*) +@enduml diff --git a/smtweb-framework/bpm/doc/TODO.md b/smtweb-framework/bpm/doc/TODO.md new file mode 100644 index 0000000..4160543 --- /dev/null +++ b/smtweb-framework/bpm/doc/TODO.md @@ -0,0 +1,4 @@ +[db design] +1. 同步数据库时返回需要手段删除的字段和表 +2. 导出和导入数据结构 +3. 数据库名不允许重复 diff --git a/smtweb-framework/bpm/doc/TODO20210714.md b/smtweb-framework/bpm/doc/TODO20210714.md new file mode 100644 index 0000000..42998d4 --- /dev/null +++ b/smtweb-framework/bpm/doc/TODO20210714.md @@ -0,0 +1,11 @@ +[ui design] +1. 数据库源字段有多个N:N非ID字段取值的情况,避免重复取值的情况 +2. bug outline-panel上下移动 +3. panel 调整方向后没有重新计算位置 +4. redo/undo +[bpm] +1. ** 后台检测数据集需要配置ID作用字段 +2. 后台检测数据集必须配置idField +3. 后台验证和前台统一 +4. PO代码生成加字段注解 +5. ** 卡片保存时未返回id值 diff --git a/smtweb-framework/bpm/doc/smt_asp20201229.txt b/smtweb-framework/bpm/doc/smt_asp20201229.txt new file mode 100644 index 0000000..ce4160c --- /dev/null +++ b/smtweb-framework/bpm/doc/smt_asp20201229.txt @@ -0,0 +1,6 @@ +ALTER TABLE `asp_model` + ADD COLUMN `mode_md_id` BIGINT(20) NULL DEFAULT NULL COMMENT '����ģ��id, asp_model_delply.md_id' AFTER `model_order`; + +ALTER TABLE `asp_model` + ADD CONSTRAINT `FK_asp_model_asp_model_deploy` FOREIGN KEY (`mode_md_id`) REFERENCES `asp_model_deploy` (`md_id`); + diff --git a/smtweb-framework/bpm/doc/trans.sql b/smtweb-framework/bpm/doc/trans.sql new file mode 100644 index 0000000..c4fb911 --- /dev/null +++ b/smtweb-framework/bpm/doc/trans.sql @@ -0,0 +1,26 @@ +-- 用户中心迁移数据 + +INSERT INTO sys_area(area_id, area_code, area_full_code, area_order, area_name, area_full_name, area_type, area_province_name, area_city_name, area_town_name, + area_town_full_name, area_village_name, area_village_full_name, area_community_name, area_community_full_name, + area_tree_level, area_parent_id, area_parent_id_list, area_status, area_stop_desc, area_desc, area_last_time, area_create_party_id + ) SELECT `area_id`, `area_code`, `area_code_12`, `sequence_code`, `area_name`, `area_full_name`, `area_type`, `area_name_shengshi`, `area_name_dishi`, `area_name_quxian`, `area_full_name_quxian`, `area_name_xiangz`, `area_full_name_xiangz`, `area_name_chun`, `area_full_name_chun`, `tree_level`, `parent_id`, `parent_id_list`, `statu`, `stop_desc`, `description`, `last_time`, `create_party_id` FROM tb_sys_area; + + +INSERT INTO sw_user.sys_user(user_id, user_code, user_nick_code, user_nick_name, user_kind, user_sex, user_head, user_signature, user_phone, user_email, + user_pwd, user_score, user_level, user_otp_id, user_err_count, user_lock_time, user_stop_info, user_pwd_time, user_last_time, user_last_ip, + user_last_info, user_status, user_create_party_id, user_create_time) +SELECT user_id, user_code, nick_code, nick_name, user_kind, user_sex, user_head, user_signature, user_phone, user_email, + user_pwd, user_score, user_level, otp_id, err_count, lock_time, stop_info, pwd_time, last_time, last_ip, + last_info, statu, create_party_id, last_time FROM demo.tb_sys_user_base; + +INSERT INTO sw_user.sys_user_card(uc_id, uc_card_name, uc_card_type, uc_card_number, uc_card_pic_url, uc_card_from_time, + uc_card_end_time, uc_card_authority, uc_card_addr, uc_id_status, uc_status, uc_desc, uc_last_time, uc_create_party_id) +SELECT user_id, user_name, card_type, card_number, card_pic_url, card_from, + card_end, id_authority, id_addr, id_statu, statu, remarks, last_time, create_party_id +FROM demo.tb_sys_user_card; + +INSERT INTO sw_user.sys_user_ex (ue_id, ue_cert_id, ue_party_id, ue_dept_id, ue_portal_id, + ue_portal_type, ue_portal_bi_url, ue_station, ue_tel, ue_otp_id, ue_is_fix, ue_msspid, ue_photo_id, ue_last_time, ue_create_party_id) +SELECT user_id, user_cert_id, party_id, department_id, portal_id, + portal_type, portal_bi_url, station, tel, otp_id, is_fix, msspid, photo_id, last_time, create_party_id +FROM demo.tb_sys_user_ex; diff --git a/smtweb-framework/bpm/doc/update20210907.sql b/smtweb-framework/bpm/doc/update20210907.sql new file mode 100644 index 0000000..9d0ac10 --- /dev/null +++ b/smtweb-framework/bpm/doc/update20210907.sql @@ -0,0 +1,75 @@ +CREATE TABLE `bpm_model` ( + `model_id` BIGINT(20) NOT NULL, + `model_full_name` VARCHAR(64) NULL DEFAULT NULL COMMENT '用.连接唯一地址:模块名+全路径名称' COLLATE 'utf8_unicode_ci', + `model_name` VARCHAR(200) NOT NULL COMMENT '名称' COLLATE 'utf8_unicode_ci', + `model_type` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '模型类型: 1 数据模型,2 工作流模型,3 PC界面,4 手机界面', + `model_content` MEDIUMTEXT NULL DEFAULT NULL COMMENT '内容,json格式' COLLATE 'utf8_unicode_ci', + `model_content_sign` VARCHAR(100) NULL DEFAULT NULL COMMENT 'sha256(内容),内容长度', + `model_status` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '状态:0 启用,1 禁用', + `model_version` INT(11) NOT NULL DEFAULT '0' COMMENT '版本', + `model_order` INT(11) NOT NULL DEFAULT '0' COMMENT '排序', + `model_site_id` BIGINT(20) NULL DEFAULT NULL COMMENT '站点ID', + `model_create_time` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '创建时间', + `model_last_time` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '更新时间', + PRIMARY KEY (`model_id`) USING BTREE, + UNIQUE INDEX `model_full_name` (`model_full_name`) USING BTREE +) +COMMENT='应用支撑平台模型定义' +COLLATE='utf8_unicode_ci' +ENGINE=InnoDB +ROW_FORMAT=DYNAMIC +; + +ALTER TABLE `asp_model` + CHANGE COLUMN `model_create_at` `model_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `model_update_uid`, + CHANGE COLUMN `model_update_at` `model_last_time` BIGINT NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `model_create_time`; + +ALTER TABLE `asp_model_catalog` + CHANGE COLUMN `mc_create_at` `mc_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `mc_module`, + CHANGE COLUMN `mc_update_at` `mc_last_time` BIGINT NOT NULL DEFAULT 0 AFTER `mc_create_time`; + +ALTER TABLE `asp_model_deploy` + CHANGE COLUMN `md_create_at` `md_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `md_update_uid`, + CHANGE COLUMN `md_update_at` `md_last_time` BIGINT NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `md_create_time`; + +ALTER TABLE `bpm_dyn_form_log` + CHANGE COLUMN `dfl_create_at` `dfl_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `dfl_lock_rev`, + CHANGE COLUMN `dfl_update_at` `dfl_last_time` BIGINT NOT NULL DEFAULT 0 AFTER `dfl_create_time`; + +ALTER TABLE `bpm_node_log` + CHANGE COLUMN `nl_create_at` `nl_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `nl_duration`; + +ALTER TABLE `bpm_process` + CHANGE COLUMN `process_create_at` `process_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `process_route`, + CHANGE COLUMN `process_update_at` `process_last_time` BIGINT NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `process_create_time`; + +ALTER TABLE `bpm_process_user` + CHANGE COLUMN `pu_create_at` `pu_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `pu_type`, + CHANGE COLUMN `pu_update_at` `pu_last_time` BIGINT NOT NULL DEFAULT 0 AFTER `pu_create_time`; + +ALTER TABLE `bpm_task` + CHANGE COLUMN `task_create_at` `task_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `task_due_time`, + CHANGE COLUMN `task_update_at` `task_last_time` BIGINT NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `task_create_time`; + +ALTER TABLE `bpm_process_log` + CHANGE COLUMN `pl_create_at` `pl_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `pl_route`; + +ALTER TABLE `bpm_process_attachment_log` + CHANGE COLUMN `pal_create_at` `pal_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `pal_type`; + +ALTER TABLE `bpm_process_comment_log` + CHANGE COLUMN `pcl_create_at` `pcl_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `pcl_content`; + +ALTER TABLE `bpm_process_detail_log` + CHANGE COLUMN `pdl_create_at` `pdl_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `pdl_lock_rev`, + CHANGE COLUMN `pdl_update_at` `pdl_last_time` BIGINT NOT NULL DEFAULT 0 AFTER `pdl_create_time`; + +ALTER TABLE `bpm_task_log` + CHANGE COLUMN `tl_create_at` `tl_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `tl_claim_time`; + +ALTER TABLE `bpm_variable` + CHANGE COLUMN `var_create_at` `var_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `var_lock_rev`, + CHANGE COLUMN `var_update_at` `var_update_time` BIGINT NOT NULL DEFAULT 0 AFTER `var_create_time`; + +ALTER TABLE `bpm_variable_log` + CHANGE COLUMN `vl_create_at` `vl_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `vl_lock_rev`; diff --git a/smtweb-framework/bpm/doc/update20211122.sql b/smtweb-framework/bpm/doc/update20211122.sql new file mode 100644 index 0000000..d87633b --- /dev/null +++ b/smtweb-framework/bpm/doc/update20211122.sql @@ -0,0 +1,6 @@ +ALTER TABLE `asp_model` + ADD COLUMN `model_sub_type` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '模型子类型:0 默认 1 页面 2 子页面 3 目录' AFTER `model_type`; +ALTER TABLE `asp_model` + ADD COLUMN `model_icon` VARCHAR(50) NULL COMMENT '图标' AFTER `model_sub_type`; +ALTER TABLE `asp_model_catalog` + ADD COLUMN `mc_icon` VARCHAR(50) NOT NULL COMMENT '项目图标' AFTER `mc_name`; diff --git a/smtweb-framework/bpm/doc/版本修改说明.md b/smtweb-framework/bpm/doc/版本修改说明.md new file mode 100644 index 0000000..d1c430f --- /dev/null +++ b/smtweb-framework/bpm/doc/版本修改说明.md @@ -0,0 +1,8 @@ +2.1.0 break changes +1. 数据库升级 update20210907 + smt_ => sw_ +2. 必填和验证规则设置到数据集里面了 +3. 移除数据集的表类型属性tableType, 添加 initData + + +后台写 defaultEvent.js 后台 ctrl+shift+f9 diff --git a/smtweb-framework/bpm/pom.xml b/smtweb-framework/bpm/pom.xml new file mode 100644 index 0000000..150d9ad --- /dev/null +++ b/smtweb-framework/bpm/pom.xml @@ -0,0 +1,216 @@ + + + 4.0.0 + + sw-system-bpm + cc.smtweb + 3.1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.5.6 + + + + + 1.8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + cc.smtweb + sw-framework-core + 3.1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-freemarker + + + net.coobird + thumbnailator + [0.4, 0.5) + + + org.jclarion + image4j + 0.7 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.11.0 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.11.0 + + + + + + + + + org.apache.velocity + velocity-engine-core + 2.3 + compile + + + org.springframework.boot + spring-boot-test + test + + + + org.junit.platform + junit-platform-launcher + 1.6.2 + test + + + + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + org.junit.vintage + junit-vintage-engine + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-params + 5.6.2 + test + + + + + + + + + + + + org.mockito + mockito-all + 1.10.19 + test + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + verify + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + config/application.yaml + config/application-dev.yaml + config/application-prod.yaml + + + + + + + + E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-ui-design-vue/dist/ + ${basedir}/target/classes/static/design/ui + + + + E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-db-design-vue/dist/ + ${basedir}/target/classes/static/design/db + + + + E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-flow-design-vue/dist/ + ${basedir}/target/classes/static/design/flow + + + + E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-framework-widget-vue/dist/ + ${basedir}/target/classes/static/design/preview + + + + src/main/resources + + + + + + + nexus-releases + Nexus Release Repository + http://47.92.149.153:7000/repository/maven-releases/ + + + nexus-snapshots + Nexus Snapshot Repository + http://47.92.149.153:7000/repository/maven-snapshots/ + + + diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java new file mode 100644 index 0000000..3c3543b --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java @@ -0,0 +1,14 @@ +package cc.smtweb.system.bpm.spring; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author xkliu + */ +@SpringBootApplication +public class BpmApplication { + public static void main(String[] args) { + SpringApplication.run(BpmApplication.class, args); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java new file mode 100644 index 0000000..211a8f7 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java @@ -0,0 +1,19 @@ +package cc.smtweb.system.bpm.spring; + +import cc.smtweb.framework.core.mvc.config.ControllerConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +/** + * @author kevin + */ +@Configuration +@ComponentScan +public class BpmAutoConfiguration { + /** 配置自定义service扫描路径 {module}/{service}/{method} */ + @Bean + public ControllerConfig bpmControllerConfig() { + return new ControllerConfig("bpm", "cc.smtweb.system.bpm.web", null); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java new file mode 100644 index 0000000..454e6ff --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java @@ -0,0 +1,14 @@ +package cc.smtweb.system.bpm.spring; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "smtweb.bpm") +@Data +public class BpmConfigBean { + // 是否debug模式 + private boolean debug; + private String codeJavaPath; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java new file mode 100644 index 0000000..19475c5 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java @@ -0,0 +1,26 @@ +package cc.smtweb.system.bpm.spring.config; + +import cc.smtweb.system.bpm.util.FilePathGenerator; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import cc.smtweb.framework.core.db.jdbc.IdGenerator; + +/** + * 微服务框架封装自动配置类 + */ +@Configuration +public class FileConfig { + // 文件本地存储配置 + @Value("${smtweb.file.local-path}") + private String fileLocalPath; + + // 文件请求URL路径配置 http://127.0.0.1:${server.port}/${server.servlet.context-path}/files/ + @Value("${smtweb.file.url}") + private String fileUrl; + + @Bean + public FilePathGenerator filePathGenerator(IdGenerator idGenerator) { + return new FilePathGenerator(fileLocalPath, fileUrl, idGenerator); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java new file mode 100644 index 0000000..40e6795 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java @@ -0,0 +1,185 @@ +package cc.smtweb.system.bpm.spring.controller; + +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.session.SessionUtil; +import cc.smtweb.system.bpm.util.FilePathGenerator; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.*; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.util.concurrent.TimeUnit; + +@RestController +public class FileDownloadController { + private static final MediaType APPLICATION_JAVASCRIPT = new MediaType("application", "javascript"); + @Value("${smtweb.static.local-path:}") + private String staticLocalPath; + + @Autowired + private FilePathGenerator filePathGenerator; + + @Autowired + private RedisManager redisManager; + + /** path方式下载文件 */ + @GetMapping("/fs/files/**") + public ResponseEntity files(@RequestParam(value="name", required=false) String name, + @RequestParam(value="noCache", required=false) Boolean noCache, + HttpServletRequest request + ) throws FileNotFoundException { + String filePath = request.getRequestURI().substring(10); + return download(filePath, name, noCache, request); + } + + /** 参数方式下载文件 */ + @GetMapping("/fs/download") + public ResponseEntity download(@RequestParam(value="path") String path, + @RequestParam(value="name", required=false) String name, + @RequestParam(value="noCache", required=false) Boolean noCache, + HttpServletRequest request + ) throws FileNotFoundException { + SessionUtil.checkSession(request, redisManager); + + File file = new File(filePathGenerator.getFileDiskPath(path)); + + if (!file.exists()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + } + + if (StringUtils.isBlank(name)) { + name = file.getName(); + } + + HttpHeaders headers = new HttpHeaders(); + if (Boolean.TRUE.equals(noCache)) { + headers.setCacheControl("no-cache, no-store, must-revalidate"); + headers.setPragma("no-cache"); + headers.setExpires(0); + } + + headers.setLastModified(file.lastModified()); + headers.add("Content-Disposition", + String.format("attachment; filename=\"%s\"", new String(name.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1))); + + return ResponseEntity.ok() + .headers(headers) + .contentLength(file.length()) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(new InputStreamResource(new FileInputStream(file))); + } + + /** path方式读取静态目录文件 */ + @GetMapping("/fs/static/**") + public ResponseEntity resource(@RequestParam(value="default", required=false) String defaultPath, + @RequestParam(value="noCache", required=false) Boolean noCache, + @RequestHeader(value="If-Modified-Since", required = false) String ifModifiedSince, + HttpServletRequest request) throws FileNotFoundException { + String filePath = request.getRequestURI().substring(11); + + HttpHeaders headers = new HttpHeaders(); + + if (Boolean.TRUE.equals(noCache)) { + headers.setCacheControl("no-cache, no-store, must-revalidate"); + headers.setPragma("no-cache"); + headers.setExpires(0); + } else { + // 暂时缓存1天 + headers.setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)); + headers.setExpires(Instant.ofEpochMilli(System.currentTimeMillis() + DateUtils.MILLIS_PER_DAY)); + } + + String name = getFileName(filePath); + headers.add("Content-Disposition", + String.format("attachment; filename=\"%s\"", new String(name.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1))); + + MediaType contentType = getContentType(filePath); + // 先找文件 + if (StringUtils.isNotBlank(staticLocalPath)) { + File file = new File(staticLocalPath + filePath); + + if (file.exists()) { + headers.setLastModified(file.lastModified()); + + return ResponseEntity.ok() + .headers(headers) + .contentLength(file.length()) + .contentType(contentType) + .body(new InputStreamResource(new FileInputStream(file))); + } + } + + // 再找资源目录 + InputStream inputStream = getClass().getResourceAsStream("/static/" + filePath); + if (inputStream != null) { + return buildResource(inputStream, contentType, headers); + } else if (StringUtils.isNotBlank(defaultPath)) { + inputStream = getClass().getResourceAsStream("/static/" + defaultPath); + if (inputStream != null) { + return buildResource(inputStream, contentType, headers); + } + } + + return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + } + + private String getFileName(String filePath) { + int pos = filePath.lastIndexOf("/"); + if (pos >= 0) { + return filePath.substring(pos + 1); + } + + return filePath; + } + + private ResponseEntity buildResource(InputStream inputStream, MediaType contentType, HttpHeaders headers) { + return ResponseEntity.ok() + .headers(headers) +// .contentLength(file.length()) + .contentType(contentType) + .body(new InputStreamResource(inputStream)); + } + + private static MediaType getContentType(String filePath) { + int pos = filePath.lastIndexOf("."); + + if (pos >= 0) { + String fileExt = filePath.substring(pos + 1).toLowerCase(); + switch (fileExt) { + case "htm": + case "html": + case "css": + return MediaType.TEXT_HTML; + case "js": + return APPLICATION_JAVASCRIPT; + case "txt": + return MediaType.TEXT_PLAIN; + case "pdf": + return MediaType.APPLICATION_PDF; + case "xml": + return MediaType.TEXT_XML; + case "gif": + return MediaType.IMAGE_GIF; + case "jpeg": + case "jpg": + return MediaType.IMAGE_JPEG; + case "png": + return MediaType.IMAGE_PNG; + default: + return MediaType.APPLICATION_OCTET_STREAM; + } + } + + return MediaType.APPLICATION_OCTET_STREAM; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java new file mode 100644 index 0000000..b0f1404 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java @@ -0,0 +1,157 @@ +package cc.smtweb.system.bpm.spring.controller; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.session.SessionUtil; +import cc.smtweb.system.bpm.spring.dao.ImageAttachDao; +import cc.smtweb.system.bpm.util.FilePathGenerator; +import cc.smtweb.system.bpm.util.FilePathInfo; +import cc.smtweb.system.bpm.util.MemMultipartFile; +import cc.smtweb.system.bpm.util.ThumbImage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import cc.smtweb.system.bpm.spring.entity.FileDataVO; +import cc.smtweb.system.bpm.spring.entity.UploadDataVO; + +import javax.servlet.http.HttpServletRequest; +import java.io.*; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; + +@RestController +public class FileUploadController { + @Autowired + private FilePathGenerator filePathGenerator; + + @Autowired + private DbEngine dbEngine; + + @Autowired + private RedisManager redisManager; + + @Autowired + private ImageAttachDao imageAttachDao; + + // TODO: 权限处理,临时文件处理 + @PostMapping("/fs/upload/{path}") + public R upload(@RequestParam("file") MultipartFile file, @PathVariable("path") String path, + @RequestParam(value="thumb", required=false) String thumb, + @RequestParam(value="thumbHeight", required=false) Integer thumbHeight, + @RequestParam(value="commit", required=false) Boolean insert, + @RequestParam(value="keepName", required=false) Boolean keepName, + HttpServletRequest request + ) { + SessionUtil.checkSession(request, redisManager); + return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, insert, keepName); + } + + @PostMapping("/fs/uploadImage/{path}") + public R upload(@RequestBody FileDataVO data, @PathVariable("path") String path, + @RequestParam(value="thumb", required=false) String thumb, + @RequestParam(value="thumbHeight", required=false) Integer thumbHeight, + @RequestParam(value="commit", required=false) Boolean insert, + HttpServletRequest request) { + SessionUtil.checkSession(request, redisManager); + + MultipartFile file = MemMultipartFile.build(data.getData()); + if (file == null) { + return R.error("数据内容格式有错"); + } + + return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, insert, false); + } + + @PostMapping("/fs/uploadAvatar/{path}") + public R uploadAvatar(@RequestParam("file") MultipartFile file, @PathVariable("path") String path, + @RequestParam(value="size", required=false) Integer size, + @RequestParam(value="commit", required=false) Boolean insert, + @RequestParam(value="keepName", required=false) Boolean keepName, + HttpServletRequest request) { + SessionUtil.checkSession(request, redisManager); + return uploadFile(path, file, ThumbImage.TYPE_AVATAR, size, insert, keepName); + } + + // 保存文件和插入数据库数据 + @PostMapping("/fs/commit/{path}") + public R commit(@RequestParam("file") MultipartFile file, @PathVariable("path") String path, + @RequestParam(value="thumb", required=false) String thumb, + @RequestParam(value="thumbHeight", required=false) Integer thumbHeight, + @RequestParam(value="keepName", required=false) Boolean keepName, + HttpServletRequest request) { + SessionUtil.checkSession(request, redisManager); + return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, true, keepName); + } + + private R uploadFile(String path, MultipartFile file, int type, Integer size, Boolean insert, Boolean keepName) { + //获取上传时的文件名 + String fileName = file.getOriginalFilename(); + + //判断文件是否为空 + if(file.isEmpty() && fileName != null){ + return R.error("文件为空"); + } + + // 判断保持文件名不变 + FilePathInfo fileInfo = filePathGenerator.make(path, fileName, Boolean.TRUE.equals(keepName)); + + // 注意是路径+文件名 + File targetFile = new File(fileInfo.getFullFileName()); + + try(InputStream inputStream = file.getInputStream(); OutputStream outputStream = new FileOutputStream(targetFile)) { + // 最后使用资源访问器FileCopyUtils的copy方法拷贝文件 + FileCopyUtils.copy(inputStream, outputStream); + } catch (IOException e) { + //出现异常,则告诉页面失败 + return R.error("上传失败", e); + } + + // 生成缩略图 +// String contentType = file.getContentType(); + UploadDataVO data = new UploadDataVO(); + + data.setPath(fileInfo.getMysqlFilePath()); + data.setName(fileName); + data.setSize(file.getSize()); + data.setContentType(file.getContentType()); + data.setUrl(filePathGenerator.getFileUrl(fileInfo.getMysqlFilePath())); + + if (type == ThumbImage.TYPE_THUMB || type == ThumbImage.TYPE_AVATAR) { + try { + imageAttachDao.makeThumb(data, type == ThumbImage.TYPE_THUMB, targetFile, size); + } catch (IOException e) { + return R.error("生成缩略图失败", e); + } + } + + if (Boolean.TRUE.equals(insert)) { + Long id = dbEngine.nextId(); + Timestamp now = new Timestamp(System.currentTimeMillis()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + + dbEngine.update("insert into sw_user.sys_attach(attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time) values(?, ?, ?, ?, ?, ?)", + id, data.getName(), data.getPath(), data.getContentType(), data.getSize(), sdf.format(now)); + + data.setId(id); + } + + return R.success(data); + } + + // TODO: 修改为安全的后台删除方式 + @PostMapping("/fs/remove") + public R remove(@RequestParam(value="filePath") String filePath, HttpServletRequest request) { + SessionUtil.checkSession(request, redisManager); + + File file = new File(filePathGenerator.getFileDiskPath(filePath)); + if (file.exists() && file.isFile()) { + if (file.delete()) { + R.success(filePath); + } + } + + return R.success(); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java new file mode 100644 index 0000000..322d293 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java @@ -0,0 +1,63 @@ +package cc.smtweb.system.bpm.spring.dao; + +import cc.smtweb.system.bpm.util.ThumbImage; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import cc.smtweb.system.bpm.spring.entity.UploadDataVO; + +import java.io.File; +import java.io.IOException; + +@Service +public class ImageAttachDao { + public static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; + + public void makeThumb(UploadDataVO data, boolean isThumb, File targetFile, Integer size) throws IOException { + boolean imageType = false; + String fileName = data.getName(); + String contentType = data.getContentType(); + + if (contentType.startsWith("image/")) { + imageType = true; + } else if (contentType.equals(APPLICATION_OCTET_STREAM)) { + String fileExt = fileName.substring(fileName.lastIndexOf(".")); + + if (StringUtils.isNotEmpty(fileExt)) { + switch (fileExt.toLowerCase()) { + case ".jpg": + case ".jpeg": + contentType = "image/jpg"; + imageType = true; + break; + case ".gif": + contentType = "image/gif"; + imageType = true; + break; + case ".png": + contentType = "image/png"; + imageType = true; + break; + default: + break; + } + + if (imageType) { + data.setContentType(contentType); + } + } + } + + if (imageType) { + int thumbHeight = 80; + if (size != null) { + thumbHeight = (size > 500) ? 500 : size; + } + + ThumbImage thumbImage = new ThumbImage(); + + thumbImage.makeThumb(isThumb, targetFile, thumbHeight); + data.setWidth(thumbImage.getImageWidth()); + data.setHeight(thumbImage.getImageHeight()); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java new file mode 100644 index 0000000..166e76b --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java @@ -0,0 +1,114 @@ +package cc.smtweb.system.bpm.spring.dao; + +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.system.bpm.spring.entity.AttachPathPO; +import cc.smtweb.system.bpm.util.FilePathGenerator; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.yaml.snakeyaml.util.UriEncoder; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class SysAttachDao { + @Autowired + private FilePathGenerator filePathGenerator; + + @Autowired + private DbEngine dbEngine; + + /** + * 获取文件本地文件路径 + * + * @param filePath 相对路径 + * @return 本地文件全路径 + */ + public String getDiskPath(String filePath) { + return filePathGenerator.getFileDiskPath(filePath); + } + + /** + * 获取访问文件的URL地址 + * + * @param filePath 文件相对路径 + * @return 文件URL地址 + */ + public String getFileUrl(String filePath) { + return filePathGenerator.getFileUrl(filePath); + } + + /** + * 获取访问文件的URL地址 + * + * @param filePath 文件相对路径 + * @param filePath 文件名 + * @return 文件URL地址 + */ + public String getFileUrl(String filePath, String fileName) { + return "/fs/download?path=" + UriEncoder.encode(filePath) + "&name=" + UriEncoder.encode(fileName); + } + + public AttachPathPO get(Long id) { + if (id != null) { + return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?", + AttachPathPO.class, id); + } + + return null; + } + + // 删除文件记录和文件 + public void remove(Long fileId) { +// if (id != null) { +// return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?", +// AttachPathPO.class, id); +// } +// +// return null; + } + + // 删除文件 + public void remove(String filePath) { +// if (id != null) { +// return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?", +// AttachPathPO.class, id); +// } +// +// return null; + } + + public List list(Long[] ids) { + if (ids != null && ids.length > 0) { + return dbEngine.query("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id in( " + + StringUtils.join(ids, ",") + ")", + AttachPathPO.class); + } + + return null; + } + + public Map map(Long[] ids) { + List list = list(ids); + if (list != null && !list.isEmpty()) { + Map map = new HashMap<>(list.size()); + list.forEach((item) -> map.put(item.getAttachId(), item)); + + return map; + } + + return null; + } + + // 保持文件,删除临时文件记录,避免被定时删除 + public void retain(String filePath) { + + } + + // 保持文件,删除临时文件记录,避免被定时删除 + public void retain(Long fileId) { + + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java new file mode 100644 index 0000000..399bfc7 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java @@ -0,0 +1,13 @@ +package cc.smtweb.system.bpm.spring.entity; + +import lombok.Data; + +@Data +public class AttachPathPO { + private Long attachId; + private String attachName; + private String attachPath; + private String attachContentType; + private Long attachSize; + private Long attachCreate; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java new file mode 100644 index 0000000..5754e26 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java @@ -0,0 +1,8 @@ +package cc.smtweb.system.bpm.spring.entity; + +import lombok.Data; + +@Data +public class FileDataVO { + private String data; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java new file mode 100644 index 0000000..d67aeb4 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java @@ -0,0 +1,15 @@ +package cc.smtweb.system.bpm.spring.entity; + +import lombok.Data; + +@Data +public class UploadDataVO { + private Long id; + private Integer height; + private Integer width; + private long size; + private String path; + private String name; + private String contentType; + private String url; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java new file mode 100644 index 0000000..4dbeabb --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java @@ -0,0 +1,120 @@ +package cc.smtweb.system.bpm.util; + +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class BeanUtil { + private BeanUtil() {} + + public static void mapToBean(SwMap source, Object target) { + mapToBean(source, target, null); + } + + private static void mapToBean(SwMap source, Object target, @Nullable Class editable, + @Nullable String... ignoreProperties) throws BeansException { + Assert.notNull(source, "Source must not be null"); + Assert.notNull(target, "Target must not be null"); + + Class actualEditable = target.getClass(); + if (editable != null) { + if (!editable.isInstance(target)) { + throw new IllegalArgumentException("Target class [" + target.getClass().getName() + + "] not assignable to Editable class [" + editable.getName() + "]"); + } + actualEditable = editable; + } + PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable); + List ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null); + + for (PropertyDescriptor targetPd : targetPds) { + Method writeMethod = targetPd.getWriteMethod(); + if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) { + Object value = source.get(targetPd.getName()); + + if (value == null || ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], value.getClass())) { + try { + if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { + writeMethod.setAccessible(true); + } + writeMethod.invoke(target, value); + } catch (Throwable ex) { + throw new FatalBeanException( + "Could not copy property '" + targetPd.getName() + "' from source to target", ex); + } + } + } + } + } + + public static void beanToMap(Object source, SwMap target, @Nullable String... ignoreProperties) throws BeansException { + Assert.notNull(source, "Source must not be null"); + Assert.notNull(target, "Target must not be null"); + + List ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null); + + PropertyDescriptor[] sourcePds = BeanUtils.getPropertyDescriptors(source.getClass()); + + for (PropertyDescriptor sourcePd: sourcePds) { + if (ignoreList == null || !ignoreList.contains(sourcePd.getName())) { +// PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getKey()); +// if (sourcePd != null) { + Method readMethod = sourcePd.getReadMethod(); + if (readMethod != null) { + try { + if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { + readMethod.setAccessible(true); + } + Object value = readMethod.invoke(source); + target.put(sourcePd.getName(), value); + } + catch (Throwable ex) { + throw new FatalBeanException( + "Could not copy property '" + sourcePd.getName() + "' from source to target", ex); + } + } +// } + } + } + } + + public static List toBeanList(List bodyList, Class clazz) { + List beans = new ArrayList<>(bodyList.size()); + try { + for (SwMap body: bodyList) { + Object bean = clazz.newInstance(); + BeanUtil.mapToBean(body, bean); + beans.add(bean); + } + } catch (InstantiationException | IllegalAccessException e) { + throw new SwException(e); + } + return beans; + } + + public static List toMapList(List beans) { + List bodyList = null; + if (beans != null) { + bodyList = new ArrayList<>(beans.size()); + for (Object bean: beans) { + SwMap body = new SwMap(); + beanToMap(bean, body); + bodyList.add(body); + } + } + + return bodyList; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenUtil.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenUtil.java new file mode 100644 index 0000000..c930682 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenUtil.java @@ -0,0 +1,111 @@ +package cc.smtweb.system.bpm.util; + +import org.apache.commons.lang3.StringUtils; + +public class CodeGenUtil { + private CodeGenUtil() { + } + + /*** + * 下划线命名转为驼峰命名 + * + * @param para + * 下划线命名的字符串 + */ + public static String underlineToHump(String para) { + StringBuilder result = new StringBuilder(); + String[] a = para.split("_"); + for (String s : a) { + if (result.length() == 0) { + result.append(s.toLowerCase()); + } else { + result.append(s.substring(0, 1).toUpperCase()); + result.append(s.substring(1).toLowerCase()); + } + } + return result.toString(); + } + + /*** + * 下划线命名转为大写驼峰命名 + * 大驼峰式命名法(upper camel case) + * + * @param para + * 下划线命名的字符串 + */ + public static String underlineToUpperHump(String para) { + StringBuilder result = new StringBuilder(); + String[] a = para.split("_"); + for (String s : a) { + result.append(s.substring(0, 1).toUpperCase()); + result.append(s.substring(1).toLowerCase()); + } + return result.toString(); + } + + /*** + * 驼峰命名转为下划线命名 + * + * @param para + * 驼峰命名的字符串 + */ + public static String humpToUnderline(String para) { + return humpTo(para, "_"); + } + + private static String humpTo(String para, String splitChar) { + StringBuilder sb = new StringBuilder(para); + //偏移量,第i个下划线的位置是 当前的位置+ 偏移量(i-1),第一个下划线偏移量是0 + int temp = 0; + for (int i = 0; i < para.length(); i++) { + if (Character.isUpperCase(para.charAt(i))) { + sb.insert(i + temp, splitChar); + temp += 1; + } + } + return sb.toString().toLowerCase(); + } + + /*** + * 驼峰命名转为横线线命名 + * + * @param para + * 驼峰命名的字符串 + */ + public static String humpToDash(String para) { + return humpTo(para, "-"); + } + + /** + * 大驼峰转小驼峰 + */ + public static String toLowerHump(String name) { + if (StringUtils.isNotBlank(name)) { + return Character.toLowerCase(name.charAt(0)) + name.substring(1); + } + + return ""; + } + + /** + * 小驼峰转大驼峰 + */ + public static String toUpperHump(String name) { + if (StringUtils.isNotBlank(name)) { + return Character.toUpperCase(name.charAt(0)) + name.substring(1); + } + + return ""; + } + + public static String getBeanName(String tableName) { + StringBuilder result = new StringBuilder(); + String[] a = tableName.split("_"); + for (int i = 1, len = a.length; i < len; i++) { + String s = a[i]; + result.append(s.substring(0, 1).toUpperCase()); + result.append(s.substring(1).toLowerCase()); + } + return result.toString(); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java new file mode 100644 index 0000000..c8a0fbf --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java @@ -0,0 +1,201 @@ +package cc.smtweb.system.bpm.util; + +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateMethodModelEx; +import freemarker.template.TemplateModelException; +import org.apache.commons.io.IOUtils; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by Akmm at 2022/6/8 15:36 + * 模板生成代码 + */ +public class CodeGenerator { + private final static String KEY_MODEL = "model"; + private final static String TEMPLATE_JAVA_BEAN = "java_bean"; + private final static String TEMPLATE_JAVA_CACHE = "java_cache"; + private final static String TEMPLATE_JAVA_SERVICE = "java_service"; + private final static String TEMPLATE_JS_EVENT = "js_event"; + private static CodeGenerator instance = null; + + private Configuration configuration = null; + + private final String encode = org.apache.commons.codec.CharEncoding.UTF_8; + //模板文件所在目录 +// private String templatesDir; + + //模板信息 + private SwMap mapTemplate; + + protected CodeGenerator() { +// templatesDir = this.getClass().getResource("/static/template").getPath(); + mapTemplate = YamlUtil.readValue(this.getClass().getResourceAsStream("/static/template/index.yaml"), SwMap.class); + configuration = new Configuration(Configuration.VERSION_2_3_31); + try { + configuration.setClassForTemplateLoading(this.getClass(), "/static/template/"); +// configuration.setDirectoryForTemplateLoading(new File(templatesDir)); + configuration.setClassicCompatible(true); + configuration.setDefaultEncoding(encode); + configuration.setOutputEncoding(encode); + } catch (Exception e) { + e.printStackTrace(); + throw new SwException(e); + } + } + + //页面设计的模板信息 + public List> getModelTemplates() { + return (List>)mapTemplate.get(KEY_MODEL); + } + + private void initModel(Map model) { + model.put("newId", new PKGenerator()); + } + + public void generate(Map model, String templateName, Writer writer) { + try { + initModel(model); + Template template = configuration.getTemplate(templateName, encode); + template.setOutputEncoding(encode); + template.process(model, writer); + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + throw new SwException(e); + } + } + + + public void generate(Map model, String templateName, String fileName) { + File file = new File(fileName); + if (file.exists()) file.delete(); + FileOutputStream out = null; + try { + file.createNewFile(); + out = new FileOutputStream(fileName); + + initModel(model); + Template template = configuration.getTemplate(templateName + ".ftl", StandardCharsets.UTF_8.toString()); + template.setOutputEncoding(encode); + template.process(model, new OutputStreamWriter(out, encode)); + out.flush(); + } catch (Exception e) { + throw new SwException("生成代码失败!", e); + } finally { + IOUtils.closeQuietly(out); + } + } + + public String generate(Map model, String templateName) { + StringWriter out = new StringWriter(); + generate(model, templateName + ".ftl", out); + return out.getBuffer().toString(); + } + + public void generateBean(Map model, String fileName) { + generate(model, TEMPLATE_JAVA_BEAN, fileName); + } + + public void generateCache(Map model, String fileName) { + generate(model, TEMPLATE_JAVA_CACHE, fileName); + } + + public void generateService(Map model, String fileName) { + generate(model, TEMPLATE_JAVA_SERVICE, fileName); + } + + public void generateJsEvent(Map model, String fileName) { + generate(model, TEMPLATE_JS_EVENT, fileName); + } + + + /** + * 获取单实例 + * + * @return + */ + public static CodeGenerator getInstance() { + if (instance == null) { + synchronized (CodeGenerator.class) { + instance = new CodeGenerator(); + } + } + return instance; + } + + static class PKGenerator implements TemplateMethodModelEx { + @Override + public Object exec(List list) throws TemplateModelException { + return String.valueOf(DbEngine.getInstance().nextId()); +// return DbEngine.getInstance().nextId(); + } + } + + + /* + {param:{pa:"aaa"}, + layout:{ + c1:[{type:"list", dataset:"ds123", fields:[{field:"", dataset:""}], cfilters:[{}]}] + } + */ + public static void main(String[] args) { + StringWriter out = new StringWriter(); + SwMap map = new SwMap(); + SwMap param = new SwMap(); + param.put("pa", "aaaaa"); + map.put("param", param); + + SwMap layout = new SwMap(); + map.put("layout", layout); + List groups = new ArrayList<>(); + layout.put("c1", groups); + + SwMap area = new SwMap(); + groups.add(area); + area.put("type", "list"); + area.put("dataset", "ds123"); + + List fields = new ArrayList<>(); + area.put("fields", fields); + SwMap field = new SwMap(); + field.put("field", "f123"); + field.put("dataset", "ds123"); + field.put("label", "字段123"); + fields.add(field); + + field = new SwMap(); + field.put("field", "f121"); + field.put("label", "字段121"); + field.put("dataset", "ds123"); + fields.add(field); + + field = new SwMap(); + field.put("field", "f122"); + field.put("label", "字段122"); + field.put("dataset", "ds123"); + fields.add(field); + + List filters = new ArrayList<>(); + area.put("cfilters", filters); + field = new SwMap(); + field.put("field", "f122"); + field.put("dataset", "ds123"); + field.put("label", "字段122"); + field.put("maxlength", 20); + filters.add(field); + + map.put("title", "thisIsATest!"); + map.put("newId", new PKGenerator()); + CodeGenerator.getInstance().generate(map, "model_card.ftl", out); + System.out.println(out.getBuffer().toString()); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java new file mode 100644 index 0000000..34e841b --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java @@ -0,0 +1,106 @@ +package cc.smtweb.system.bpm.util; + +import cc.smtweb.framework.core.util.DateUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.time.DateUtils; + +import java.io.File; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.Random; + +/** + * 动态文件〈文件路径〉 + * + * @author kevin + * @since 1.0.0 + */ +@Slf4j +public class FileDynPath extends FileFixPath { + // 目录允许的最大文件数量,避免批量导入文件时文件太多 + private static final int MAX_FILE_COUNT = 2000; + private static final int MAX_DIR_COUNT = 100000; + private long startTime; + private long endTime; + private final SimpleDateFormat sdf; + // 文件数量 + private int fileCount; + // 目录子索引 + private int pathIndex; + + public FileDynPath(String rootPath, String typeDir, SimpleDateFormat sdf) { + super(rootPath, typeDir); + this.sdf = sdf; + } + + /** + * 返回日期路径字符串 + */ + @Override + public FilePathInfo makeDatePath(long fileId, String fileExt) { + long now = System.currentTimeMillis(); + String fileName; + + // 如果不在就需要重新创建子目录 + if (now < startTime || now >= endTime) { + startTime = DateUtil.getTimesmorning(now); + endTime = startTime + DateUtils.MILLIS_PER_DAY; + + this.path = this.typeDir + "/" + sdf.format(new Timestamp(now)); + createFolder(rootPath + this.path); + } + + // 如果文件数量太大就需要创建新子目录 + while (this.fileCount >= MAX_FILE_COUNT) { + this.pathIndex++; + if(this.pathIndex > MAX_DIR_COUNT) { + throw new RuntimeException("dir is two many"); + } + + createFolder(rootPath + getSubPath()); + } + + Random random = new Random(); + int randomId = random.nextInt(Integer.MAX_VALUE); + + fileName = Long.toHexString(fileId) + "_" + Integer.toHexString(randomId) + fileExt; + + return new FilePathInfo(rootPath, getSubPath(), now, fileName, fileId); + } + + private String getSubPath() { + if (this.pathIndex > 0) { + return String.format("%s%02d/%04d", this.path, MAX_DIR_COUNT / 1000, this.pathIndex % 1000); + } + + return this.path; + } + + private boolean createFolder(String path) { + File file = new File(path); + if (file.exists()) { + if (!file.isDirectory()) { + return false; + } + + File[] list = file.listFiles(); + if (list != null) { + this.fileCount = list.length; + } else { + this.fileCount = 0; + } + + return true; + } + + if (!file.mkdirs()) { + log.error("unable to create folders {}.", rootPath + this.path); + return false; + } + + log.debug("create folders {}.", file); + this.fileCount = 0; + + return true; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileFixPath.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileFixPath.java new file mode 100644 index 0000000..5838559 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileFixPath.java @@ -0,0 +1,51 @@ +package cc.smtweb.system.bpm.util; + +import lombok.extern.slf4j.Slf4j; + +import java.io.File; + +/** + * 〈文件路径〉 + * + * @author kevin + * @since 1.0.0 + */ +@Slf4j +public class FileFixPath { + protected String path; + protected String rootPath; + protected String typeDir; + + public FileFixPath(String rootPath, String typeDir) { + this.rootPath = rootPath; + this.typeDir = typeDir; + } + + public FilePathInfo makeDatePath(long fileId, String fileName) { + long now = System.currentTimeMillis(); + this.path = this.typeDir + "/"; + createFolder(rootPath + this.path); + + return new FilePathInfo(rootPath, this.path, now, fileName, fileId); + } + + private boolean createFolder(String path) { + File file = new File(path); + if (file.exists()) { + if (!file.isDirectory()) { + return false; + } + + return true; + } + + if (!file.mkdirs()) { + log.error("unable to create folders {}.", rootPath + this.path); + return false; + } + + log.debug("create folders {}.", file); + + return true; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java new file mode 100644 index 0000000..4d307ba --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java @@ -0,0 +1,132 @@ +package cc.smtweb.system.bpm.util; + +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.tika.mime.MimeType; +import org.apache.tika.mime.MimeTypeException; +import org.apache.tika.mime.MimeTypes; +import org.springframework.web.multipart.MultipartFile; +import cc.smtweb.framework.core.db.jdbc.IdGenerator; + +/** + * 文件名生成规则 subDir/[yyyymm]/[d]/[hex(fileid)]_[hex(rand)].[fileExt] 如果文件是图片格式,会生成缩略图,文件名会直接添加.thumb.jpg后缀 规则参数 yyyymm: + * 时间的年月,固定6位字符。如200505 d: 时间的日期,值范围1~31。如5 fileid: 上传文件的ID,hex(int64) rand: 防盗链随机数,hex(int32)。 fileExt: 文件扩展名。 + */ +@Slf4j +public class FilePathGenerator { + + public static final String THUMB_FILE_EXT = ".thumb.jpg"; + // 文件时间是否作为PK + private SimpleDateFormat sdf; + @Getter + private String rootPath; + private Map fileFxPathMap = new HashMap<>(); + private Map fileDynPathMap = new HashMap<>(); + private String fileUrl; + private IdGenerator idGenerator; + + public FilePathGenerator(String rootPath, String fileUrl, IdGenerator idGenerator) { + this.fileUrl = fixEnd(fileUrl); + this.idGenerator = idGenerator; + this.rootPath = fixEnd(rootPath); + + sdf = new SimpleDateFormat("yyyyMM/dd/"); + } + + private static String fixEnd(String path) { + if (path.endsWith("/") || path.endsWith("\\")) { + return path; + } else { + return path + "/"; + } + } + + /** + * 生成文件路径,根据日期分目录存储 + * + * @param subPath 子目录,区分不同应用的文件 + * @param originalFileName 原始的文件名,用于提取扩展名用 + * @return 文件路径信息类 + */ + public FilePathInfo make(String subPath, String originalFileName) { + return make(subPath, originalFileName, null, false); + } + + public FilePathInfo make(String subPath, String originalFileName, boolean keepName) { + return make(subPath, originalFileName, null, keepName); + } + /** + * 生成文件路径,根据日期分目录存储 + * + * @param subPath 子目录,区分不同应用的文件 + * @param multipartFile 上传文件流,用于提取扩展名用 + * @return 文件路径信息类 + */ + public FilePathInfo make(String subPath, MultipartFile multipartFile) { + return make(subPath, multipartFile.getOriginalFilename(), multipartFile.getContentType(), false); + } + + private synchronized FilePathInfo make(String subPath, String originFileName, String contentType, boolean keepName) { + if (keepName) { + FileFixPath filePathSub = fileFxPathMap.get(subPath); + if (filePathSub == null) { + filePathSub = new FileFixPath(this.rootPath, subPath); + fileFxPathMap.put(subPath, filePathSub); + } + + return filePathSub.makeDatePath(this.idGenerator.nextId(), originFileName); + } else { + FileDynPath filePathSub = fileDynPathMap.get(subPath); + if (filePathSub == null) { + filePathSub = new FileDynPath(this.rootPath, subPath, sdf); + fileDynPathMap.put(subPath, filePathSub); + } + + return filePathSub.makeDatePath(this.idGenerator.nextId(), ext(originFileName, contentType)); + } + } + + private static String ext(String filename, String contentType) { + int index = filename.lastIndexOf("."); + + if (index == -1) { + if (contentType != null) { + MimeTypes allTypes = MimeTypes.getDefaultMimeTypes(); + try { + MimeType jpeg = allTypes.forName(contentType); + return jpeg.getExtension(); + } catch (MimeTypeException e) { + log.error(contentType, e); + } + } + + return ""; + } + + return filename.substring(index); + } + + // 根据数据库存储文件路径获取URL + public String getFileUrl(FilePathInfo filePathInfo) { + return this.fileUrl + filePathInfo.getMysqlFilePath(); + } + + // 根据数据库存储文件路径获取URL + public String getFileUrl(String mysqlFilePath) { + return this.fileUrl + mysqlFilePath; + } + + // 根据数据库存储文件路径获取磁盘存储路径 + public String getFileDiskPath(String mysqlFilePath) { + return this.rootPath + mysqlFilePath; + } + + // 获取下载路径前缀 + public String getDownloadUrl() { + return this.fileUrl; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java new file mode 100644 index 0000000..de9557e --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java @@ -0,0 +1,48 @@ +package cc.smtweb.system.bpm.util; + +import lombok.Getter; + + +/** + * 数据库需要存储 + * fileId, fileTime, subPath + fileName + */ +@Getter +public class FilePathInfo { + // 文件ID + private long fileId; + // 文件创建时间,数据库需要存储 + private long fileTime; + // 文件子路径 + private String subPath; + // 文件名 + private String fileName; + // 本地根路径 + private String rootPath; + + public FilePathInfo(String rootPath, String subPath, long fileTime, String fileName, long fileId) { + this.rootPath = rootPath; + this.subPath = subPath; + this.fileTime = fileTime; + this.fileName = fileName; + this.fileId = fileId; + } + + /** + * 获取本地需要存储的文件全路径 + */ + public String getFullFileName() { + return getDiskFilePath(); + } + + public String getDiskFilePath() { + return this.rootPath + subPath + fileName; + } + + /** + * 获取数据库存储需要的文件全路径 + */ + public String getMysqlFilePath() { + return subPath + fileName; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java new file mode 100644 index 0000000..ec08884 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java @@ -0,0 +1,45 @@ +package cc.smtweb.system.bpm.util; + +import java.util.List; + +/** + * 树型节点句柄 + * @author xkliu + */ +public interface ITreeDataHandler { + /** + * 获取ID + * @param node 节点 + * @return 节点ID + */ + Long getId(T node); + + /** + * 获取上级ID + * @param node 当前节点 + * @return 上级ID + */ + Long getParentId(T node); + +// void addChild(IWebTreeVO item); + + /** + * 获取下级对象列表 + * @param node 当前节点 + * @return 下级对象列表 + */ + List getChildren(T node); + + /** + * 设置下级对象列表 + * @param children 下级对象列表 + */ + void setChildren(T node, List children); + + /** + * 是否强行添加未找到上级的错误节点到顶级 + * @param node 通过node有parentId值,但未找到对应上级节点 + * @return 是否强行添加错误节点到顶级 + */ + default boolean forceAdd(T node) { return false; } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java new file mode 100644 index 0000000..2e43c00 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java @@ -0,0 +1,6 @@ +package cc.smtweb.system.bpm.util; + +public interface ITreeDataLevelHandler extends ITreeDataHandler { + int getLevel(T t); + void setLevel(T t, int level); +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java new file mode 100644 index 0000000..7ef1883 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java @@ -0,0 +1,73 @@ +package cc.smtweb.system.bpm.util; + + +import cc.smtweb.framework.core.common.SwMap; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; +import lombok.Data; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by Akmm at 14-2-14 上午10:13 + * 读取Idea信息的工具类 + */ +public class IdeaUtil { + //获取工程中的Module文件 + public static Map getModules(String ideaPath) { + Map map = new HashMap<>(); + IdeaProject project = XmlUtil.readValue(new File(ideaPath + "/.idea/modules.xml"), IdeaProject.class); + if (project == null || project.component == null || project.component.modules == null) return map; + for (Module module: project.component.modules) { + String s = module.filepath.replace("$PROJECT_DIR$", ideaPath); + File f = new File(s); + s = f.getName(); + int i = s.lastIndexOf("."); + if (i >= 0) s = s.substring(0, i); + map.put(s, f.getParent()); + } + return map; + } + + + public static void main(String args[]) throws Exception { + Map list = getModules("e:/jujia/git/6.0/smtweb2/smtweb-framework"); + for (Map.Entry s : list.entrySet()) { + System.out.println(s.getKey() + "=" + s.getValue()); + } + } + + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + @JacksonXmlRootElement(localName = "project") + public static class IdeaProject { + private Component component; + + } + + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + static class Component { + @JacksonXmlElementWrapper(localName = "modules") + @JacksonXmlProperty(localName = "module") + public List modules; + } + + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + static class Module { + @JacksonXmlProperty + private String fileurl; + @JacksonXmlProperty + private String filepath; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java new file mode 100644 index 0000000..33f5681 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java @@ -0,0 +1,79 @@ +package cc.smtweb.system.bpm.util; + +import org.apache.commons.codec.binary.Base64; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; + +public class MemMultipartFile implements MultipartFile { + private static final String DATA_IMAGE = "data:image/"; + private byte[] data; + private String contentType; + private String filename; + + public static MemMultipartFile build(String dataUrl) { + if (dataUrl != null && dataUrl.startsWith(DATA_IMAGE)) { + // data:image/png;base64, + int pos1 = dataUrl.indexOf(';', DATA_IMAGE.length()); + int pos2 = dataUrl.indexOf(',', DATA_IMAGE.length()); + if (pos1 > 0 && pos2 > pos1) { + byte[] data = Base64.decodeBase64(dataUrl.substring(pos2)); + + if (data != null) { + String contentType = dataUrl.substring(5, pos1); + return new MemMultipartFile(contentType.replace('/', '.'), contentType, data); + } + } + } + + return null; + } + + private MemMultipartFile(String filename, String contentType, byte[] data) { + this.data = data; + this.contentType = contentType; + this.filename = filename; + } + + @Override + public String getName() { + return "data"; + } + + @Override + public String getOriginalFilename() { + return filename; + } + + @Override + public String getContentType() { + return contentType; + } + + @Override + public boolean isEmpty() { + return data.length == 0; + } + + @Override + public long getSize() { + return data.length; + } + + @Override + public byte[] getBytes() throws IOException { + return data; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(data); + } + + @Override + public void transferTo(File file) throws IOException, IllegalStateException { + try(FileOutputStream os = new FileOutputStream(file)) { + os.write(data); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java new file mode 100644 index 0000000..e3b2d22 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java @@ -0,0 +1,109 @@ +package cc.smtweb.system.bpm.util; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.List; + +import javax.imageio.ImageIO; + +import lombok.Getter; +import net.coobird.thumbnailator.Thumbnails; +import net.coobird.thumbnailator.geometry.Positions; +import net.coobird.thumbnailator.resizers.configurations.Antialiasing; +import net.sf.image4j.codec.ico.ICODecoder; +import org.apache.commons.lang3.StringUtils; + +/** + * 缩略图生成工具 + * @author xkliu + */ +@Getter +public class ThumbImage { + // 图片处理方式 + public static final int TYPE_DEFAULT = 1; + public static final int TYPE_THUMB = 2; + public static final int TYPE_AVATAR = 3; + + private int imageWidth; + private int imageHeight; + + public static int type(String thumb) { + // 解决历史遗留boolean类型 + if (StringUtils.isBlank(thumb) || "false".equalsIgnoreCase(thumb)) { + return TYPE_DEFAULT; + } + + if ("true".equalsIgnoreCase(thumb)) { + return TYPE_THUMB; + } + + return Integer.parseInt(thumb); + } + + public void makeThumb(boolean isThumb, File file, int size) throws IOException { + makeThumb(file, size, size, isThumb); + } + // 后台等比压缩后大小最好控制在20k以内 + public void makeThumb(File file, int w, int h, boolean keepAspectRatio) throws IOException { + String fileName = file.getName().toLowerCase(); + + BufferedImage image; + + if (fileName.endsWith(".ico")) { + List images = ICODecoder.read(file); + image = images.get(images.size() - 1); + } else { + image = ImageIO.read(file); + } + + imageWidth = image.getWidth(); + imageHeight = image.getHeight(); + + if (fileName.endsWith(".png") || fileName.endsWith(".gif")) { + // 把透明的图填充白色背景 + BufferedImage newBufferedImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); + newBufferedImage.createGraphics().drawImage(image, 0, 0, Color.WHITE, null); + image = newBufferedImage; + } + + Thumbnails.Builder builder = Thumbnails.of(image); + + if (keepAspectRatio) { + if (h > 0) { + // 高度为基准调整宽度到达原图缩放比例 + int imageR = imageWidth * 1000 / imageHeight; + w = h * imageR / 1000; + } else { + // 宽度为基准调整宽度到达原图缩放比例 + int imageR = imageHeight * 1000 / imageWidth; + h = w * imageR / 1000; + } + +// int r = w * 1000 / h; +// int imageR = imageWidth * 1000 / imageHeight; +// if (r != imageR) { +// w = imageHeight * r / 1000; +// } + } else { + int r = w * 1000 / h; + int imageR = imageWidth * 1000 / imageHeight; + + if (r != imageR) { + int width = imageWidth; + int height = imageHeight; + if (r > imageR) { + width = imageHeight * r / 1000; + } else { + height = imageWidth * 1000 / r; + } + + builder.sourceRegion(Positions.CENTER, width, height); + } + } + + builder.size(w, h).antialiasing(Antialiasing.ON).outputFormat("jpg").outputQuality(0.9) + .toFile(file.getAbsolutePath() + FilePathGenerator.THUMB_FILE_EXT); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java new file mode 100644 index 0000000..7c1e490 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java @@ -0,0 +1,217 @@ +package cc.smtweb.system.bpm.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +/** + * 树结构数据创建器 + * @author xkliu + */ +public class TreeDataUtil { + private TreeDataUtil(){} + + public static boolean longEquals(Long l1, Long l2) { + if (l1 != null) { + return l1.equals(l2); + } + + return l2 == null; + } + + private static boolean findAndAdd(T parent, T item, ITreeDataHandler handler) { + if (longEquals(handler.getId(parent), handler.getParentId(item))) { + addChild(parent, item, handler); + return true; + } else { + List children = handler.getChildren(parent); + + if (children != null) { + for (T child : children) { + if (findAndAdd(child, item, handler)) { + return true; + } + } + } + } + + return false; + } + + private static boolean findAndAddLevel(T parent, T item, ITreeDataLevelHandler handler) { + if (longEquals(handler.getId(parent), handler.getParentId(item))) { + addChildLevel(parent, item, handler); + return true; + } else { + List children = handler.getChildren(parent); + + if (children != null) { + for (T child : children) { + if (findAndAddLevel(child, item, handler)) { + return true; + } + } + } + } + + return false; + } + + private static void addChild(T parent, T item, ITreeDataHandler handler) { + List children = handler.getChildren(parent); + if (children == null) { + children = new ArrayList<>(); + handler.setChildren(parent, children); + } + + children.add(item); + } + + private static void addChildLevel(T parent, T item, ITreeDataLevelHandler handler) { + List children = handler.getChildren(parent); + if (children == null) { + children = new ArrayList<>(); + handler.setChildren(parent, children); + } + + updateLevel(item, handler.getLevel(parent) + 1, handler); + children.add(item); + } + + private static void updateLevel(T parent, int parentLevel, ITreeDataLevelHandler handler) { + handler.setLevel(parent, parentLevel); + List children = handler.getChildren(parent); + if (children != null) { + int level = parentLevel + 1; + for (T t: children) { + handler.setLevel(t, level); + updateLevel(t, level, handler); + } + } + } + + // 读取树结构 + public static List buildTree(T root, List list, ITreeDataHandler handler) { + if (list != null) { + for (T item: list) { + if (!findAndAdd(root, item, handler)) { + for (T it: list) { + if (longEquals(handler.getId(it), handler.getParentId(item))) { + addChild(it, item, handler); + item = null; + break; + } + } + + // not find item parent + if (item != null && handler.forceAdd(item)) { + addChild(root, item, handler); + } + } + } + } + + return handler.getChildren(root); + } + + // 读取树结构 + public static List buildLevelTree(T root, List list, ITreeDataLevelHandler handler) { + if (list != null) { + handler.setLevel(root, 0); + for (T item: list) { + if (!findAndAddLevel(root, item, handler)) { + for (T it: list) { + if (longEquals(handler.getId(it), handler.getParentId(item))) { + addChildLevel(it, item, handler); + item = null; + break; + } + } + + // not find item parent + if (item != null && handler.forceAdd(item)) { + addChildLevel(root, item, handler); + } + } + } + } + + return handler.getChildren(root); + } + + public static T findParent(T root, Long id, int treeLevel, ITreeDataLevelHandler handler) { + T result = findParentInLevel(root, id, treeLevel, handler); + if (result != null && handler.getLevel(result) != treeLevel) { + result = null; + } + + return result; + } + + private static T findParentInLevel(T parent, Long id, int treeLevel, ITreeDataLevelHandler handler) { + List children = handler.getChildren(parent); + if (children != null) { + for (T child: children) { + if (id.equals(handler.getId(child))) { + return parent; + } else { + T find = findParentInLevel(child, id, treeLevel - 1, handler); + if (find != null) { + if (treeLevel > 0) { + return find; + } else { + return parent; + } + } + } + } + } + + return null; + } + + public static T findParent(T root, Long id,ITreeDataHandler handler) { + List children = handler.getChildren(root); + if (children != null) { + for (T child: children) { + if (id.equals(handler.getId(child))) { + return root; + } else { + T find = findParent(child, id, handler); + if (find != null) { + return find; + } + } + } + } + + return null; + } + + public static T find(T root, Long id, ITreeDataHandler handler) { + List children = handler.getChildren(root); + if (children != null) { + for (T child: children) { + if (id.equals(handler.getId(child))) { + return child; + } else { + T find = find(child, id, handler); + if (find != null) { + return find; + } + } + } + } + + return null; + } + + public static void forEach(T node, ITreeDataHandler handler, Consumer action) { + List children = handler.getChildren(node); + if (children != null) { + for (T child: children) { + action.accept(child); + } + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java new file mode 100644 index 0000000..3235db6 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java @@ -0,0 +1,88 @@ +package cc.smtweb.system.bpm.util; + +import cc.smtweb.framework.core.exception.JsonParseException; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class XmlUtil { + private static final XmlMapper OBJECT_MAPPER = new XmlMapper(); + + static { + OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + OBJECT_MAPPER.enable(SerializationFeature.INDENT_OUTPUT); + } + + private XmlUtil() {} + + public static T readValue(String str, Class clazz) { + try { + if (StringUtils.isBlank(str)) { + return null; + } else { + return OBJECT_MAPPER.readValue(str, clazz); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to " + clazz + " type", e); + } + } + + public static T readValue(File file, Class clazz) { + try { + if (file == null || !file.exists()) { + return null; + } else { + return OBJECT_MAPPER.readValue(file, clazz); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to " + clazz + " type", e); + } + } + + public static T readValue(InputStream is, Class clazz) { + try { + if (is == null) { + return null; + } else { + return OBJECT_MAPPER.readValue(is, clazz); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this xml to " + clazz + " type", e); + } + } + + public static String writeValue(Object obj) { + try { + return OBJECT_MAPPER.writeValueAsString(obj); + } catch (JsonProcessingException e) { + throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); + } + } + + public static void writeValue(OutputStream outputStream, Object obj) { + try { + OBJECT_MAPPER.writeValue(outputStream, obj); + } catch (JsonProcessingException e) { + throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); + } catch (IOException e) { + throw new JsonParseException(e.getMessage(), e); + } + } + + public static void writeValue(File file, Object obj) { + try { + OBJECT_MAPPER.writeValue(file, obj); + } catch (JsonProcessingException e) { + throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); + } catch (IOException e) { + throw new JsonParseException(e.getMessage(), e); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java new file mode 100644 index 0000000..24ebd47 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java @@ -0,0 +1,112 @@ +package cc.smtweb.system.bpm.util; + +import cc.smtweb.framework.core.exception.JsonParseException; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import org.apache.commons.lang3.StringUtils; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.introspector.Property; +import org.yaml.snakeyaml.nodes.NodeTuple; +import org.yaml.snakeyaml.nodes.Tag; +import org.yaml.snakeyaml.representer.Representer; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class YamlUtil { + private static final ObjectMapper OBJECT_MAPPER; + private static final Representer representer; + + static { + YAMLFactory yamlFactory = new YAMLFactory(); + +// yamlFactory.enable(YAMLGenerator.Feature.CANONICAL_OUTPUT); + yamlFactory.disable(YAMLGenerator.Feature.SPLIT_LINES); + yamlFactory.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES); + + OBJECT_MAPPER = new ObjectMapper(yamlFactory); + OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + // 生成yaml时忽略null属性 + representer = new Representer() { + @Override + protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) { + // if value of property is null, ignore it. + if (propertyValue == null) { + return null; + } + else { + return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); + } + } + }; + } + + private YamlUtil() {} + + public static T readValue(String str, Class clazz) { + try { + if (StringUtils.isBlank(str)) { + return null; + } else { + return OBJECT_MAPPER.readValue(str, clazz); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to " + clazz + " type", e); + } + } + + public static T readValue(File file, Class clazz) { + try { + return OBJECT_MAPPER.readValue(file, clazz); + } catch (Exception e) { + throw new JsonParseException("can't convert this json to " + clazz + " type", e); + } + } + + public static T readValue(InputStream is, Class clazz) { + try { + if (is == null) { + return null; + } else { + return OBJECT_MAPPER.readValue(is, clazz); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this yaml to " + clazz + " type", e); + } + } + + public static String writeValue(Object obj) { + Yaml yaml = buildYaml(); + StringWriter sw = new StringWriter(); + yaml.dump(obj, sw); + return sw.toString(); + } + + private static Yaml buildYaml() { + Yaml result = new Yaml(representer); + + return result; + } + + public static void writeValue(OutputStream outputStream, Object obj) { + Yaml yaml = buildYaml(); + yaml.dump(obj, new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)); + } + + public static void writeValue(File file, Object obj) { + Yaml yaml = buildYaml(); + try(OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) { + yaml.dump(obj, out); +// OBJECT_MAPPER.writeValue(file, obj); + } catch (IOException e) { + throw new JsonParseException(e.getMessage(), e); + } + + +// StringWriter sw = new StringWriter(); +// System.out.println(sw.toString()); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java new file mode 100644 index 0000000..100114a --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java @@ -0,0 +1,55 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.annotation.SwCache; +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.vo.ModelCatalog; + +import java.util.List; + +/** + * Created by Akmm at 2022/1/12 18:34 + */ +@SwCache(ident = "ASP_MODEL_CATALOG", title = "目录") +public class ModelCatalogCache extends AbstractCache { + public final static String CACHE_KEY = "prj"; + + public static ModelCatalogCache getInstance() { + return CacheManager.getIntance().getCache(ModelCatalogCache.class); + } + + public ModelCatalogCache() { + regList(SwConsts.KEY_PARENT_ID, k-> String.valueOf(k.getParentId())); + regList(CACHE_KEY, k-> k.getPrjId() + SwConsts.SPLIT_CHAR + k.getParentId()); + } + + @Override + protected String getId(ModelCatalog bean) { + return String.valueOf(bean.getId()); + } + + @Override + protected List loadAll() { + EntityDao dao = DbEngine.getInstance().findDao(ModelCatalog.class); + return dao.query(); + } + + public String getName(long id) { + ModelCatalog bean = get(id); + return bean != null ? bean.getName() : ""; + } + + public String getFullName(long id) { + ModelCatalog bean = get(id); + if (bean == null) return null; + StringBuilder sret = new StringBuilder(); + while (bean != null) { + sret.insert(0, "." + bean.getCode()); + bean = get(bean.getParentId()); + } + return sret.substring(1); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogService.java new file mode 100644 index 0000000..19cedf8 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogService.java @@ -0,0 +1,29 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.db.vo.ModelCatalog; +import cc.smtweb.framework.core.mvc.service.*; + +/** + * Created by Akmm at 2022/3/1 17:00 + * 项目服务类 + */ +@SwService +public class ModelCatalogService extends AbstractCompService { + @Override + protected AbstractHandler createHandler(String type) { + switch (type) { + case TYPE_LOAD: + return new DefaultLoadHandler(ModelCatalog.ENTITY_NAME); + case TYPE_SAVE: + return new DefaultSaveHandler<>(ModelCatalog.ENTITY_NAME); + case TYPE_DEL: + return new DefaultDelHandler<>(ModelCatalog.ENTITY_NAME); + case TYPE_LIST: + return new DefaultListHandler<>(ModelCatalog.ENTITY_NAME); + case TYPE_TREE: + return new ModelCatalogTreeHandler(); + } + return null; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java new file mode 100644 index 0000000..6ec3335 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java @@ -0,0 +1,200 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.vo.ModelCatalog; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.AbstractTreeHandler; +import cc.smtweb.framework.core.mvc.service.TreeHelper; +import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.framework.core.util.CommUtil; +import cc.smtweb.system.bpm.web.design.form.ModelForm; +import cc.smtweb.system.bpm.web.design.form.ModelFormCache; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by Akmm at 2022/3/21 18:22 + */ +public class ModelCatalogTreeHandler extends AbstractTreeHandler { + //查询类型:0-目录;1-表定义;2-页面;3-控件;23-页面和控件 + private final static int TYPE_CATALOG = 0; + private final static int TYPE_TABLE = 1; + private final static int TYPE_PAGE = 2; + private final static int TYPE_WIDGET = 3; + private final static int TYPE_FORM = 23; + + private long prj_id;//所属项目 + private int type;//查询类型:0-目录;1-表定义;2-页面定义 + private boolean exc_empty;//排除空目录,type非目录时有效 + + private ModelCatalogTreeHelper mcTreeHelper = null; + + @Override + public void init(SwMap params, UserSession us) { + super.init(params, us); + type = params.readInt("type"); + prj_id = params.readLong("prj_id"); + exc_empty = params.readBool("exc_empty"); + mcTreeHelper = (ModelCatalogTreeHelper) TreeHelper.getTreeHelper(ModelCatalog.ENTITY_NAME, ModelCatalogTreeHelper.class); + } + + @Override + protected List getChildren(DefaultEntity bean) { + if (bean instanceof ModelCatalog) { + return super.getChildren(bean); + } + return null; + } + + @Override + protected List filterData() { + + EntityDao dao = DbEngine.getInstance().findDao(ModelCatalog.ENTITY_NAME); + String text = "%" + params.readString("text") + "%"; + List list = dao.queryWhere(" mc_prj_id=? and (mc_name like ? or mc_code like ?) order by mc_name", prj_id, text, text); + List listRet = new ArrayList<>(list); + + switch (type) { + case TYPE_TABLE: + EntityDao tabledao = DbEngine.getInstance().findDao(ModelTable.class); + List l = tabledao.queryWhere(" tb_prj_id=? and (tb_name like ? or tb_title like ?) order by tb_name", prj_id, text, text); + listRet.addAll(l); + break; + case TYPE_PAGE: + case TYPE_WIDGET: + case TYPE_FORM: + EntityDao formdao = DbEngine.getInstance().findDao(ModelForm.class); + List lf; + if (type != TYPE_FORM) { + lf = formdao.queryWhere(" mf_prj_id=? and (mf_name like ? or mf_title like ?) order by tb_name", prj_id, text, text); + } else { + //数据库type 0-页面 1-控件 + lf = formdao.queryWhere(" mf_prj_id=? and mf_type=? and (mf_name like ? or mf_title like ?) order by tb_name", prj_id, type - 2, text, text); + } + listRet.addAll(lf); + } + return listRet; + } + + @Override + protected List getChildren(long id) { + List list = mcTreeHelper.getChildren(id, prj_id, (o1, o2) -> CommUtil.chineseCompare(o1.getName(), o2.getName())); + List listRet; + if (type != TYPE_CATALOG && exc_empty) {//排除空目录 + listRet = cleanEmpty(list); + } else { + listRet = new ArrayList<>(list); + } + + switch (type) { + case TYPE_TABLE: + addTableChildren(listRet, id); + break; + case TYPE_PAGE: + case TYPE_WIDGET: + case TYPE_FORM: + addPageChildren(listRet, id, type); + } + return listRet; + } + + /** + * 去掉没有叶子的空目录 + * @param list + * @return + */ + private List cleanEmpty(List list) { + if (list.isEmpty()) return new ArrayList<>(list); + List lret = new ArrayList<>(); + for (ModelCatalog mc: list) { + if (hasChildren(mc)) lret.add(mc); + } + return lret; + } + + //递归判断,目录是否有儿子 + private boolean hasChildren(ModelCatalog mc) { + List listRet = new ArrayList<>(); + switch (type) { + case TYPE_TABLE: + addTableChildren(listRet, mc.getId()); + break; + case TYPE_PAGE: + case TYPE_WIDGET: + case TYPE_FORM: + addPageChildren(listRet, mc.getId(), type); + } + if (!listRet.isEmpty()) return true; + List list = mcTreeHelper.getChildren(mc.getId(), prj_id, null); + if (list == null || list.isEmpty()) return false; + for (ModelCatalog c: list) { + if (hasChildren(c)) return true; + } + return false; + } + + //增加表 + private void addTableChildren(List listRet, long mcid) { + Collection set = ModelTableCache.getInstance().getTablesByMc(mcid, (o1, o2) -> CommUtil.chineseCompare(o1.getName(), o2.getName())); + if (set == null || set.isEmpty()) return; + + listRet.addAll(set); + } + + //增加页面定义 + private void addPageChildren(List listRet, long mcid, int type) { + List set = ModelFormCache.getInstance().getFormsByMc(mcid, (o1, o2) -> { + if (o1.getType() != o2.getType()) return o1.getType() - o2.getType(); + return CommUtil.chineseCompare(o1.getTitle(), o2.getTitle()); + }); + if (set == null || set.isEmpty()) return; + if (type != TYPE_FORM) { + int pt = type - 2; + for (ModelForm form: set) { + if (form.getType() == pt) { + listRet.add(form); + } + } + } else { + listRet.addAll(set); + } + } + + @Override + protected long getId(DefaultEntity bean) { + return bean.getEntityId(); + } + + @Override + protected String getText(DefaultEntity bean) { + if (bean instanceof ModelCatalog) { + return ((ModelCatalog) bean).getName(); + } + if (bean instanceof ModelTable) { + return ((ModelTable) bean).getTitle(); + } + + if (bean instanceof ModelForm) { + return ((ModelForm)bean).getTitle(); + } + return null; + } + + @Override + protected void buildNode(SwMap node, DefaultEntity bean) { + super.buildNode(node, bean); + if (bean instanceof ModelCatalog) { + node.put("type", TYPE_CATALOG); + } else if (bean instanceof ModelTable) { + node.put("type", TYPE_TABLE); + } else if (bean instanceof ModelForm) { + node.put("type", ((ModelForm)bean).getType() + 2); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java new file mode 100644 index 0000000..037a170 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java @@ -0,0 +1,34 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.db.vo.ModelCatalog; +import cc.smtweb.framework.core.mvc.service.TreeHelper; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +/** + * Created by Akmm at 2022/3/25 10:47 + */ +public class ModelCatalogTreeHelper extends TreeHelper { + //按项目的缓存key,确保此表缓存配置:prj:prjid_parentid + private final static String CACHE_KEY = "prj"; + + public ModelCatalogTreeHelper() { + super(ModelCatalog.ENTITY_NAME); + } + + public List getChildren(long id, long prj_id, Comparator comparator) { + if (id > 0) { + return getChildren(id, comparator); + } + Collection set = cache.getListByKey(CACHE_KEY, prj_id + SwConsts.SPLIT_CHAR + SwConsts.DEF_ROOT_ID); + + List list = set == null ? new ArrayList<>() : new ArrayList<>(set); + if (comparator != null) + list.sort(comparator); + return list; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseComboHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseComboHandler.java new file mode 100644 index 0000000..265eee2 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseComboHandler.java @@ -0,0 +1,25 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.db.vo.ModelDatabase; +import cc.smtweb.framework.core.mvc.service.DefaultComboHandler; + +import java.util.List; + +/** + * Created by Akmm at 2022/3/22 19:25 + */ +public class ModelDatabaseComboHandler extends DefaultComboHandler { + public ModelDatabaseComboHandler() { + super(ModelDatabase.ENTITY_NAME); + } + + @Override + protected void buildCondition(StringBuilder sql, List args) { + super.buildCondition(sql, args); + long prj_id = params.readLong("prj_id"); + if (prj_id > 0) { + sql.append(" and db_prj_id=?"); + args.add(prj_id); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseService.java new file mode 100644 index 0000000..c002425 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseService.java @@ -0,0 +1,30 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.db.vo.ModelCatalog; +import cc.smtweb.framework.core.db.vo.ModelDatabase; +import cc.smtweb.framework.core.mvc.service.*; + +/** + * Created by Akmm at 2022/3/22 9:12 + */ +@SwService +public class ModelDatabaseService extends AbstractCompService { + @Override + protected AbstractHandler createHandler(String type) { + switch (type) { + case TYPE_LOAD: + return new DefaultLoadHandler(ModelDatabase.ENTITY_NAME); + case TYPE_SAVE: + return new DefaultSaveHandler<>(ModelDatabase.ENTITY_NAME); + case TYPE_DEL: + return new DefaultDelHandler<>(ModelDatabase.ENTITY_NAME); + case TYPE_LIST: + return new DefaultListHandler<>(ModelDatabase.ENTITY_NAME); + case TYPE_COMBO: + return new ModelDatabaseComboHandler(); + + } + return null; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java new file mode 100644 index 0000000..0ba5e4a --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java @@ -0,0 +1,48 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.annotation.SwCache; +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.vo.ModelProject; + +import java.util.List; + +/** + * Created by Akmm at 2022/1/12 18:34 + */ +@SwCache(ident = "ASP_MODEL_PROJECT", title = "项目定义") +public class ModelProjectCache extends AbstractCache { + private final static String mm = "m"; + public static ModelProjectCache getInstance() { + return CacheManager.getIntance().getCache(ModelProjectCache.class); + } + + public ModelProjectCache() { + regMap(mm, k-> String.valueOf(k.getModule())); + } + + @Override + protected String getId(ModelProject bean) { + return String.valueOf(bean.getId()); + } + + @Override + protected List loadAll() { + EntityDao dao = DbEngine.getInstance().findDao(ModelProject.class); + return dao.query(); + } + + public String getModule(long id) { + ModelProject bean = get(id); + return bean != null ? bean.getModule() : ""; + } + public ModelProject getByModule(String module){ + return getByKey(mm,module); + } + public String getIdByModule(String module) { + ModelProject bean = getByModule(module); + return bean !=null ? String.valueOf(bean.getId()): ""; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectService.java new file mode 100644 index 0000000..396c2b1 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectService.java @@ -0,0 +1,31 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.db.vo.ModelProject; +import cc.smtweb.framework.core.mvc.service.*; + +/** + * Created by Akmm at 2022/3/1 17:00 + * 项目服务类 + */ +@SwService +public class ModelProjectService extends AbstractCompService { + @Override + protected AbstractHandler createHandler(String type) { + switch (type) { + case TYPE_LOAD: + return new DefaultLoadHandler(ModelProject.ENTITY_NAME); + case TYPE_SAVE: + return new DefaultSaveHandler<>(ModelProject.ENTITY_NAME); + case TYPE_DEL: + return new DefaultDelHandler<>(ModelProject.ENTITY_NAME); + case TYPE_LIST: + return new DefaultListHandler<>(ModelProject.ENTITY_NAME); + case TYPE_COMBO: + return new DefaultComboHandler<>(ModelProject.ENTITY_NAME); + } + return null; + } + + +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableComboHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableComboHandler.java new file mode 100644 index 0000000..b4b574f --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableComboHandler.java @@ -0,0 +1,31 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.DefaultComboHandler; + +import java.util.List; + +/** + * Created by Akmm at 2022/3/22 19:25 + */ +public class ModelTableComboHandler extends DefaultComboHandler { + public ModelTableComboHandler() { + super(ModelTable.ENTITY_NAME); + } + + @Override + protected void buildCondition(StringBuilder sql, List args) { + super.buildCondition(sql, args); + long prj_id = params.readLong("prj_id"); + if (prj_id > 0) { + sql.append(" and tb_prj_id=?"); + args.add(prj_id); + } + + long db_id = params.readLong("db_id"); + if (db_id > 0) { + sql.append(" and tb_db_id=?"); + args.add(db_id); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableSaveHanlder.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableSaveHanlder.java new file mode 100644 index 0000000..01ab1eb --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableSaveHanlder.java @@ -0,0 +1,20 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.DefaultSaveHandler; + +/** + * Created by Akmm at 2022/3/25 11:40 + */ +public class ModelTableSaveHanlder extends DefaultSaveHandler { + public ModelTableSaveHanlder() { + super(ModelTable.ENTITY_NAME); + } + + @Override + protected void readFromPage() { + super.readFromPage(); + bean.setContent(bean.getContent()); + bean.setName(bean.getName().toUpperCase()); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java new file mode 100644 index 0000000..4936a5f --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java @@ -0,0 +1,47 @@ +package cc.smtweb.system.bpm.web.design.db; + +import cc.smtweb.framework.core.annotation.SwBody; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.*; +import cc.smtweb.framework.core.session.UserSession; + +/** + * Created by Akmm at 2022/3/22 9:12 + */ +@SwService +public class ModelTableService extends AbstractCompService { + @Override + protected AbstractHandler createHandler(String type) { + switch (type) { + case TYPE_LOAD: + return new DefaultLoadHandler(ModelTable.ENTITY_NAME); + case TYPE_SAVE: + return new ModelTableSaveHanlder(); + case TYPE_DEL: + return new DefaultDelHandler(ModelTable.ENTITY_NAME); + case TYPE_LIST: + return new DefaultListHandler(ModelTable.ENTITY_NAME); + case TYPE_COMBO: + return new ModelTableComboHandler(); + + } + return null; + } + + //获取表的字段列表 + public R loadFields(@SwBody SwMap params, UserSession us) { + try { + final long tableId = params.readLong("tableId"); + ModelTable table = ModelTableCache.getInstance().get(tableId); + if (table == null) return R.error("没有找到对应的表定义信息【" + tableId + "】!"); + + return R.success(SwListData.create(table.getFields(), 0)); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java new file mode 100644 index 0000000..1cbe955 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java @@ -0,0 +1,93 @@ +package cc.smtweb.system.bpm.web.design.flow; + +import cc.smtweb.framework.core.common.IntEnum; + +/** + * Created by Akmm at 2022/5/24 9:04 + * 工作流常量及枚举定义 + */ +public interface FlowConst { + //流程按钮 + class Button { + public static final String DISUSE = "disuse";// 作废 + public static final String LOG = "log";// 流程历史 + public static final String WORD = "word";// 导出Word + public static final String EXCEL = "excel";// 导出Excel + public static final String HANDLER = "handler";// 办理,签收 + public static final String SUBMIT = "submit";// 提交 + public static final String RETAKE = "retake";// 取回 + public static final String REJECT = "reject";// 驳回 + public static final String ADD = "add";// 新增 + public static final String DEL = "del";// 删除 + public static final String SAVE = "save";// 保存 + } + /** + * 活动类型 1-开始任务 2-用户任务 3-条件分支 4-并行开始 5-并行结束 6-脚本任务 9-结束任务 + */ + class ActivityType extends IntEnum { + public static ActivityType instance = new ActivityType(); + public static IntEnumBean START = instance.addEnum(1, "开始任务"); + public static IntEnumBean USER = instance.addEnum(2, "用户任务"); + public static IntEnumBean CONDITION = instance.addEnum(3, "判断分支"); + public static IntEnumBean PARALLEL = instance.addEnum(4, "并行开始"); + public static IntEnumBean GATHER = instance.addEnum(5, "并行结束"); + public static IntEnumBean AUTO = instance.addEnum(6, "脚本任务"); + public static IntEnumBean END = instance.addEnum(9, "结束任务"); + } + + /** + * 流程活动状态 0-待办 1-办理中 2-已提交 3-已驳回 + */ + class ActivityStatu extends IntEnum { + public static ActivityStatu instance = new ActivityStatu(); + public static IntEnumBean WAIT = instance.addEnum(0, "待办"); + public static IntEnumBean HANDLE = instance.addEnum(1, "办理中"); + public static IntEnumBean SUBMIT = instance.addEnum(2, "已提交"); + public static IntEnumBean DISUSE = instance.addEnum(8, "已作废"); + public static IntEnumBean REJECT = instance.addEnum(9, "已驳回"); + } + + /** + * 流程实例状态 + */ + class InstanceStatu extends IntEnum { + public static ActivityStatu instance = new ActivityStatu(); + public static IntEnumBean BEGIN = instance.addEnum(1, "制单"); + public static IntEnumBean RUNING = instance.addEnum(2, "审批中"); + public static IntEnumBean FINISH = instance.addEnum(99, "生效"); + public static IntEnumBean ABORTED = instance.addEnum(98, "中止"); + public static IntEnumBean DISUSE = instance.addEnum(89, "作废"); + } + + /** + * 流程任务创建方式 + */ + class TaskCreateType extends IntEnum { + public static TaskCreateType instance = new TaskCreateType(); + public static IntEnumBean AUTO = instance.addEnum(1, "自动"); + public static IntEnumBean RETAKE = instance.addEnum(2, "取回"); + public static IntEnumBean REJECT = instance.addEnum(3, "驳回"); + } + + /** + * 候选人过滤类别 主办人过滤:制单人所属单位/制单人所属部门/上一步提交人所属单位/上一步提交人所属部门 + */ + class CndFilterType extends IntEnum { + public static CndFilterType instance = new CndFilterType(); + public static IntEnumBean BILL_CORP = instance.addEnum(1, "单据所属单位"); + public static IntEnumBean BILL_DEPT = instance.addEnum(2, "单据所属部门"); + public static IntEnumBean MAKE_CORP = instance.addEnum(3, "制单人所属单位"); + public static IntEnumBean MAKE_DEPT = instance.addEnum(4, "制单人所属部门"); + public static IntEnumBean SUBMITTER_CORP = instance.addEnum(5, "上一步提交人所属单位"); + public static IntEnumBean SUBMITTER_DEPT = instance.addEnum(6, "上一步提交人所属部门"); + } + + /** + * 主办人忽略类型:位运算,上一步提交人/过滤制单人 + */ + class CndIgnoreType extends IntEnum { + public static CndIgnoreType instance = new CndIgnoreType(); + public static IntEnumBean MAKER = instance.addEnum(1, "制单人"); + public static IntEnumBean SUBMITTER = instance.addEnum(2, "上一步提交人"); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java new file mode 100644 index 0000000..e6c1957 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java @@ -0,0 +1,90 @@ +package cc.smtweb.system.bpm.web.design.flow; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.util.JsonUtil; +import cc.smtweb.system.bpm.web.design.flow.define.ProcInfo; +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Created by Akmm at 2022/5/21 10:40 + * 流程定义 + */ +@SwTable("ASP_MODEL_PROC") +public class ModelProc extends DefaultEntity { + public static final String ENTITY_NAME = "ASP_MODEL_PROC"; + //流程定义详情 + @JsonIgnore + private transient ProcInfo procInfo = null; + + public ModelProc() { + super(ENTITY_NAME); + } + + public ProcInfo getProcInfo() { + if (procInfo == null) { + synchronized ("ModelProc_" + getId()) { + if (procInfo == null) { + procInfo = JsonUtil.parse(getContent(), ProcInfo.class); + } + } + } + return procInfo; + } + + public long getId() { + return getLong("prc_id"); + } + + public void setId(long prcId) { + put("prc_id", prcId); + } + + public long getPrjId() { + return getLong("prc_prj_id"); + } + + public void setPrjId(long prcPrjId) { + put("prc_prj_id", prcPrjId); + } + + public long getMcId() { + return getLong("prc_mc_id"); + } + + public void setMcId(long prcMcId) { + put("prc_mc_id", prcMcId); + } + + public String getCode() { + return getStr("prc_code"); + } + + public void setCode(String prcCode) { + put("prc_code", prcCode); + } + + public String getName() { + return getStr("prc_name"); + } + + public void setName(String prcName) { + put("prc_name", prcName); + } + + public String getContent() { + return getStr("prc_content"); + } + + public void setContent(String prcContent) { + put("prc_content", prcContent); + } + + public String getRemark() { + return getStr("prc_remark"); + } + + public void setRemark(String prcRemark) { + put("prc_remark", prcRemark); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java new file mode 100644 index 0000000..3cfd542 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java @@ -0,0 +1,59 @@ +package cc.smtweb.system.bpm.web.design.flow; + +import cc.smtweb.framework.core.annotation.SwCache; +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +/** + * Created by Akmm at 2022/1/12 18:34 + */ +@SwCache(ident = "ASP_MODEL_PROC", title = "流程定义") +public class ModelProcCache extends AbstractCache { + private final static String mk = "k"; + private final static String mp = "prj"; + private final static String mc = "c"; + + public static ModelProcCache getInstance() { + return CacheManager.getIntance().getCache(ModelProcCache.class); + } + + public ModelProcCache() { + regMap(mk, k-> k.getName().toUpperCase()); + regList(mp, k-> String.valueOf(k.getPrjId())); + regList(mc, k-> String.valueOf(k.getMcId())); + } + + @Override + protected String getId(ModelProc bean) { + return String.valueOf(bean.getId()); + } + + @Override + protected List loadAll() { + EntityDao dao = DbEngine.getInstance().findDao(ModelProc.class); + return dao.query(); + } + + public final ModelProc getByName(String key) { + return getByKey(mk, key.toUpperCase()); + } + + public final Set getFormsByMc(long mcId) { + return getListByKey(mc, String.valueOf(mcId)); + } + + public final List getFormsByMc(long mcId, Comparator comparator) { + Set set = getListByKey(mc, String.valueOf(mcId)); + if (set == null || set.isEmpty()) return null; + List list = new ArrayList<>(set); + list.sort(comparator); + return list; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java new file mode 100644 index 0000000..d44fad1 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java @@ -0,0 +1,102 @@ +package cc.smtweb.system.bpm.web.design.flow; + +import cc.smtweb.framework.core.annotation.SwBody; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.mvc.service.AbstractCompService; +import cc.smtweb.framework.core.mvc.service.AbstractHandler; +import cc.smtweb.framework.core.mvc.service.DefaultDelHandler; +import cc.smtweb.framework.core.mvc.service.DefaultListHandler; +import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.framework.core.util.SqlUtil; +import cc.smtweb.system.bpm.web.design.form.ModelForm; +import cc.smtweb.system.bpm.web.design.form.ModelFormLoadHandler; +import cc.smtweb.system.bpm.web.design.form.ModelFormSaveHandler; +import org.apache.commons.lang3.StringUtils; + +import java.sql.ResultSetMetaData; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Akmm at 2022/3/22 9:12 + */ +@SwService +public class ModelProcService extends AbstractCompService { + @Override + protected AbstractHandler createHandler(String type) { + switch (type) { + case TYPE_LOAD: + return new ModelFormLoadHandler(); + case TYPE_SAVE: + return new ModelFormSaveHandler(); + case TYPE_DEL: + return new DefaultDelHandler(ModelForm.ENTITY_NAME); + case TYPE_LIST: + return new DefaultListHandler(ModelForm.ENTITY_NAME); + + } + return null; + } + + //保存数据集 + public R saveDataset(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelFormSaveHandler)handler).saveDataset()); + } + + //加载数据集 + public R loadDataset(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadDataset()); + } + + //保存页面模型 + public R saveModel(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelFormSaveHandler)handler).saveModel()); + } + + //加载页面模型 + public R loadModel(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadModel()); + } + + //加载引擎用页面模型 + public R model(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadForm()); + } + + //获取页面使用的控件的filter信息 + public R loadWidgetFilter(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadWidgetFilter()); + } + + //获取自定义sql的字段信息,去库里查 + public R loadSqlFields(@SwBody SwMap params, UserSession us) { + try { + String sql = params.readString("sql"); + if (StringUtils.isEmpty(sql)) return R.error("没有传入的sql!"); + sql = sql.trim().toLowerCase(); + if (!sql.startsWith("select ")) return R.error("非查询类sql,禁止执行!"); + if (sql.contains(";")) return R.error("sql内禁止出现分号!"); + sql = SqlUtil.replaceTable(sql); + List ret = DbEngine.getInstance().query(sql + " where 1=0", rs -> { + List fields = new ArrayList<>(); + ResultSetMetaData metaData = rs.getMetaData(); + + for (int i = 1, count = metaData.getColumnCount(); i <= count; i++) { + SwMap col = new SwMap(2); + col.put("name", metaData.getColumnLabel(i)); + SwEnum.DataTypeBean dtb = SwEnum.DataType.getBySqlType(metaData.getColumnType(i), metaData.getPrecision(i), metaData.getScale(i)); + col.put("dataType", dtb.value); + fields.add(col); + } + return fields; + }); + return R.success(ret); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ActivityInfo.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ActivityInfo.java new file mode 100644 index 0000000..91172f8 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ActivityInfo.java @@ -0,0 +1,35 @@ +package cc.smtweb.system.bpm.web.design.flow.define; + +import lombok.Data; + +import java.util.List; + +/** + * Created by Akmm at 2022/5/21 10:48 + * 步骤定义 + */ +@Data +public class ActivityInfo { + //"id": "", + private String id; + //类别:1-开始任务 2-用户任务 3-条件分支 4-并行开始 5-并行结束 6-脚本任务 9-结束任务 + private int type; + //活动编号,代码可调用 + private String code; + //活动名称 + private String label; + //表单定义 + private String page; + //是否可编辑 + private boolean canEdit; + //是否需要会签 + private boolean needSign; + //可编辑的字段 + private List eidtFields; + //不可查看的字段 + private List disableFields; + //主办人相关信息 + private HandlerInfo handler; + //会签相关信息 + private SignInfo sign; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/HandlerInfo.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/HandlerInfo.java new file mode 100644 index 0000000..1475f1c --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/HandlerInfo.java @@ -0,0 +1,19 @@ +package cc.smtweb.system.bpm.web.design.flow.define; + +import lombok.Data; + +import java.util.List; + +/** + * Created by Akmm at 2022/5/23 9:45 + * 主办人设置信息 + */ +@Data +public class HandlerInfo { + //主办人分组 + private List userGroup; + //主办人过滤:制单人所属单位/制单人所属部门/上一步提交人所属单位/上一步提交人所属部门 + private int filter; + //主办人过滤:上一步提交人/过滤制单人 + private int ignore; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java new file mode 100644 index 0000000..1f1fd8f --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java @@ -0,0 +1,23 @@ +package cc.smtweb.system.bpm.web.design.flow.define; + +import lombok.Data; + +import java.util.List; + +/** + * Created by Akmm at 2022/5/21 10:48 + * 流程定义信息 + */ +@Data +public class ProcInfo { + //默认表单定义 + private String page; + //是否允许编辑非本人单据 + private boolean canEditOther; + //1-驳回到制单 0-逐级驳回 + private boolean rejectToMake; + //活动节点 + private List activities; + //连接线 + private List trans; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/SignInfo.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/SignInfo.java new file mode 100644 index 0000000..ab1b148 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/SignInfo.java @@ -0,0 +1,17 @@ +package cc.smtweb.system.bpm.web.design.flow.define; + +import lombok.Data; + +/** + * Created by Akmm at 2022/5/23 9:54 + * 会签信息 + */ +@Data +public class SignInfo extends HandlerInfo{ + //最少会签人数 + private int minSign; + //最少会签同意人数 + private int minAgree; + //最少会签同意人数单位:0-人数 1-会签同意占比 + private int minAgreeUnit; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/TransInfo.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/TransInfo.java new file mode 100644 index 0000000..246792e --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/TransInfo.java @@ -0,0 +1,23 @@ +package cc.smtweb.system.bpm.web.design.flow.define; + +import lombok.Data; + +/** + * Created by Akmm at 2022/5/21 11:38 + * 连接线 + */ +@Data +public class TransInfo { + //唯一标识 + private String id; + //序号 + private int seq; + //条件表达式 + private String expr; + //源活动 + private String src; + //目标活动 + private String dst; + //说明 + private String desc; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java new file mode 100644 index 0000000..e7bcbd8 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java @@ -0,0 +1,183 @@ +package cc.smtweb.system.bpm.web.design.form; + +import cc.smtweb.framework.core.common.*; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelCache; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.mvc.service.AbstractHandler; +import cc.smtweb.framework.core.util.DateUtil; +import cc.smtweb.framework.core.util.MapUtil; +import cc.smtweb.framework.core.util.SpringUtil; +import cc.smtweb.system.bpm.spring.BpmConfigBean; +import cc.smtweb.system.bpm.util.CodeGenUtil; +import cc.smtweb.system.bpm.util.CodeGenerator; +import cc.smtweb.system.bpm.util.IdeaUtil; +import cc.smtweb.system.bpm.web.design.db.ModelCatalogCache; +import cc.smtweb.system.bpm.web.design.db.ModelProjectCache; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by Akmm at 2022/6/14 20:11 + * 生成代码 + */ +public class CodeBuildHandler extends AbstractHandler { + private static final String SRC_MAIN_JAVA = "/src/main/java/"; + private static final String SRC_MAIN_RES = "/src/main/resources"; + + private String userName; + //java文件所在路径 + private String codeJavaPath; + private String packageName; + private BpmConfigBean bpmConfigBean; + + public R buildJavaCode() { + userName = String.valueOf(us.getUserId()); + + //页面id + long pageId = params.readLong("pageId"); + + //是否需要创建服务 + boolean needBuildService = params.readBool("service"); + //实体相关 + List> tables = params.readListMap("table"); + + buildCodeJavaPath(pageId); + for (Map map : tables) { + long tableId = MapUtil.readLong(map, "tableId"); + buildJavaTable(tableId, MapUtil.readBool(map, "bean"), MapUtil.readBool(map, "cache")); + } + if (needBuildService) buildJavaService(pageId); + return R.success(); + } + + public R buildJsCode() { + userName = String.valueOf(us.getUserId()); + //页面id + long pageId = params.readLong("pageId"); + ModelForm form = ModelFormCache.getInstance().get(pageId); + if (form == null) throw new BizException("未找到指定的页面定义(" + pageId + ")!"); + String moduleName = ModelProjectCache.getInstance().getModule(form.getPrjId()); + if (StringUtils.isEmpty(moduleName)) throw new BizException("此项目未定义Module!"); + + codeJavaPath = ModelFormHelper.getEventPath(form); + new File(codeJavaPath).mkdirs(); + + SwMap model = new SwMap(); + model.put("user", userName); + model.put("sysTime", DateUtil.nowDateTime()); + model.put("title", form.getTitle()); + model.put("eventPath", ModelFormHelper.getEventPath(form)); + CodeGenerator.getInstance().generateJsEvent(model, codeJavaPath + "/" + form.getName() + ".js"); + return R.success(); + } + + /** + * 构建java代码路径 + * + * @param pageId 页面id + */ + private void buildCodeJavaPath(long pageId) { + ModelForm form = ModelFormCache.getInstance().get(pageId); + if (form == null) throw new BizException("未找到指定的页面定义(" + pageId + ")!"); + String moduleName = ModelProjectCache.getInstance().getModule(form.getPrjId()); + if (StringUtils.isEmpty(moduleName)) throw new BizException("此项目未定义Module!"); + + if (moduleName.equals("bpm")) { + packageName = "cc.smtweb.system.bpm.web"; + } else { + packageName = "cc.smtweb.biz." + moduleName + ".web"; + } + BpmConfigBean bpmConfigBean = SpringUtil.getBean(BpmConfigBean.class); + Map mapIdeaModules = IdeaUtil.getModules(bpmConfigBean.getCodeJavaPath()); + if (mapIdeaModules == null || mapIdeaModules.isEmpty()) throw new BizException("没有定义idea项目的路径(smtweb.bpm.codeJavaPath)!"); + codeJavaPath = mapIdeaModules.get(moduleName); + if (StringUtils.isEmpty(codeJavaPath)) { + throw new BizException("没有找到对应项目在idea中Module的路径(" + moduleName + ")!"); + } + codeJavaPath += "/src/main/java/"; + //加上目录 + String cn = ModelCatalogCache.getInstance().getFullName(form.getMcId()); + if (StringUtils.isNotEmpty(cn)) { + packageName += "." + cn; + } + codeJavaPath += packageName.replaceAll("\\.", "/"); + new File(codeJavaPath).mkdirs(); + } + + /** + * 生成bean + * + * @param tableId + */ + private void buildJavaTable(long tableId, boolean needBean, boolean needCache) { + ModelTable table = ModelTableCache.getInstance().get(tableId); + if (table == null) throw new BizException("没有找到对应的表定义(" + tableId + ")!"); + SwMap model = new SwMap(); + model.put("user", userName); + model.put("sysTime", DateUtil.nowDateTime()); + model.put("packageName", packageName); + model.put("tableName", table.getName()); + model.put("tableTitle", table.getTitle()); + + final String beanName = CodeGenUtil.getBeanName(table.getName()); + model.put("beanName", beanName); + if (needBean) { + List fields = new ArrayList<>(); + model.put("fields", fields); + for (ModelField field : table.getFields()) { + SwMap fn = new SwMap(); + fields.add(fn); + fn.put("name", field.getName()); + fn.put("title", field.getTitle()); + fn.put("javaName", CodeGenUtil.getBeanName(field.getName())); + SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(field.getDataType()); + fn.put("javaType", dtb.javaType); + fn.put("shortJavaType", dtb.shortJavaType); + } + + CodeGenerator.getInstance().generateBean(model, codeJavaPath + "/" + beanName + ".java"); + } + + if (needCache) { + if (!table.isNeedCache()) throw new BizException("表设置为不需要缓存!" + table.getTitle()); + List caches = new ArrayList<>(); + model.put("caches", caches); + for (ModelCache cache : table.getCaches()) { + SwMap fn = new SwMap(); + caches.add(fn); + final String name = cache.getName(); + fn.put("name", name); + fn.put("nameUF", CodeGenUtil.toUpperHump(name)); + fn.put("title", cache.getTitle()); + fn.put("fields", cache.getFields()); + } + + CodeGenerator.getInstance().generateCache(model, codeJavaPath + "/" + beanName + "Cache.java"); + } + } + + private void buildJavaService(long pageId) { + ModelForm form = ModelFormCache.getInstance().get(pageId); + String sName = form.getService(); + if (StringUtils.isEmpty(sName)) throw new BizException("页面设置未定义服务名!" + form.getTitle()); + sName = CodeGenUtil.toUpperHump(sName); + + SwMap model = new SwMap(); + model.put("user", userName); + model.put("sysTime", DateUtil.nowDateTime()); + model.put("packageName", packageName); + model.put("formTitle", form.getTitle()); + model.put("service", sName); + model.put("eventPath", ModelFormHelper.getEventPath(form)); + + CodeGenerator.getInstance().generateService(model, codeJavaPath + "/" + sName + "Service.java"); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java new file mode 100644 index 0000000..8c6f51d --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java @@ -0,0 +1,210 @@ +package cc.smtweb.system.bpm.web.design.form; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.system.bpm.web.design.form.define.PageDatasets; +import cc.smtweb.system.bpm.web.design.form.define.PageModel; + +/** + * Created by Akmm at 2022/4/15 17:26 + */ +@SwTable("ASP_MODEL_FORM") +public class ModelForm extends DefaultEntity { + public static final String ENTITY_NAME = "ASP_MODEL_FORM"; + //将相关信息缓存起来 + private transient long masterTableId = -1; + private transient PageDatasets datasets; + private transient SwMap opts; + + public void clearEx() { + masterTableId = -1L; + datasets = null; + opts = null; + } + + public long getMasterTableId() { + if (masterTableId < 0) { + synchronized (ModelForm.class) { + if (masterTableId < 0) { + datasets = ModelFormHelper.parsePageDataset(getDataset()); + if (datasets == null) { + masterTableId = 0; + } else { + masterTableId = datasets.findMasterTableId(); + } + } + } + } + return masterTableId; + } + + public void setMasterTableId(long masterTableId) { + this.masterTableId = masterTableId; + } + + public PageDatasets getDatasets() { + if (datasets == null) { + synchronized (ModelForm.class) { + if (datasets == null) { + datasets = ModelFormHelper.parsePageDataset(getDataset()); + } + } + } + return datasets; + } + + public void setDatasets(PageDatasets datasets) { + this.datasets = datasets; + } + + public SwMap getOpts() { + if (opts == null) { + synchronized (ModelForm.class) { + if (opts == null) { + opts = ModelFormHelper.parseFormOption(getOption()); + } + } + } + return opts; + } + + public void setOpts(SwMap opts) { + this.opts = opts; + } + + public ModelForm() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("mf_id"); + } + + public void setId(long mfId) { + put("mf_id", mfId); + } + + public long getPrjId() { + return getLong("mf_prj_id"); + } + + public void setPrjId(long mfPrjId) { + put("mf_prj_id", mfPrjId); + } + + public long getMcId() { + return getLong("mf_mc_id"); + } + + public void setMcId(long mfMcId) { + put("mf_mc_id", mfMcId); + } + + public String getName() { + return getStr("mf_name"); + } + + public void setName(String mfName) { + put("mf_name", mfName); + } + + public String getTitle() { + return getStr("mf_title"); + } + + public void setTitle(String mfTitle) { + put("mf_title", mfTitle); + } + + public int getType() { + return getInt("mf_type"); + } + + public void setType(int mfType) { + put("mf_type", mfType); + } + + public String getService() { + return getStr("mf_service"); + } + + public void setService(String mfService) { + put("mf_service", mfService); + } + + public String getContent() { + return getStr("mf_content"); + } + + public void setContent(String mfContent) { + put("mf_content", mfContent); + } + + public String getOption() { + return getStr("mf_option"); + } + + public void setOption(String mf_option) { + put("mf_option", mf_option); + opts = null; + } + + public String getTmpl() { + return getStr("mf_tmpl"); + } + + public void setTmpl(String mf_tmpl) { + put("mf_tmpl", mf_tmpl); + } + + public String getDataset() { + return getStr("mf_dataset"); + } + + public void setDataset(String mf_dataset) { + put("mf_dataset", mf_dataset); + datasets = null; + masterTableId = 0L; + } + + public long getCreateUid() { + return getLong("mf_create_uid"); + } + + public void setCreateUid(long mfCreateUid) { + put("mf_create_uid", mfCreateUid); + } + + public long getUpdateUid() { + return getLong("mf_update_uid"); + } + + public void setUpdateUid(long mfUpdateUid) { + put("mf_update_uid", mfUpdateUid); + } + + public long getCreateAt() { + return getLong("mf_create_at"); + } + + public void setCreateAt(long mfCreateAt) { + put("mf_create_at", mfCreateAt); + } + + public long getUpdateAt() { + return getLong("mf_update_at"); + } + + public void setUpdateAt(long mfUpdateAt) { + put("mf_update_at", mfUpdateAt); + } + + public String getRemark() { + return getStr("mf_remark"); + } + + public void setRemark(String mfRemark) { + put("mf_remark", mfRemark); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java new file mode 100644 index 0000000..77c01fd --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java @@ -0,0 +1,86 @@ +package cc.smtweb.system.bpm.web.design.form; + +import cc.smtweb.framework.core.annotation.SwCache; +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.AbstractEntityCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +/** + * Created by Akmm at 2022/1/12 18:34 + */ +@SwCache(ident = "ASP_MODEL_FORM", title = "页面定义") +public class ModelFormCache extends AbstractEntityCache { + private final static String mk = "k"; + private final static String mp = "prj"; + private final static String mc = "c"; + private final static String mt = "t"; + + public static ModelFormCache getInstance() { + return CacheManager.getIntance().getCache(ModelFormCache.class); + } + + public ModelFormCache() { + regMap(mk, k-> k.getName().toUpperCase()); + regList(mp, k-> String.valueOf(k.getPrjId())); + regList(mc, k-> String.valueOf(k.getMcId())); + regList(mt, k-> k.getMasterTableId() + SwConsts.SPLIT_CHAR + k.getType()); +// regList(mf, k-> k.get); + } + + @Override + protected String getId(ModelForm bean) { + return String.valueOf(bean.getId()); + } + + @Override + protected List loadAll() { + EntityDao dao = DbEngine.getInstance().findDao(ModelForm.class); + return dao.query(); + } + + public final ModelForm getByName(String key) { + return getByKey(mk, key.toUpperCase()); + } + + public final Set getFormsByMc(long mcId) { + return getListByKey(mc, String.valueOf(mcId)); + } + + public final List getFormsByMc(long mcId, Comparator comparator) { + Set set = getListByKey(mc, String.valueOf(mcId)); + if (set == null || set.isEmpty()) return null; + List list = new ArrayList<>(set); + list.sort(comparator); + return list; + } + + public final Set getFormsByPrj(long mcId) { + return getListByKey(mp, String.valueOf(mcId)); + } + + public final List getFormsByPrj(long mcId, Comparator comparator) { + Set set = getListByKey(mp, String.valueOf(mcId)); + if (set == null || set.isEmpty()) return null; + List list = new ArrayList<>(set); + list.sort(comparator); + return list; + } + + //根据表id,找对应的页面设计 + public Set getListByTable(long tableId, int type) { + return getListByKey(mt, tableId + SwConsts.SPLIT_CHAR + type); + } + + public String getText(long id) { + ModelForm form = get(id); + return form != null ? form.getTitle() : String.valueOf(id); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java new file mode 100644 index 0000000..3ca35a9 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java @@ -0,0 +1,499 @@ +package cc.smtweb.system.bpm.web.design.form; + +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.variable.SwVariableFactory; +import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.framework.core.util.CommUtil; +import cc.smtweb.framework.core.util.JsonUtil; +import cc.smtweb.framework.core.util.MapUtil; +import cc.smtweb.framework.core.util.SpringUtil; +import cc.smtweb.system.bpm.spring.BpmConfigBean; +import cc.smtweb.system.bpm.util.CodeGenerator; +import cc.smtweb.system.bpm.util.IdeaUtil; +import cc.smtweb.system.bpm.web.design.db.ModelCatalogCache; +import cc.smtweb.system.bpm.web.design.db.ModelProjectCache; +import cc.smtweb.system.bpm.web.design.form.define.*; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; + +/** + * Created by Akmm at 2022/4/20 18:45 + * 辅助类 + */ +public class ModelFormHelper { + public static final String KEY_EVENT_PATH = "eventPath"; + //分组类别-list + public static final String PAGE_TYPE_LIST = "list"; + //分组类别-card + public static final String PAGE_TYPE_CARD = "card"; + //分组类别-view + public static final String PAGE_TYPE_VIEW = "view"; + + /** + * 从缓存获取Form对象 + * + * @param formId + * @return + */ + public static ModelForm getFromCache(long formId) { + AbstractCache cache = ModelFormCache.getInstance(); + if (cache == null) return null; + return cache.get(formId); + } + + /*public static PageDatasets parsePageDataset(long formId) { + ModelForm form = getFromCache(formId); + if (form == null) return null; + return parsePageDataset(form.getDataset()); + }*/ + + public static PageDatasets parsePageDataset(String jsonStr) { + if (StringUtils.isEmpty(jsonStr)) return null; + PageDataset[] list = JsonUtil.parse(jsonStr, PageDataset[].class); + return new PageDatasets(list); + } + + /** + * 根据json字符串解析对象 + * + * @param jsonStr + * @return + */ + public static PageModel parsePageInfo(String jsonStr) { + if (StringUtils.isEmpty(jsonStr)) return null; + return JsonUtil.parse(jsonStr, PageModel.class); + } + + public static SwMap parseFormOption(String jsonStr) { + if (StringUtils.isEmpty(jsonStr)) return null; + return JsonUtil.parse(jsonStr, SwMap.class); + } + + /** + * 页面传回的content,加工处理成待保存的json串 + * 主要处理内容: + * 1、model的一些maxlen、默认值等信息,如果和数据库一致,则去掉 + * 2、db中的只保留表、字段和别名 + * + * @param form + * @return + */ + public static String buildSaveModel(ModelForm form, String jsonStr) { + PageDatasets datasets = form.getDatasets(); + PageModel pageInfo = parsePageInfo(jsonStr); + if (pageInfo == null) return ""; + for (Map model : pageInfo.model) { + buildSaveModelFields(datasets, pageInfo, model, true); + buildSaveModelFields(datasets, pageInfo, model, false); + } + return JsonUtil.encodeString(pageInfo); + } + + //处理model的fields和filters + private static void buildSaveModelFields(PageDatasets datasets, PageModel pageInfo, Map model, boolean isField) { + String db = (String) model.get("dataset"); + //没有配置db,配置有误,不处理 + if (StringUtils.isEmpty(db)) throw new BizException("model未配置数据集db,无法解析!"); + PageDataset pds = datasets.findById(db); + String key = isField ? "fields" : "filters"; + List> fields = (List>) model.get(key); + if (fields == null || fields.isEmpty()) return; + for (Map field : fields) { + String fn = (String) field.get("field"); + if (StringUtils.isEmpty(fn)) throw new BizException("model[" + db + "]." + key + "未配置字段名field,无法解析!"); + PageDatasetField pdf = isField ? pds.findFieldByName(fn) : pds.findFilterByName(fn); + if (pdf == null) throw new BizException("model[" + db + "]." + key + "未找到定义的数据集字段(" + fn + "),无法解析!"); + + if (CommUtil.isStrEquals(MapUtil.readString(field, "label"), pdf.label)) { + field.remove("label"); + } + + //必填字段 + if (pdf.isFieldNotNull() == MapUtil.readBool(field, "required")) { + field.remove("required"); + } + + final SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(pdf.dataType); + if (dtb != null && MapUtil.readInt(field, "maxlength") == dtb.dataLength) { + field.remove("maxlength"); + } + } + } + + /** + * 保存的数据集,删除掉一些不必要的字段信息 + * + * @param jsonStr + * @return + */ + public static String buildSaveDataset(String jsonStr) { + PageDatasets datasets = parsePageDataset(jsonStr); + if (datasets == null || datasets.list == null) return ""; + for (PageDataset dataSet : datasets.list) { + buildSaveDataSetFields(dataSet.fields); + buildSaveDataSetFields(dataSet.filters); + } + return JsonUtil.encodeString(datasets.list); + } + + /** + * 构建待保存的数据集 + * + * @return + * @throws JsonProcessingException + */ + public static void buildSaveDataSetFields(List fields) { + ModelTable table = null; + for (PageDatasetField field : fields) { + if (field.table <= 0) continue; + if (table == null || table.getEntityId() != field.table) { + table = ModelTableCache.getInstance().get(field.table); + } + if (table == null) continue; + ModelField tf = table.findFieldByName(field.field); + if (tf == null) continue; + field.table_text = null; + if (CommUtil.isStrEquals(tf.getTitle(), field.label)) field.label = null; + if (CommUtil.isStrEquals(tf.getDataType(), field.dataType)) field.dataType = null; + if (CommUtil.isStrEquals(tf.getRemark(), field.remark)) field.remark = null; + if (CommUtil.isStrEquals(tf.getEditor(), field.editor)) field.editor = null; + } + } + + /** + * 构建请求的数据集,补充表定义信息 + * + * @return + * @throws JsonProcessingException + */ + public static String buildReqDataset(PageDatasets datasets) { + if (datasets == null || datasets.list == null) return ""; + return JsonUtil.encodeString(datasets.list); + } + + + /** + * 根据数据库存储的信息,加工处理成页面要的,与buildsave逆向 + * + * @param form + * @return + */ + public static String buildReqModel(ModelForm form) { + PageDatasets datasets = form.getDatasets(); + PageModel pageInfo = parsePageInfo(form.getContent()); + if (pageInfo == null) return ""; + for (Map model : pageInfo.model) { + String db = (String) model.get("dataset"); + //没有配置db,配置有误,不处理 + if (StringUtils.isEmpty(db)) continue; + PageDataset dataSet = datasets.findById(db); + if (dataSet == null) continue; + buildReqModelFields(dataSet, model, true); + buildReqModelFields(dataSet, model, false); + } + return JsonUtil.encodeString(pageInfo); + } + + //处理model的fields和filters + private static void buildReqModelFields(PageDataset dataSet, Map model, boolean isField) { + String key = isField ? "fields" : "filters"; + List> fields = (List>) model.get(key); + if (fields == null || fields.isEmpty()) return; + for (Map field : fields) { + String fn = (String) field.get("field"); + if (StringUtils.isEmpty(fn)) continue; + PageDatasetField pdf = isField ? dataSet.findFieldByName(fn) : dataSet.findFilterByName(fn); + if (pdf == null) continue; + if (!field.containsKey("label")) { + field.put("label", pdf.label); + } + //必填字段 + if (!field.containsKey("required")) { + field.put("required", pdf.isFieldNotNull()); + } + + if (!field.containsKey("maxlength")) { + final SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(pdf.dataType); + if (dtb != null) { + field.put("maxlength", dtb.dataLength); + } + } + if (!isField) { + PageDatasetFilter filter = (PageDatasetFilter) pdf; + field.put("type", filter.type); + field.put("linkDb", filter.linkDb); + field.put("linkField", filter.linkField); + field.put("value", filter.value); + field.put("trigger",filter.trigger); + } + } + } + + /** + * 根据数据库存储的信息,加工处理成页面要的,与buildsave逆向 + * + * @param form + * @return + */ + public static String buildEngineModel(ModelForm form, SwMap params, UserSession us) { + return buildEngineModel(form, params, us, true); + } + + public static String buildEngineModel(ModelForm form, SwMap params, UserSession us, boolean incExtra) { + PageDatasets datasets = form.getDatasets(); + if (datasets == null || datasets.list == null) return ""; + + SwMap ret = new SwMap(); + PageModel pageInfo = parsePageInfo(form.getContent()); + if (pageInfo == null) return ""; + ret.put("pageId", form.getEntityId()); + ret.put("label", form.getTitle()); + ret.put("service", form.getService()); + ret.put("module", ModelProjectCache.getInstance().getModule(form.getPrjId())); + buildOptsEx(form, ret); + //form不用管 + if (pageInfo.form != null) ret.put("form", pageInfo.form); + List listModel = new ArrayList<>(); + ret.put("model", listModel); + //构建Model + for (Map model : pageInfo.model) { + String db = (String) model.get("dataset"); + PageDataset dataSet = datasets.findById(db); + if (dataSet == null) throw new BizException("未找到指定的数据集定义!" + db); + + listModel.add(buildEngineModelMap(dataSet, model)); + } + if (incExtra) { + ret.put("extra", buildEngineExtra(pageInfo.option, params, us)); + } + return JsonUtil.encodeString(ret); + } + + //构建model部分 + private static SwMap buildEngineModelMap(PageDataset dataSet, Map model) { + SwMap ret = new SwMap(); + + ret.put("id", dataSet.id); + ret.put("name", dataSet.name); + ret.put("label", dataSet.label); + ret.put("type", dataSet.type); + ret.put("idField", dataSet.idField); + ret.put("lazy", dataSet.lazy); + ret.put("canEdit", dataSet.canEdit); + + ret.put("fields", model.get("fields")); + ret.put("filters", model.get("filters")); + + buildReqModelFields(dataSet, model, true); + buildReqModelFields(dataSet, model, false); + + return ret; + } + + //根据option构建Extra部分 + private static SwMap buildEngineExtra(Map option, SwMap params, UserSession us) { + SwMap map = new SwMap(); + if (option == null) return map; + //控件信息 + SwMap widget = new SwMap(); + map.put("widget", widget); + + List widgetIds = (List) option.get("widgetRef"); + for (Object v : widgetIds) { + long id; + if (v instanceof String) { + id = Long.parseLong((String) v); + } else if (v instanceof Integer) { + id = (Integer) v; + } else if (v instanceof Long) { + id = (Long) v; + } else throw new BizException("不能识别的控件Id:" + v); + ModelForm widgetForm = getFromCache(id); + if (widgetForm == null) throw new BizException("没有找到指定的控件定义!id=" + id); + SwMap w = new SwMap(); + widget.put("w" + id, w); + SwMap widgetOpts = widgetForm.getOpts(); + w.put("service", widgetForm.getService()); + if (widgetOpts != null) w.putAll(widgetOpts); + w.put("define", buildEngineModel(widgetForm, params, us, false)); + } + //构建变量 + SwMap mapVar = new SwMap(); + map.put("var", mapVar); + List vars = (List) option.get("vars"); + for (String var : vars) { + mapVar.put(var, SwVariableFactory.getInstance().calcVar(var, params, us)); + } + return map; + } + + //获取控件的filter信息 + public static List buildWidgetFilter(ModelForm bean) { + List listRet = new ArrayList<>(); + PageDatasets datasets = bean.getDatasets(); + if (datasets == null || datasets.list == null) return listRet; + for (PageDataset ds : datasets.list) { + for (PageDatasetFilter filter : ds.filters) { + if (SwEnum.FilterType.INPUT.value.equals(filter.type) || SwEnum.FilterType.PARAM.value.equals(filter.type)) { + SwMap fret = new SwMap(); + fret.put("name", filter.name); + fret.put("label", filter.label); + listRet.add(fret); + } + } + } + listRet.sort((o1, o2) -> CommUtil.chineseCompare(o1.readString("label"), o2.readString("label"))); + return listRet; + } + + /** + * 构建一些扩展属性,目前主要是eventPath + * + * @param opts + */ + public static void buildOptsEx(ModelForm bean, SwMap opts) { + String eventPath = getEventPath(bean); + if (StringUtils.isNotEmpty(eventPath)) { + opts.put(KEY_EVENT_PATH, eventPath); + } + } + + public static String getEventPath(ModelForm bean) { + String moduleName = ModelProjectCache.getInstance().getModule(bean.getPrjId()); + if (StringUtils.isNotEmpty(moduleName)) { + String ep = moduleName; + String cn = ModelCatalogCache.getInstance().getFullName(bean.getMcId()); + if (StringUtils.isNotEmpty(cn)) ep = ep + "." + cn; + return ep + "." + bean.getName(); + } + return ""; + } + + /** + * 根据向导生成model + * @param form + * @param tmplId + */ + public static void buildSaveModelByTmpl(ModelForm form, String tmplId) { + PageDatasets datasets = form.getDatasets(); + SwMap tmplModel = JsonUtil.parse(form.getTmpl(), SwMap.class); + tmplModel.put("title", form.getTitle()); + tmplModel.put("datasets", JsonUtil.bean2MapList(form.getDatasets().list)); + SwMap layout = tmplModel.readMap("layout"); + //用到的自定义控件 + Set setWidget = new HashSet<>(); + for (String key : layout.keySet()) { + List> groups = layout.readListMap(key); + for (Map group : groups) { + String type = MapUtil.readString(group, "type"); + switch (type) { + case PAGE_TYPE_CARD: + buildTmplFields(MapUtil.readListMap(group, "fields"), datasets, setWidget, true); + break; + case PAGE_TYPE_LIST: + buildTmplFields(MapUtil.readListMap(group, "fields"), datasets, setWidget, true); + buildTmplFields(MapUtil.readListMap(group, "cfilters"), datasets, setWidget, false); + buildTmplFields(MapUtil.readListMap(group, "sfilters"), datasets, setWidget, false); + break; + } + } + } + String widgetRef = ""; + if (!setWidget.isEmpty()) { + for (long s: setWidget) { + widgetRef += ",\"" + s + "\""; + } + widgetRef = widgetRef.substring(1); + } + tmplModel.put("widgetRef", widgetRef); + final String model = CodeGenerator.getInstance().generate(tmplModel, tmplId); + form.setContent(model); +// form.setContent(buildSaveModel(form)); + } + + private static void buildTmplFields(List> fields, PageDatasets datasets, Set setWidget, boolean isField) { + if (fields == null) return; + PageDataset dataset = null; + for (Map field : fields) { + final String dsId = MapUtil.readString(field, "dataset"); + if (dataset == null || !dataset.id.equals(dsId)) { + dataset = datasets.findById(dsId); + if (dataset == null) throw new BizException("没有找到指定数据集:" + dsId); + } + String fn = MapUtil.readString(field, "field"); + PageDatasetField pdf; + if (!isField) { + pdf = dataset.findFilterById(fn); + } else { + pdf = dataset.findFieldById(fn); + if (pdf == null) pdf = dataset.findFilterByName(fn); + } + if (pdf == null) throw new BizException("model[" + dsId + "]未找到定义的数据集字段(" + fn + "),无法解析!"); + field.put("id", pdf.id); + field.put("field", pdf.field); + field.put("name", pdf.name); + field.put("label", pdf.label); + field.put("required", pdf.isFieldNotNull()); + field.put("widget", 0); + final SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(pdf.dataType); + if (dtb != null) { + field.put("maxlength", dtb.dataLength); + field.put("editor", dtb.editor); + if (pdf.link > 0) { + long widget = getFieldCtrl(pdf.link); + if (widget > 0) { + setWidget.add(widget); + field.put("widget", widget); + field.put("widgetText", ModelFormCache.getInstance().getText(widget)); + } + } + } else { + field.put("maxlength", 0); + field.put("editor", SwEnum.EditorType.INPUT.value); + } + } + } + + /** + * 计算字段适用控件 + * + * @param tableId + * @return + */ + public static long getFieldCtrl(long tableId) { + Set set = ModelFormCache.getInstance().getListByTable(tableId, SwEnum.FormType.WIDGET.value); + if (set == null || set.isEmpty()) return 0L; + ModelForm form = set.iterator().next(); + return (form != null) ? form.getEntityId() : 0L; + } + + //js文件的路径 + public String getJsPath(ModelForm form) { + if (form == null) throw new BizException("页面定义对象不能为空!"); + String moduleName = ModelProjectCache.getInstance().getModule(form.getPrjId()); + BpmConfigBean bpmConfigBean = SpringUtil.getBean(BpmConfigBean.class); + Map mapIdeaModules = IdeaUtil.getModules(bpmConfigBean.getCodeJavaPath()); + if (mapIdeaModules == null || mapIdeaModules.isEmpty()) throw new BizException("没有定义idea项目的路径(smtweb.bpm.codeJavaPath)!"); + String codeJavaPath = mapIdeaModules.get(moduleName); + if (StringUtils.isEmpty(codeJavaPath)) { + throw new BizException("没有找到对应项目在idea中Module的路径(" + moduleName + ")!"); + } + codeJavaPath += "/src/main/resources/static/event/" + moduleName + "/"; + //加上目录 + String cn = ModelCatalogCache.getInstance().getFullName(form.getMcId()); + if (StringUtils.isNotEmpty(cn)) { + codeJavaPath += cn.replaceAll("\\.", "/"); + } + return codeJavaPath; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java new file mode 100644 index 0000000..32b55b2 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java @@ -0,0 +1,102 @@ +package cc.smtweb.system.bpm.web.design.form; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.mvc.service.DefaultLoadHandler; +import cc.smtweb.framework.core.util.FileUtil; +import cc.smtweb.framework.core.util.JsonUtil; +import cc.smtweb.system.bpm.web.design.db.ModelProjectCache; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by Akmm at 2022/5/9 16:17 + */ +public class ModelFormLoadHandler extends DefaultLoadHandler { + public ModelFormLoadHandler() { + super(ModelForm.ENTITY_NAME); + } + + @Override + protected ModelForm loadComp(long id) { + ModelForm bean = super.loadComp(id); + SwMap opts = bean.getOpts(); + if (opts != null) { + ModelFormHelper.buildOptsEx(bean, opts); + bean.setOption(JsonUtil.encodeString(opts)); + } + //去掉content和dataset + bean.getData().remove("mf_content"); + bean.getData().remove("mf_dataset"); + return bean; + } + + //页面设计-加载数据集定义 + public R loadDataset() { + long id = params.readLong("id"); + ModelForm bean = super.loadComp(id); + if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id); + return R.success(ModelFormHelper.buildReqDataset(bean.getDatasets())); + } + + //页面设计 - 加载页面model定义 + public R loadModel() { + long id = params.readLong("id"); + ModelForm bean = super.loadComp(id); + if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id); + return R.success(ModelFormHelper.buildReqModel(bean)); + } + + //页面引擎-获取页面模型 + public R loadForm() { + long id = params.readLong("id"); + ModelForm bean = super.loadComp(id); + if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id); + return R.success(ModelFormHelper.buildEngineModel(bean, params, us)); + } + + //获取页面使用的控件的filter信息 + public R loadWidgetFilter() { + long id = params.readLong("id"); + ModelForm bean = super.loadComp(id); + if (bean == null) throw new BizException("没有找到指定控件定义!id=" + id); + return R.success(ModelFormHelper.buildWidgetFilter(bean)); + } + + //加载页面js方法 + public R loadJsFuncs() { + long pageId = params.readLong("pageId"); + ModelForm form = ModelFormCache.getInstance().get(pageId); + if (form == null) throw new BizException("未找到指定的页面定义(" + pageId + ")!"); + String moduleName = ModelProjectCache.getInstance().getModule(form.getPrjId()); + List listRet = new ArrayList<>(); + R r = R.success(listRet); + if (StringUtils.isEmpty(moduleName)) { + return r; + } + String path = ModelFormHelper.getEventPath(form) + "/" + form.getName() + ".js"; + String js = FileUtil.readFileStr(path); + if (StringUtils.isEmpty(js)) { + return r; + } + //解析,比如以【return 】 + int index = js.lastIndexOf("return "); + if (index < 0) { + return r; + } + index = js.indexOf("{", index); + js = js.substring(index + 1, js.indexOf("}", index)).trim(); + String[] fs = js.split(","); + for (String s: fs) { + if (StringUtils.isNotBlank(s)) { + listRet.add(s.trim()); + } + } + return R.success(listRet); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java new file mode 100644 index 0000000..6ccfab9 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java @@ -0,0 +1,135 @@ +package cc.smtweb.system.bpm.web.design.form; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.DefaultSaveHandler; +import cc.smtweb.framework.core.util.JsonUtil; +import org.apache.commons.lang3.StringUtils; + +/** + * Created by Akmm at 2022/5/9 17:05 + * 页面定义保存,注意不要覆盖content和dataset + */ +public class ModelFormSaveHandler extends DefaultSaveHandler { + public ModelFormSaveHandler() { + super(ModelForm.ENTITY_NAME); + } + + @Override + protected void updateBean(EntityDao dao) { + SwMap opts = bean.getOpts(); + if (opts != null) { + opts.remove(ModelFormHelper.KEY_EVENT_PATH); + bean.setOption(JsonUtil.encodeString(opts)); + } + + dao.updateEntityEx(bean, "mf_content", "mf_dataset", "mf_tmpl"); + } + + public R saveDataset() { + long id = params.readLong("id"); + String data = params.readString("data"); + bean = loadComp(id); + if (StringUtils.isEmpty(data)) { + throw new BizException("没有待保存的数据!"); + } + bean.setDataset(ModelFormHelper.buildSaveDataset(data)); + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + EntityDao dao = DbEngine.getInstance().findDao(tableName); + + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); + if (field != null) bean.put(field.getName(), us.getUserId()); + dao.updateEntity(bean, "mf_dataset"); + } + + @Override + public void doAfterDbCommit() { + saveSuccess(); + } + + @Override + public void doAfterDbRollback() { + saveFailed(); + } + }); + return R.success(); + } + + public R saveModel() { + long id = params.readLong("id"); + String data = params.readString("data"); + bean = loadComp(id); + if (StringUtils.isEmpty(data)) { + throw new BizException("没有待保存的数据!"); + } + bean.setContent(ModelFormHelper.buildSaveModel(bean, data)); + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + EntityDao dao = DbEngine.getInstance().findDao(tableName); + + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); + if (field != null) bean.put(field.getName(), us.getUserId()); + dao.updateEntity(bean, "mf_content"); + } + + @Override + public void doAfterDbCommit() { + saveSuccess(); + } + + @Override + public void doAfterDbRollback() { + saveFailed(); + } + }); + return R.success(); + } + + public R saveModelByTmpl() { + long id = params.readLong("pageId"); + String templateId = params.readString("templateId"); + String data = params.readString("data"); + bean = loadComp(id); + if (StringUtils.isEmpty(data)) { + throw new BizException("没有待保存的数据!"); + } + bean.setTmpl(data); + ModelFormHelper.buildSaveModelByTmpl(bean, templateId); + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + EntityDao dao = DbEngine.getInstance().findDao(tableName); + + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); + if (field != null) bean.put(field.getName(), us.getUserId()); + dao.updateEntity(bean, "mf_content,mf_tmpl"); + } + + @Override + public void doAfterDbCommit() { + saveSuccess(); + } + + @Override + public void doAfterDbRollback() { + saveFailed(); + } + }); + return R.success(ModelFormHelper.buildReqModel(bean)); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java new file mode 100644 index 0000000..84b001e --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java @@ -0,0 +1,177 @@ +package cc.smtweb.system.bpm.web.design.form; + +import cc.smtweb.framework.core.annotation.SwBody; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.mvc.service.AbstractCompService; +import cc.smtweb.framework.core.mvc.service.AbstractHandler; +import cc.smtweb.framework.core.mvc.service.DefaultDelHandler; +import cc.smtweb.framework.core.mvc.service.DefaultListHandler; +import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.framework.core.util.SqlUtil; +import cc.smtweb.system.bpm.util.CodeGenerator; +import org.apache.commons.lang3.StringUtils; + +import java.sql.ResultSetMetaData; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Akmm at 2022/3/22 9:12 + */ +@SwService +public class ModelFormService extends AbstractCompService { + private final static String TYPE_CODE = "type_code"; + @Override + protected AbstractHandler createHandler(String type) { + switch (type) { + case TYPE_LOAD: + return new ModelFormLoadHandler(); + case TYPE_SAVE: + return new ModelFormSaveHandler(); + case TYPE_DEL: + return new DefaultDelHandler(ModelForm.ENTITY_NAME); + case TYPE_LIST: + return new DefaultListHandler(ModelForm.ENTITY_NAME); + case TYPE_CODE: + return new CodeBuildHandler(); + } + return null; + } + + //保存数据集 + public R saveDataset(@SwBody SwMap params, UserSession us) { + try { + ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE); + return handler.saveDataset(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //加载数据集 + public R loadDataset(@SwBody SwMap params, UserSession us) { + try { + ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); + return handler.loadDataset(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //保存页面模型 + public R saveModel(@SwBody SwMap params, UserSession us) { + try { + ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE); + return handler.saveModel(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //根据模板保存页面定义 + public R saveModelByTmpl(@SwBody SwMap params, UserSession us) { + try { + ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE); + return handler.saveModelByTmpl(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //加载页面模型 + public R loadModel(@SwBody SwMap params, UserSession us) { + try { + ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); + return handler.loadModel(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //加载页面js方法 + public R loadJsFuncs(@SwBody SwMap params, UserSession us) { + try { + ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); + return handler.loadJsFuncs(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //加载引擎用页面模型 + public R model(@SwBody SwMap params, UserSession us) { + try { + ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); + return handler.loadForm(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //获取页面使用的控件的filter信息 + public R loadWidgetFilter(@SwBody SwMap params, UserSession us) { + try { + ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); + return handler.loadWidgetFilter(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //获取自定义sql的字段信息,去库里查 + public R loadSqlFields(@SwBody SwMap params, UserSession us) { + try { + String sql = params.readString("sql"); + if (StringUtils.isEmpty(sql)) return R.error("没有传入的sql!"); + sql = sql.trim().toLowerCase(); + if (!sql.startsWith("select")) return R.error("非查询类sql,禁止执行!"); + if (sql.contains(";")) return R.error("sql内禁止出现分号!"); + sql = SqlUtil.replaceTable(sql); + List ret = DbEngine.getInstance().query(sql + " where 1=0", rs -> { + List fields = new ArrayList<>(); + ResultSetMetaData metaData = rs.getMetaData(); + + for (int i = 1, count = metaData.getColumnCount(); i <= count; i++) { + SwMap col = new SwMap(2); + col.put("name", metaData.getColumnLabel(i)); + SwEnum.DataTypeBean dtb = SwEnum.DataType.getBySqlType(metaData.getColumnType(i), metaData.getPrecision(i), metaData.getScale(i)); + col.put("dataType", dtb.value); + fields.add(col); + } + return fields; + }); + return R.success(ret); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //加载模板定义 + public R loadTmpls(@SwBody SwMap params, UserSession us) { + return R.success(CodeGenerator.getInstance().getModelTemplates()); + } + + //生成java代码 + public R buildJavaCode(@SwBody SwMap params, UserSession us) { + try { + CodeBuildHandler handler = (CodeBuildHandler) getHandler(params, us, TYPE_CODE); + return handler.buildJavaCode(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } + + //生成js代码 + public R buildJsCode(@SwBody SwMap params, UserSession us) { + try { + CodeBuildHandler handler = (CodeBuildHandler) getHandler(params, us, TYPE_CODE); + return handler.buildJsCode(); + } catch (Exception e) { + return R.error("操作失败!", e); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java new file mode 100644 index 0000000..dddc39a --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java @@ -0,0 +1,137 @@ +package cc.smtweb.system.bpm.web.design.form.define; + +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; + +/** + * Created by Akmm at 2022/4/18 14:20 + * 数据集定义 + */ +public class PageDataset { + //唯一标识 + public String id; + //名称 + public String name; + //中文名 + public String label; + //类别:list-列表;form-表单;editList-编辑列表;tree + public String type; + //主表 + public long masterTable; + public String masterTable_text; + //id字段 对应field的name + public String idField; + //list的自定义sql,仅列表支持,select fields from tables [condition] group by xxx order by xxx + public String sql; + //固定条件,如f1='a' and f2=:p1 + public String fixedCond; + //是否懒加载 + public boolean lazy; + //是否可编辑 + public boolean canEdit; + //select的字段 + public List fields; + public List filters; + public List data; + public PageDatasetDynCond dynCond; + public List sortFields; + + //按字段名的缓存 + private Map mapFieldName; + private Map mapFilterName; + //按字段Id的缓存 + private Map mapFieldId; + private Map mapFilterId; + + //依赖的数据集 + private Set linkDs = new HashSet<>(); + + public PageDatasetField findFieldByName(String name) { + if (mapFieldName == null) resetFields(); + return mapFieldName.get(name); + } + + public PageDatasetFilter findFilterByName(String name) { + if (mapFilterName == null) resetFields(); + return mapFilterName.get(name); + } + + public PageDatasetField findFieldById(String id) { + if (mapFieldId == null) resetFields(); + return mapFieldId.get(id); + } + + public PageDatasetFilter findFilterById(String id) { + if (mapFilterId == null) resetFields(); + return mapFilterId.get(id); + } + + /** + * 重置丰富字段信息 + */ + public void resetFields() { + mapFieldName = new HashMap<>(); + mapFieldId = new HashMap<>(); + linkDs.clear(); + resetFields(mapFieldName, mapFieldId, fields, false); + mapFilterName = new HashMap<>(); + mapFilterId = new HashMap<>(); + resetFields(mapFilterName, mapFilterId, filters, true); + + for (PageDatasetFilter filter : filters) { + if (StringUtils.isEmpty(filter.sqlName)) { + filter.sqlName = filter.field; + } + } + } + + private void resetFields(Map mapName, Map mapId, List list, boolean isFilter) { + ModelTableCache cache = ModelTableCache.getInstance(); + ModelTable table = null; + for (T field : list) { + mapName.put(field.name, field); + mapId.put(field.id, field); + if (field.table <= 0 || StringUtils.isEmpty(field.field)) continue; + if (table == null || table.getId() != field.table) { + table = cache.get(field.table); + } + if (table == null) continue; + ModelField mf = table.findField(field.field); + if (mf == null) throw new BizException("未找到表字段的定义信息(" + table.getName() + "." + field.field + ")"); + field.table_text = table.getTitle(); + field.fieldType = mf.getFieldType(); + field.notNull = mf.getNotNull(); + field.link = mf.getLink(); + + if (StringUtils.isEmpty(field.label)) field.label = mf.getTitle(); + if (StringUtils.isEmpty(field.dataType)) field.dataType = mf.getDataType(); + if (StringUtils.isEmpty(field.remark)) field.remark = mf.getRemark(); + if (StringUtils.isEmpty(field.editor)) field.editor = mf.getEditor(); + //过滤条件,需要建立依赖关系 + if (isFilter) { + PageDatasetFilter filter = (PageDatasetFilter) field; + if (StringUtils.isNotEmpty(filter.linkDb)) linkDs.add(filter.linkDb); + } + } + } + + public PageDatasetFilter findFilterByDs(String dsName) { + for (PageDatasetFilter filter : filters) { + if (SwEnum.FilterType.LINK.value.equals(filter.type) && dsName.equals(filter.linkDb)) { + return filter; + } + } + return null; + } + + public boolean hasDepends(String dsName) { + return linkDs.contains(dsName); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetDynCond.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetDynCond.java new file mode 100644 index 0000000..16efb8e --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetDynCond.java @@ -0,0 +1,25 @@ +package cc.smtweb.system.bpm.web.design.form.define; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +/** + * Created by Akmm at 2022/4/20 18:15 + */ //动态条件,一颗二叉树 +public class PageDatasetDynCond { + public String param; + public String opt; + public List children; + + @JsonIgnore + public boolean isEmpty() { + return StringUtils.isEmpty(param) && StringUtils.isEmpty(opt); + } + + @JsonIgnore + public boolean isCondOpt() { + return StringUtils.isEmpty(param); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetEnumData.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetEnumData.java new file mode 100644 index 0000000..2a71919 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetEnumData.java @@ -0,0 +1,9 @@ +package cc.smtweb.system.bpm.web.design.form.define; + +/** + * Created by Akmm at 2022/4/20 18:15 + */ //简单枚举combo的数据 +public class PageDatasetEnumData { + public String value; + public String label; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetField.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetField.java new file mode 100644 index 0000000..0101386 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetField.java @@ -0,0 +1,41 @@ +package cc.smtweb.system.bpm.web.design.form.define; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Created by Akmm at 2022/4/20 18:15 + */ //字段要素 +public class PageDatasetField { + public String id; + //表 + public long table; + public String table_text; + //字段 + public String field = ""; + //有别名取别名,无别名同字段名 + public String name; + public String label; + //合计栏 + public String summary; + + public String remark; + //字段类型,如编码字段,参见FieldTypeDef + public int fieldType; + /** + * 数据类型,参见DataType + */ + public String dataType; + /** + * '禁止为空' + */ + public int notNull; + //外键关联表 + public long link; + //控件类型:TEXT/TextArea/NUMBER/COMBO + public String editor; + + @JsonIgnore + public boolean isFieldNotNull() { + return notNull == 1; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java new file mode 100644 index 0000000..4eb2538 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java @@ -0,0 +1,20 @@ +package cc.smtweb.system.bpm.web.design.form.define; + +/** + * Created by Akmm at 2022/4/20 18:15 + */ //过滤条件信息 +public class PageDatasetFilter extends PageDatasetField { + //param-参数/link/const + public String type; + public String title; + //sql中的查询字段名,可能带前缀 + public String sqlName; + //type为link时,关联的数据集及字段 + public String linkDb; + public String linkField; + //type为const时,常量值 + public String value; + // 触发类型 click按钮触发;change监听触发 + public String trigger; + public boolean required = false; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetSortField.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetSortField.java new file mode 100644 index 0000000..46fb4f3 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetSortField.java @@ -0,0 +1,9 @@ +package cc.smtweb.system.bpm.web.design.form.define; + +/** + * Created by Akmm at 2022/4/20 18:16 + */ +public class PageDatasetSortField { + public String field; + public String type; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java new file mode 100644 index 0000000..def7f1d --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java @@ -0,0 +1,57 @@ +package cc.smtweb.system.bpm.web.design.form.define; + +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.util.*; + +/** + * Created by Akmm at 2022/5/25 15:53 + * 数据集集合 + */ +public class PageDatasets { + public List list; + + @JsonIgnore + private Map mapId = null; + @JsonIgnore + private Map mapName = null; + + public PageDatasets(PageDataset[] datasets) { + this.list = new ArrayList<>(datasets.length); + this.mapId = new HashMap<>(datasets.length); + this.mapName = new HashMap<>(datasets.length); + for (PageDataset ds : datasets) { + this.list.add(ds); + mapId.put(ds.id, ds); + mapName.put(ds.name, ds); + ds.masterTable_text = ModelTableCache.getInstance().getTableName(ds.masterTable); + ds.resetFields(); + } + //按依赖关系排序 + this.list.sort((o1, o2) -> { + if (o1.hasDepends(o2.name)) return 1; + if (o2.hasDepends(o1.name)) return -1; + return 0; + }); + } + + public PageDataset findMasterDataset() { + if (list == null || list.isEmpty()) return null; + return this.list.get(0); + } + + public long findMasterTableId() { + PageDataset ds = findMasterDataset(); + if (ds == null) return 0L; + return ds.masterTable; + } + + public PageDataset findById(String id) { + return mapId.get(id); + } + + public PageDataset findByName(String name) { + return mapName.get(name); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageModel.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageModel.java new file mode 100644 index 0000000..15dcf8f --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageModel.java @@ -0,0 +1,15 @@ +package cc.smtweb.system.bpm.web.design.form.define; + +import java.util.List; +import java.util.Map; + +/** + * Created by Akmm at 2022/4/20 15:39 + * 页面模型 + */ +public class PageModel { + public List> form; + public List> model; + public Map option; + public Map extra; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java new file mode 100644 index 0000000..09a506d --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java @@ -0,0 +1,52 @@ +package cc.smtweb.system.bpm.web.design.preview; + +import cc.smtweb.system.bpm.util.ITreeDataLevelHandler; +import lombok.Data; + +import java.util.List; + +@Data +public class MenuVO { + private Long id; + private Long parentId; + private int level; + private String name; + private String path; + private String icon; + private List children; + + // 树结构数据句柄 + public static ITreeDataLevelHandler createTreeHandler() { + return new ITreeDataLevelHandler () { + @Override + public Long getId (MenuVO node){ + return node.getId(); + } + + @Override + public Long getParentId (MenuVO node){ + return node.getParentId(); + } + + @Override + public List getChildren (MenuVO node){ + return node.children; + } + + @Override + public void setChildren (MenuVO node, List children){ + node.children = children; + } + + @Override + public int getLevel (MenuVO node){ + return node.level; + } + + @Override + public void setLevel (MenuVO node, int level){ + node.level = level; + } + } ; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java new file mode 100644 index 0000000..e1a308d --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java @@ -0,0 +1,53 @@ +package cc.smtweb.system.bpm.web.design.preview; + +import cc.smtweb.framework.core.annotation.SwParam; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.framework.core.util.CommUtil; +import cc.smtweb.system.bpm.util.TreeDataUtil; +import cc.smtweb.system.bpm.web.design.db.ModelProjectCache; +import cc.smtweb.system.bpm.web.design.form.ModelForm; +import cc.smtweb.system.bpm.web.design.form.ModelFormCache; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +@SwService +public class PreviewMenuTreeService { + @SwParam + private DbEngine dbEngine; + + public R treeAll(@SwParam("module") String module, UserSession us) { + String prj_id = ModelProjectCache.getInstance().getIdByModule(module); + List listForm; + if (StringUtils.isNotEmpty(prj_id)) { + listForm = new ArrayList<>(ModelFormCache.getInstance().getFormsByPrj(Long.parseLong(prj_id))); + } else { + listForm = new ArrayList<>(ModelFormCache.getInstance().getAll()); + } + listForm.sort((o1, o2) -> CommUtil.chineseCompare(o1.getTitle(), o2.getTitle())); + if (listForm.isEmpty()) throw new BizException("此项目无页面设计!"); + + List list = new ArrayList<>(listForm.size()); + for (ModelForm form: listForm) { + MenuVO menu = new MenuVO(); + menu.setId(form.getId()); + menu.setName(form.getTitle()); + menu.setPath("/bpm/" + form.getId()); +// menu.setParentId(-1L); + list.add(menu); + } + + MenuVO root = new MenuVO(); + root.setName("项目"); + root.setPath(module); + List data = TreeDataUtil.buildTree(root, list, MenuVO.createTreeHandler()); + + return R.success(data); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java new file mode 100644 index 0000000..d91e643 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java @@ -0,0 +1,54 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.mvc.service.AbstractHandler; +import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.system.bpm.web.design.form.ModelForm; +import cc.smtweb.system.bpm.web.design.form.ModelFormHelper; +import cc.smtweb.system.bpm.web.design.form.define.PageDataset; +import cc.smtweb.system.bpm.web.design.form.define.PageDatasets; + +/** + * Created by Akmm at 2022/4/21 17:53 + */ +public abstract class AbstractDynPageHandler extends AbstractHandler { + //页面定义id + protected long pageId; + protected PageDatasets datasets; + + protected DynPageProvider provider = new DynPageProvider(); + + @Override + public void init(SwMap params, UserSession us) { + super.init(params, us); + pageId = params.readLong("pageId"); + ModelForm form = ModelFormHelper.getFromCache(pageId); + if (form == null) throw new BizException("没有找到页面定义数据(" + pageId + ")!"); + datasets = form.getDatasets(); + if (datasets == null || datasets.list == null) throw new BizException("没有找到页面定义的数据集数据(" + pageId + ")!"); + + provider.pageId = pageId; + provider.datasets = datasets; + } + + protected PageDataset findDataset(String name) { + return datasets.findByName(name); + } + + //获取第一个,主数据集 + protected PageDataset findMasterDataset() { + return datasets.findMasterDataset(); + } + + //从参数读取数据集定义 + protected PageDataset readParamDs() { + //数据集 + String dbName = params.readString("dataset"); + //对应的数据集定义 + PageDataset pageDataSet = findDataset(dbName); + if (pageDataSet == null) throw new BizException("没有找到指定的的数据集定义:" + dbName + "!"); + return pageDataSet; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java new file mode 100644 index 0000000..7c3199f --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java @@ -0,0 +1,156 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.EntityHelper; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.system.bpm.web.design.form.define.PageDataset; +import cc.smtweb.system.bpm.web.design.form.define.PageDatasetFilter; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by Akmm at 2022/4/21 17:53 + * 删除操作 + */ +public class DynPageDelHandler extends AbstractDynPageHandler { + /** + * 删除指定数据集,入参{pageId, dataset, id} + * + * @return + */ + public R delOne() { + long id = params.readLong("id"); + if (id == 0) throw new BizException("没有收到待删除记录Id(" + id + ")!"); + //数据集 + PageDataset pageDataSet = readParamDs(); + + checkBean(pageDataSet, id); + + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable); + if (table == null) throw new BizException("没有找到指定的的表定义:" + pageDataSet.name + "!"); + EntityDao dao = DbEngine.getInstance().findDao(table.getName()); + dao.deleteEntity(id); + } + + @Override + public void doAfterDbCommit() { + ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable); + if (table.isNeedCache()) { + AbstractCache cache = CacheManager.getIntance().getCache(table.getName()); + cache.remove(id); + } + } + }); + return R.success(); + } + + public R delAll() { + long id = params.readLong("id"); + if (id == 0) throw new BizException("没有收到待删除记录Id(" + id + ")!"); + //校验主表即可 + PageDataset masterDs = findMasterDataset(); + if (masterDs == null || !masterDs.canEdit || !SwEnum.DatasetType.FORM.value.equals(masterDs.type)) + throw new BizException("主表不允许删除!"); + checkBean(masterDs, id); + + Map mapRemovableInfo = new HashMap<>(); + for (PageDataset pageDataSet : datasets.list) { + //非表单编辑,不管 + if (!pageDataSet.canEdit || !SwEnum.DatasetType.FORM.value.equals(pageDataSet.type)) continue; + ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable); + RemovableInfo info = mapRemovableInfo.computeIfAbsent(table.getName(), k -> { + RemovableInfo ret = new RemovableInfo(k); + if (pageDataSet != masterDs) {//非主表,记录一下关联字段 + PageDatasetFilter f = pageDataSet.findFilterByDs(masterDs.name); + if (f == null) { + throw new BizException("无法删除表【" + pageDataSet.name + "】,此表未关联主表!"); + } + ret.field = f.field; + } + return ret; + }); + + if (pageDataSet == masterDs || !table.isNeedCache()) { + //主表或没有缓存,直接按FK删除 + info.addId(id); + } else { + info.needCache = true; + //有缓存,需要先把id查出来 + EntityDao dao = DbEngine.getInstance().findDao(table.getName()); + List list = dao.queryIdListWhere(info.field + " = ?", id); + info.ids.addAll(list); + } + } + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + for (RemovableInfo info : mapRemovableInfo.values()) { + EntityDao dao = DbEngine.getInstance().findDao(info.tableName); + if (!info.needCache && StringUtils.isNotEmpty(info.field)) { + //按外键来删除 + dao.deleteEntity(" where " + info.field + "=?", id); + } else { + dao.deleteEntity(info.ids); + } + } + } + + @Override + public void doAfterDbCommit() { + for (RemovableInfo info : mapRemovableInfo.values()) { + if (!info.needCache) continue; + AbstractCache cache = CacheManager.getIntance().getCache(info.tableName); + cache.remove(id); + + } + } + }); + return R.success(); + } + + /** + * 删除校验 + * + * @param pageDataSet + * @param id + */ + protected void checkBean(PageDataset pageDataSet, long id) { + //校验外键引用关系 + EntityHelper.checkExists(pageDataSet.masterTable, id); + } + + /** + * 待删除信息 + */ + class RemovableInfo { + String tableName; + String field = null; + boolean needCache = false; + List ids = new ArrayList<>(); + + public RemovableInfo(String tableName) { + this.tableName = tableName; + } + + void addId(long id) { + ids.add(id); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java new file mode 100644 index 0000000..18f934e --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java @@ -0,0 +1,238 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.SqlNamedPara; +import cc.smtweb.framework.core.util.MapUtil; +import cc.smtweb.system.bpm.web.design.form.define.*; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY; + +/** + * Created by Akmm at 2022/4/23 10:01 + * 动态页面辅助类 + */ +public class DynPageHelper { + /** + * 新建bean + * + * @param dataSet + * @return + */ + public static SwMap createBean(PageDataset dataSet) { + //主表 + ModelTable masterTable = ModelTableCache.getInstance().get(dataSet.masterTable); + EntityDao dao = DbEngine.getInstance().findDao(masterTable.getName()); + DefaultEntity bean = dao.createBean(); + return bean.getData(); + } + + /** + * 构建select fields from table + * + * @param dataSet + * @return + */ + public static SqlNamedPara buildSelectSql(PageDataset dataSet, Map params) { + StringBuilder sql = new StringBuilder(512); + + SqlNamedPara sqlNamedPara = buildWhereSql(dataSet, params); + + sql.append(buildSelFieldsSql(dataSet, sqlNamedPara)); + if (StringUtils.isNotEmpty(sqlNamedPara.sql)) { + sql.append(" where ").append(sqlNamedPara.sql); + } + if (dataSet.sortFields != null) { + String s = ""; + for (PageDatasetSortField sf : dataSet.sortFields) { + s += "," + sf.field + " " + sf.type; + } + if (StringUtils.isNotEmpty(s)) { + sql.append(" order by ").append(s.substring(1)); + } + } + sqlNamedPara.sql = sql.toString(); + sqlNamedPara.page = MapUtil.readInt(params, SwConsts.PARAM_PAGE); + sqlNamedPara.rows = MapUtil.readInt(params, SwConsts.PARAM_ROWS); + return sqlNamedPara; + } + + public static SqlNamedPara buildSumSql(PageDataset dataSet, Map params) { + SqlNamedPara sqlNamedPara = buildSelectSql(dataSet, params); + StringBuilder sql = new StringBuilder(256); + sql.append("select count(1) " + TOTAL_KEY); + for (PageDatasetField field : dataSet.fields) { + if (StringUtils.isEmpty(field.summary)) continue; + sql.append(","); + if (!SwEnum.SummaryType.instance.isText(field.summary)) { + sql.append(field.summary).append("(").append(field.name).append(") ").append(field.name); + } else { + sql.append("'").append(field.summary).append("' ").append(field.name); + } + } + sqlNamedPara.sql = sql.toString() + " from (" + sqlNamedPara.sql + ") xxxxa"; + return sqlNamedPara; + } + + private static String buildSelFieldsSql(PageDataset dataSet, SqlNamedPara sqlNamedPara) { + StringBuilder sql = new StringBuilder(512); + //主表 + ModelTable masterTable = ModelTableCache.getInstance().get(dataSet.masterTable); + //非查询列表,或sql为空,则自己组装select sql + if (!SwEnum.DatasetType.LIST.equals(dataSet.type) || StringUtils.isEmpty(dataSet.sql)) { + sql.append("select "); + for (PageDatasetField field : dataSet.fields) { + sql.append(field.field); + //加别名 + if (!field.field.equalsIgnoreCase(field.name)) { + sql.append(" ").append(field.name); + sqlNamedPara.addFieldAlias(field.field, field.name); + } + sql.append(","); + } + sql.setCharAt(sql.length() - 1, ' '); + sql.append(" from ").append(masterTable.getSchemaTableName()); + return sql.toString(); + } else { + return dataSet.sql; + } + } + + /** + * 构建where条件:组合固定和动态条件 + * + * @param dataSet + * @param params + * @return + */ + public static SqlNamedPara buildWhereSql(PageDataset dataSet, Map params) { + StringBuilder sql = new StringBuilder(512); + SwMap args = new SwMap(); + + if (StringUtils.isNotEmpty(dataSet.fixedCond)) { + sql.append("(").append(dataSet.fixedCond).append(")"); + } + //记录归属于固定条件的filter,最后设置参数 + Set setFixedFilter = new HashSet<>(); + for (PageDatasetFilter filter : dataSet.filters) { + setFixedFilter.add(filter.name); + } + if (!dataSet.dynCond.isEmpty()) { + String s = buildDynCondSql(dataSet, dataSet.dynCond, params, args, setFixedFilter); + if (StringUtils.isNotEmpty(s)) { + if (sql.length() > 0) sql.append(" and "); + sql.append(s); + } + } + for (String s : setFixedFilter) { + args.put(s, MapUtil.readString(params, s, "")); + } + return new SqlNamedPara(sql.toString(), args); + } + + /** + * 构建动态条件 + * + * @param dataSet + * @param dynCond + * @param params + * @param args + * @param setFixedFilter + * @return + */ + private static String buildDynCondSql(PageDataset dataSet, PageDatasetDynCond dynCond, Map params, SwMap args, Set setFixedFilter) { + if (dynCond.isCondOpt()) {//是and/or + if (dynCond.children == null || dynCond.children.isEmpty()) return ""; + StringBuilder sql = new StringBuilder(256); + boolean b = false; + //递归调用 + for (PageDatasetDynCond dc : dynCond.children) { + String s = buildDynCondSql(dataSet, dc, params, args, setFixedFilter); + if (StringUtils.isEmpty(s)) continue; + + if (b) sql.append(" ").append(dynCond.opt).append(" "); + sql.append(s); + b = true; + } + if (sql.length() > 0) { + return "(" + sql.toString() + ")"; + } + return ""; + } + + PageDatasetFilter filter = dataSet.findFilterById(dynCond.param); + if (filter == null) throw new BizException("没有找到filter(" + dynCond.param + ")!"); + + boolean isNameSelf = setFixedFilter.contains(filter.name); + setFixedFilter.remove(filter.name); + + Object value = null; + if (SwEnum.FilterType.CONST.value.equals(filter.type)) { + value = filter.value; + //todo 有变量的情况需要处理 + } else { + value = params.get(filter.name); + } + if (value == null || StringUtils.isEmpty(value.toString())) { + if (filter.required) { + throw new BizException("过滤条件不能为空(" + filter.name + ")!"); + } + return null; + } + IBuilderExpr builder = getBuilder(dynCond.opt); + String ns = isNameSelf ? filter.name : filter.name + "_" + dynCond.hashCode(); + return builder.build(dynCond.opt, filter.sqlName, ns, value, args); + } + + private static Map mapBuilder; + private static IBuilderExpr baseBuilder; + + static { + baseBuilder = (opt, field, name, value, args) -> { + args.put(name, value); + return field + " " + opt + " :" + name; + }; + mapBuilder = new HashMap<>(); + mapBuilder.put(SwEnum.OptType.LIKE.value, (opt, field, name, value, args) -> { + args.put(name, "%" + value + "%"); + return field + " like :" + name; + }); + + mapBuilder.put(SwEnum.OptType.PLIKE.value, (opt, field, name, value, args) -> { + args.put(name, value + "%"); + return field + " like :" + name; + }); + + mapBuilder.put(SwEnum.OptType.BT.value, (opt, field, name, value, args) -> { + String[] ss = value.toString().split(","); + if (ss.length != 2) throw new BizException("介于条件,参数值个数错误!"); + args.put(name + "_1", ss[0]); + args.put(name + "_2", ss[1]); + return "(" + field + ">=:" + name + "_1 and " + field + "<=:" + name + "_2)"; + }); + } + + private static IBuilderExpr getBuilder(String opt) { + IBuilderExpr builder = mapBuilder.get(opt); + return builder != null ? builder : baseBuilder; + } + + interface IBuilderExpr { + String build(String opt, String field, String name, Object value, Map args); + } + +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java new file mode 100644 index 0000000..2d5078a --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java @@ -0,0 +1,75 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityHelper; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.AbstractListHandler; +import cc.smtweb.framework.core.mvc.service.SqlNamedPara; +import cc.smtweb.framework.core.mvc.service.SqlPara; +import cc.smtweb.system.bpm.web.design.form.define.PageDataset; + +import java.util.List; + +import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY; + +/** + * Created by Akmm at 2022/5/26 15:58 + */ +public class DynPageListHandler extends AbstractListHandler { + protected long pageId; + //过滤条件 + private SwMap filter; + + //对应的数据集定义 + private PageDataset pageDataSet; + + public DynPageListHandler(long pageId, SwMap filter, PageDataset pageDataSet) { + this.pageId = pageId; + this.filter = filter; + this.pageDataSet = pageDataSet; + } + + @Override + protected String getCompId() { + return "dynpage_" + pageId + "_" + pageDataSet.id; + } + + @Override + protected String getPkFieldName() { + return pageDataSet.idField; + } + + @Override + protected SqlPara buildSqlPara() { + return DynPageHelper.buildSelectSql(pageDataSet, filter); + } + + @Override + protected List queryData(String sql, SqlPara sqlPara) { + List list; + SqlNamedPara sp = (SqlNamedPara)sqlPara; + if (sqlPara.page > 0 && sqlPara.rows > 0) { + list = DbEngine.getInstance().pagedQueryN(sql, SwMap.class, (sqlPara.page - 1) * sqlPara.rows, sqlPara.rows, sp.mapParas); + } else { + list = DbEngine.getInstance().queryN(sql, sp.mapParas, SwMap.class); + } + ModelTable masterTable = ModelTableCache.getInstance().get(pageDataSet.masterTable); + EntityHelper.loadBeanLink(masterTable.getName(), list, sp.mapFieldAlias); + return list; + } + + @Override + public R getTotal() { + SqlNamedPara sqlPara = DynPageHelper.buildSumSql(pageDataSet, filter); + + SwMap mapFooter = DbEngine.getInstance().queryEntityN(sqlPara.sql, sqlPara.mapParas, SwMap.class); + + SwMap r = new SwMap(); + r.put("total", mapFooter.get(TOTAL_KEY)); + r.put("footer", mapFooter); + return R.success(r); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageLoadHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageLoadHandler.java new file mode 100644 index 0000000..4f96b3d --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageLoadHandler.java @@ -0,0 +1,109 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.mvc.service.SwListData; +import cc.smtweb.system.bpm.web.design.form.define.PageDataset; + +/** + * Created by Akmm at 2022/4/21 17:53 + */ +public class DynPageLoadHandler extends AbstractDynPageHandler { + //数据集 + private String dbName; + //过滤条件 + private SwMap filter = new SwMap(); + + //对应的数据集定义 + private PageDataset pageDataSet; + + //列表工具类 + public DynPageListHandler getListWorker(SwMap filter, PageDataset pageDataSet) { + DynPageListHandler listHandler = new DynPageListHandler(pageId, filter, pageDataSet); + listHandler.init(params, us); + return listHandler; + } + + //新增操作,初始化定义的数据集 + public R add() { + //返回的数据,以dataset.name为key,查出的结果(bean或list)为value + SwMap mapRet = new SwMap(); + for (PageDataset dataSet : datasets.list) { + if (!dataSet.canEdit) { + continue; + } + if (SwEnum.DatasetType.FORM.value.equals(dataSet.type)) {//单表 + SwMap data; + //懒加载,给个空对象 + if (dataSet.lazy) { + data = new SwMap(); + } else { + data = DynPageHelper.createBean(dataSet); + } + afterAddBean(dataSet, data); + mapRet.put(dataSet.name, DynRetBean.createBean(data)); + } else if (SwEnum.DatasetType.TREE.value.equals(dataSet.type)) {//树 + SwMap data = new SwMap(); + afterAddBean(dataSet, data); + mapRet.put(dataSet.name, DynRetBean.createBean(data)); + } else if (!SwEnum.DatasetType.ENUM.value.equals(dataSet.type)) {//非枚举 + SwListData listData = SwListData.create(null, 0); + afterAddList(dataSet, listData); + mapRet.put(dataSet.name, DynRetBean.createList(listData)); + } + } + return R.success(mapRet); + } + + //新增初始化 - bean + protected void afterAddBean(PageDataset dataset, SwMap bean){} + //新增初始化 - list + protected void afterAddList(PageDataset dataset, SwListData bean){} + + //新增操作,初始化定义的数据集 + public R addOne() { + //对应的数据集定义 + PageDataset dataset = readParamDs(); + + if (!dataset.canEdit) { + return R.error("指定数据集为只读数据集[" + dataset.label + "]!"); + } + //懒加载,给个空对象 + SwMap data = DynPageHelper.createBean(dataset); + afterAddBean(dataset, data); + return R.success(DynRetBean.createBean(data)); + } + + public R loadOne() { + //过滤条件 + SwMap filter = params.readMap("filter"); + //对应的数据集定义 + PageDataset pageDataSet = readParamDs(); + + DynRetBean bean = null; + if (SwEnum.DatasetType.LIST.value.equals(pageDataSet.type)) {//列表类 + bean = DynRetBean.createList(getListWorker(filter, pageDataSet).buildListData()); + } else if (SwEnum.DatasetType.TREE.value.equals(pageDataSet.type)) {//树类 +// return new DynRetBean(loadTree()); + } else {//列表类 + bean = DynRetBean.createBean(provider.loadData(filter, pageDataSet)); + } + + return R.success(bean); + } + + /** + * 计算分页数据 + * + * @return + */ + public R getTotal() { + //数据集 + PageDataset pageDataSet = readParamDs(); + //过滤条件 + SwMap filter = params.readMap("filter"); + + return getListWorker(filter, pageDataSet).getTotal(); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageProvider.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageProvider.java new file mode 100644 index 0000000..5babb69 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageProvider.java @@ -0,0 +1,36 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityHelper; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.AbstractCompProvider; +import cc.smtweb.framework.core.mvc.service.SqlNamedPara; +import cc.smtweb.system.bpm.web.design.form.define.PageDataset; +import cc.smtweb.system.bpm.web.design.form.define.PageDatasets; + +/** + * Created by Akmm at 2022/5/26 18:40 + */ +public class DynPageProvider extends AbstractCompProvider { + protected long pageId; + protected PageDatasets datasets; + + //加载表单类数据集(单条) + public SwMap loadData(SwMap filter, PageDataset pageDataSet) { + return doGetData(pageDataSet.id, () -> { + SqlNamedPara sqlPara = DynPageHelper.buildSelectSql(pageDataSet, filter); + SwMap map = DbEngine.getInstance().queryEntityN(sqlPara.sql, sqlPara.mapParas, SwMap.class); + if (map == null) { + throw new BizException("没有找到指定数据(ds=" + pageDataSet.name + ")"); + } + ModelTable masterTable = ModelTableCache.getInstance().get(pageDataSet.masterTable); + EntityHelper.loadBeanLink(masterTable.getName(), map, sqlPara.mapFieldAlias); + return map; + }); + + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageSaveHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageSaveHandler.java new file mode 100644 index 0000000..3e18418 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageSaveHandler.java @@ -0,0 +1,270 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelIndex; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.service.TreeHelper; +import cc.smtweb.framework.core.util.CommUtil; +import cc.smtweb.system.bpm.web.design.form.define.PageDataset; +import cc.smtweb.system.bpm.web.design.form.define.PageDatasetFilter; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by Akmm at 2022/4/21 17:53 + * 保存指定数据集操作 + * 入参:{pageId, data:} + */ +public class DynPageSaveHandler extends AbstractDynPageHandler { + private Map> mapTreeBean = new HashMap<>(); + + protected void setNewId(DefaultEntity bean) { + bean.setEntityId(DbEngine.getInstance().nextId()); + } + + /** + * 保存指定数据集操作,入参:{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}} + */ + public R saveOne() { + //数据集 + String dbName = params.readString("dataset"); + SwMap filter = params.readMap("filter"); + //待保存数据 + SwMap data = params.readMap("data"); + if (data == null) throw new BizException("没有收到待保存的的数据:" + dbName + "!"); + //对应的数据集定义 + PageDataset pageDataSet = findDataset(dbName); + if (pageDataSet == null) throw new BizException("没有找到指定的的数据集定义:" + dbName + "!"); + //读取待保存的bean + DefaultEntity bean = readBeanFromPage(pageDataSet, data); + if (filter != null && bean.isNew()) {//有过滤条件,将关联的值设上 + setLinkValue(pageDataSet, bean, f -> filter.get(f.name)); + } + checkBean(bean); + + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + saveBean(bean); + } + + @Override + public void doAfterDbCommit() { + afterCommit(bean); + } + + @Override + public void doAfterDbRollback() { + afterRollback(bean); + } + }); + return R.success(DynRetBean.createBean(bean.getData())); + } + + /** + * 保存对象,所有数据集数据对象,{ ds1: {form:{},list:{total:0,rows:[]}}} + * + * @return + */ + public R saveAll() { + SwMap data = params.readMap("data"); + if (data == null) throw new BizException("没有收到待保存的的数据!"); + SwMap filter = params.readMap("filter"); + + Map map = new LinkedHashMap<>(); + for (PageDataset pageDataSet : datasets.list) { + //非表单编辑,不管 + if (!pageDataSet.canEdit || !SwEnum.DatasetType.FORM.value.equals(pageDataSet.type)) continue; + SwMap dsData = data.readMap(pageDataSet.name); + if (dsData == null) continue; + + //读取待保存的bean + DefaultEntity bean = readBeanFromPage(pageDataSet, dsData.readMap("form")); + map.put(pageDataSet.name, bean); + SwMap dsFilter = filter.readMap(pageDataSet.name); + if (dsFilter != null && bean.isNew()) {//有过滤条件,将关联的值设上 + setLinkValue(pageDataSet, bean, f -> { + //link类型,去取另一个dataset的值 + if (SwEnum.FilterType.LINK.value.equals(f.type)) { + DefaultEntity lv = map.get(f.linkDb); + if (lv != null) return lv.get(f.linkField); + } + return dsFilter.get(f.name); + }); + } + checkBean(bean); + } + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + for (DefaultEntity bean: map.values()) { + saveBean(bean); + } + } + + @Override + public void doAfterDbCommit() { + for (DefaultEntity bean: map.values()) { + afterCommit(bean); + } + } + + @Override + public void doAfterDbRollback() { + for (DefaultEntity bean: map.values()) { + afterRollback(bean); + } + } + }); + Map mapRet = new HashMap<>(map.size()); + for (Map.Entry entry: map.entrySet()) { + mapRet.put(entry.getKey(), DynRetBean.createBean(entry.getValue().getData())); + } + return R.success(mapRet); + } + + /** + * 从页面获取待保存的bean + * + * @param pageDataSet + * @param data + * @return + */ + protected DefaultEntity readBeanFromPage(PageDataset pageDataSet, SwMap data) { + ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable); + if (table == null) throw new BizException("没有找到待保存的表定义:" + pageDataSet.name); + long id = data.readLong(table.getIdField()); + + EntityDao dao = DbEngine.getInstance().findDao(table.getName()); + DefaultEntity bean; + if (id <= 0) { + bean = dao.createBean(); + bean.setIsNew(true); + setNewId(bean); + } else { + bean = dao.queryEntity(id); + if (bean == null) { + throw new BizException("没有找到待保存的记录:" + table.getName() + "." + id); + } + } + //暂时不考虑list保存的情况 + bean.getData().putAll(data); + return bean; + } + + /** + * 保存校验 + * + * @param bean + */ + protected void checkBean(DefaultEntity bean) { + ModelTable table = ModelTableCache.getInstance().getByName(bean.getTableName()); + for (ModelField field : table.getFields()) { + String value = bean.getStr(field.getName()); + //非空校验 + if (field.isNotNull() && StringUtils.isEmpty(value)) { + throw new BizException("字段不允许为空:" + field.getTitle()); + } + + //长度校验 + if (StringUtils.isNotEmpty(value)) { + int len = SwEnum.DataType.instance.getByValue(field.getDataType()).dataLength; + if (len > 0 && CommUtil.getStrLenB(value) > len) { + throw new BizException("字段值超长:" + field.getTitle()); + } + } + } + //唯一键校验 + EntityDao dao = DbEngine.getInstance().findDao(bean.getTableName()); + for (ModelIndex mi : table.getIndexes()) { + if (mi.isUnique()) { + dao.checkUnique(bean, mi.getFields().split(",")); + } + } + } + + protected void saveBean(DefaultEntity bean) { + final String tableName = bean.getTableName(); + EntityDao dao = DbEngine.getInstance().findDao(tableName); + if (bean.isNew()) { + dao.insertEntity(bean); + } else { + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); + if (field != null) bean.put(field.getName(), us.getUserId()); + + dao.updateEntity(bean); + if (table.getType() == SwEnum.TableType.TYPE_TREE.value) { + List listTreeBean = TreeHelper.getTreeHelper(tableName).resetTreeLevel(bean); + mapTreeBean.put(tableName, listTreeBean); + } + } + } + + protected void afterCommit(DefaultEntity bean) { + final String tableName = bean.getTableName(); + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + if (table.isNeedCache()) { + AbstractCache cache = CacheManager.getIntance().getCache(tableName); + List listTreeBean = mapTreeBean.get(tableName); + //树型表,父亲改变了,要多处理下缓存;还有个东东:级次码 + if (listTreeBean != null && !listTreeBean.isEmpty()) { + for (DefaultEntity b : listTreeBean) { + cache.put(b); + } + } else { + cache.put(bean); + } + } + } + + protected void afterRollback(DefaultEntity bean) { + final String tableName = bean.getTableName(); + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + if (table.isNeedCache()) { + AbstractCache cache = CacheManager.getIntance().getCache(tableName); + cache.reset(bean); + } + } + + //将关联的值设上 + protected void setLinkValue(PageDataset pageDataSet, DefaultEntity bean, IGetValue iGetValue) { + ModelTable table = ModelTableCache.getInstance().getByName(bean.getTableName()); + for (PageDatasetFilter f : pageDataSet.filters) { + String v = bean.getStr(f.field); + //有值,就不管 + if (v != null && !v.equals(table.findField(f.field).getDefaultValue())) continue; + + if (SwEnum.FilterType.CONST.value.equals(f.type)) {//常量 + bean.put(f.field, f.value); + } else if (SwEnum.FilterType.PARAM.value.equals(f.type)) {//参数 + bean.put(f.field, f.value); + } else if (SwEnum.FilterType.LINK.value.equals(f.type)) {//参数 + Object value = iGetValue.getValue(f); + if (value != null) { + bean.put(f.field, value); + } + } + } + } + + interface IGetValue { + Object getValue(PageDatasetFilter f); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageService.java new file mode 100644 index 0000000..3803864 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageService.java @@ -0,0 +1,70 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.annotation.SwBody; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.mvc.service.AbstractCompService; +import cc.smtweb.framework.core.mvc.service.AbstractHandler; +import cc.smtweb.framework.core.session.UserSession; + +/** + * Created by Akmm at 2022/4/21 17:43 + * 动态页面引擎 + */ +@SwService +public class DynPageService extends AbstractCompService { + + @Override + protected AbstractHandler createHandler(String type) { + switch (type) { + case TYPE_LOAD: + return new DynPageLoadHandler(); + case TYPE_SAVE: + return new DynPageSaveHandler(); + case TYPE_DEL: + return new DynPageDelHandler(); + } + return null; + } + + //新增 + public R add(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_LOAD, handler -> ((DynPageLoadHandler)handler).add()); + } + + //新增 + public R addOne(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_LOAD, handler -> ((DynPageLoadHandler)handler).addOne()); + } + + //加载 + public R loadOne(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_LOAD, handler -> ((DynPageLoadHandler)handler).loadOne()); + } + + //保存指定数据集 + public R saveOne(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_SAVE, handler -> ((DynPageSaveHandler)handler).saveOne()); + } + + //保存指定数据集 + public R save(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_SAVE, handler -> ((DynPageSaveHandler)handler).saveAll()); + } + + //删除指定数据集 + public R delOne(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_DEL, handler -> ((DynPageDelHandler)handler).delOne()); + } + + //删除数据 + public R del(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_DEL, handler -> ((DynPageDelHandler)handler).delAll()); + } + + //列表总记录数及合计栏 + public R total(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_LOAD, handler -> ((DynPageLoadHandler)handler).getTotal()); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynRetBean.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynRetBean.java new file mode 100644 index 0000000..4fd3159 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynRetBean.java @@ -0,0 +1,35 @@ +package cc.smtweb.system.bpm.web.engine.dynPage; + +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.mvc.service.SwListData; +import lombok.Data; + +/** + * Created by Akmm at 2022/4/21 19:26 + * 动态页面加载 + */ +@Data +public class DynRetBean { + //单个表单 + private SwMap form = null; + //列表返回 + private SwListData list = null; + + public static DynRetBean createBean(SwMap form) { + DynRetBean bean = new DynRetBean(); + bean.form = form; + return bean; + } + + public static DynRetBean createList(SwListData list) { + DynRetBean bean = new DynRetBean(); + bean.list = list; + return bean; + } +/* + public static DynRetBean createTree(SwListData list) { + DynRetBean bean = new DynRetBean(); + bean.list = list; + return bean; + }*/ +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java new file mode 100644 index 0000000..21c5b91 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java @@ -0,0 +1,65 @@ +package cc.smtweb.system.bpm.web.engine.flow; + +import cc.smtweb.system.bpm.web.design.flow.ModelProc; +import cc.smtweb.system.bpm.web.engine.flow.define.ProcinstEntity; +import cc.smtweb.system.bpm.web.engine.flow.define.TaskEntity; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by Akmm at 2020/3/4 11:35 + * 单据流程实例组件 + */ +public class FlowInstance { + //流程定义 + public ModelProc proc_def; + + //流程实例 + public ProcinstEntity proc_inst; + + //活动任务 + public TaskEntity act_inst; + + //操作类型 新增/编辑/查看 + public int opt_mode = 0;//CmEnum.OperatorType.VIEW; + + //流程执行变量 +// public Map variables = new HashMap<>(); + + public List> tasks = new ArrayList<>(); + + public FlowInstance() { +// this.context = context; + } + + //能否编辑 + public boolean canEdit() { +// return opt_mode == CmEnum.OperatorType.NEW || proc_inst.getstatu() == FlowConsts.InstanceStatu.BEGIN.value; + return false; + } + + public boolean notMakeCanEdit() { + /*Map mapPermisson = MenuHelper.getPermission(context); + boolean othCanEdit = BillFlowWfHelper.getPropBool(proc_def.getEntityId(), FlowConsts.NULL_STR, FlowConsts.ProcProperty.CAN_EDIT_OTHER); + ActivityEntity act = ActivityEntityBuffer.getInstance().get(act_inst.getActId()); + return act != null && !act_inst.isMake() && act.getActEdit() && othCanEdit && MenuHelper.hasPermisson(mapPermisson, CmEnum.MenuFuncRight.UPD.value);*/ + return false; + } + + public boolean isHandleMake() { +// ActivityEntity act = ActivityEntityBuffer.getInstance().get(act_inst.getActId()); +// return !act_inst.isMake() && isHandleMakeEx(act); + return false; + } + + + private boolean isHandleMakeEx(TaskEntity act) { +// if (EntityUtil.isNull(act)) return false; +// return BillFlowWfHelper.getPropInt(proc_inst.getProcDefId(), act.getActId(), FlowConsts.ProcProperty.HANDLER_RANGE) == CmEnum.HandlerRange.MAKE.value; + return false; + } + + +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java new file mode 100644 index 0000000..0b34f57 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java @@ -0,0 +1,15 @@ +package cc.smtweb.system.bpm.web.engine.flow; + +import cc.smtweb.framework.core.mvc.service.AbstractCompService; +import cc.smtweb.framework.core.mvc.service.AbstractHandler; + +/** + * Created by Akmm at 2022/5/24 14:21 + * 工作流 + */ +public class FlowService extends AbstractCompService { + @Override + protected AbstractHandler createHandler(String type) { + return null; + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CandidateEntity.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CandidateEntity.java new file mode 100644 index 0000000..ed03bf6 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CandidateEntity.java @@ -0,0 +1,57 @@ +package cc.smtweb.system.bpm.web.engine.flow.define; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by Akmm at 2022/5/23 14:25 + * 候选信息人 + */ +@SwTable("WF_CANDIDATE") +public class CandidateEntity extends DefaultEntity { + public static final String ENTITY_NAME = "WF_CANDIDATE"; + + public CandidateEntity() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("cnd_id"); + } + + public void setId(long cndId) { + put("cnd_id", cndId); + } + + public long getPriId() { + return getLong("cnd_pri_id"); + } + + public void setPriId(long cndPriId) { + put("cnd_pri_id", cndPriId); + } + + public long getTskId() { + return getLong("cnd_tsk_id"); + } + + public void setTskId(long cndTskId) { + put("cnd_tsk_id", cndTskId); + } + + public long getUserId() { + return getLong("cnd_user_id"); + } + + public void setUserId(long cndUserId) { + put("cnd_user_id", cndUserId); + } + + public int getIsSign() { + return getInt("cnd_is_sign"); + } + + public void setIsSign(int cndIsSign) { + put("cnd_is_sign", cndIsSign); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CareEntity.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CareEntity.java new file mode 100644 index 0000000..437a1bf --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CareEntity.java @@ -0,0 +1,49 @@ +package cc.smtweb.system.bpm.web.engine.flow.define; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by Akmm at 2022/5/23 14:25 + * 候选信息人 + */ +@SwTable("WF_CARE") +public class CareEntity extends DefaultEntity { + public static final String ENTITY_NAME = "WF_CARE"; + + public CareEntity() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("cr_id"); + } + + public void setId(long crId) { + put("cr_id", crId); + } + + public long getPriId() { + return getLong("cr_pri_id"); + } + + public void setPriId(long crPriId) { + put("cr_pri_id", crPriId); + } + + public long getUserId() { + return getLong("cr_user_id"); + } + + public void setUserId(long crUserId) { + put("cr_user_id", crUserId); + } + + public long getTime() { + return getLong("cr_time"); + } + + public void setTime(long crTime) { + put("cr_time", crTime); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CommentEntity.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CommentEntity.java new file mode 100644 index 0000000..b2670d7 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CommentEntity.java @@ -0,0 +1,65 @@ +package cc.smtweb.system.bpm.web.engine.flow.define; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by Akmm at 2022/5/23 14:25 + * 审批意见 + */ +@SwTable("WF_COMMENT") +public class CommentEntity extends DefaultEntity { + public static final String ENTITY_NAME = "WF_COMMENT"; + + public CommentEntity() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("cmt_id"); + } + + public void setId(long cmtId) { + put("cmt_id", cmtId); + } + + public long getPriId() { + return getLong("cmt_pri_id"); + } + + public void setPriId(long cmtPriId) { + put("cmt_pri_id", cmtPriId); + } + + public long getTskId() { + return getLong("cmt_tsk_id"); + } + + public void setTskId(long cmtTskId) { + put("cmt_tsk_id", cmtTskId); + } + + public long getUserId() { + return getLong("cmt_user_id"); + } + + public void setUserId(long cmtUserId) { + put("cmt_user_id", cmtUserId); + } + + public String getContent() { + return getStr("cmt_content"); + } + + public void setContent(String cmtContent) { + put("cmt_content", cmtContent); + } + + public long getTime() { + return getLong("cmt_time"); + } + + public void setTime(long cmtTime) { + put("cmt_time", cmtTime); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/ProcinstEntity.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/ProcinstEntity.java new file mode 100644 index 0000000..4080977 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/ProcinstEntity.java @@ -0,0 +1,129 @@ +package cc.smtweb.system.bpm.web.engine.flow.define; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by Akmm at 2022/5/23 14:25 + * 流程实例 + */ +@SwTable("WF_PROCINST") +public class ProcinstEntity extends DefaultEntity { + public static final String ENTITY_NAME = "WF_PROCINST"; + + public ProcinstEntity() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("pri_id"); + } + + public void setId(long priId) { + put("pri_id", priId); + } + + public String getBillCode() { + return getStr("pri_bill_code"); + } + + public void setBillCode(String priBillCode) { + put("pri_bill_code", priBillCode); + } + + public long getMakeDate() { + return getLong("pri_make_date"); + } + + public void setMakeDate(long priMakeDate) { + put("pri_make_date", priMakeDate); + } + + public int getBillType() { + return getInt("pri_bill_type"); + } + + public void setBillType(int priBillType) { + put("pri_bill_type", priBillType); + } + + public long getPartyId() { + return getLong("pri_party_id"); + } + + public void setPartyId(long priPartyId) { + put("pri_party_id", priPartyId); + } + + public long getDeptId() { + return getLong("pri_dept_id"); + } + + public void setDeptId(long priDeptId) { + put("pri_dept_id", priDeptId); + } + + public String getBillDesc() { + return getStr("pri_bill_desc"); + } + + public void setBillDesc(String priBillDesc) { + put("pri_bill_desc", priBillDesc); + } + + public long getPrcId() { + return getLong("pri_prc_id"); + } + + public void setPrcId(long priPrcId) { + put("pri_prc_id", priPrcId); + } + + public long getStartTime() { + return getLong("pri_start_time"); + } + + public void setStartTime(long priStartTime) { + put("pri_start_time", priStartTime); + } + + public long getEndTime() { + return getLong("pri_end_time"); + } + + public void setEndTime(long priEndTime) { + put("pri_end_time", priEndTime); + } + + public long getUserId() { + return getLong("pri_user_id"); + } + + public void setUserId(long priUserId) { + put("pri_user_id", priUserId); + } + + public long getTaskId() { + return getLong("pri_task_id"); + } + + public void setTaskId(long priTaskId) { + put("pri_task_id", priTaskId); + } + + public int getStatu() { + return getInt("pri_statu"); + } + + public void setStatu(int priStatu) { + put("pri_statu", priStatu); + } + + public String getBillInfo() { + return getStr("pri_bill_info"); + } + + public void setBillInfo(String priBillInfo) { + put("pri_bill_info", priBillInfo); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/SignEntity.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/SignEntity.java new file mode 100644 index 0000000..4693005 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/SignEntity.java @@ -0,0 +1,74 @@ +package cc.smtweb.system.bpm.web.engine.flow.define; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by Akmm at 2022/5/23 14:25 + * 会签信息 + */ +@SwTable("WF_SIGN") +public class SignEntity extends DefaultEntity { + public static final String ENTITY_NAME = "WF_SIGN"; + + public SignEntity() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("sgn_id"); + } + + public void setId(long sgnId) { + put("sgn_id", sgnId); + } + + public long getPriId() { + return getLong("sgn_pri_id"); + } + + public void setPriId(long sgnPriId) { + put("sgn_pri_id", sgnPriId); + } + + public long getTskId() { + return getLong("sgn_tsk_id"); + } + + public void setTskId(long sgnTskId) { + put("sgn_tsk_id", sgnTskId); + } + + public long getUserId() { + return getLong("sgn_user_id"); + } + + public void setUserId(long sgnUserId) { + put("sgn_user_id", sgnUserId); + } + + public int getAgree() { + return getInt("sgn_agree"); + } + + public void setAgree(int sgnAgree) { + put("sgn_agree", sgnAgree); + } + + public String getContent() { + return getStr("sgn_content"); + } + + public void setContent(String sgnContent) { + put("sgn_content", sgnContent); + } + + public long getTime() { + return getLong("sgn_time"); + } + + public void setTime(long sgnTime) { + put("sgn_time", sgnTime); + } + +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java new file mode 100644 index 0000000..d21dcab --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java @@ -0,0 +1,161 @@ +package cc.smtweb.system.bpm.web.engine.flow.define; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by Akmm at 2022/5/23 14:25 + * 活动实例 + */ +@SwTable("WF_TASK") +public class TaskEntity extends DefaultEntity { + public static final String ENTITY_NAME = "WF_TASK"; + + public TaskEntity() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("tsk_id"); + } + + public void setId(long tskId) { + put("tsk_id", tskId); + } + + public long getPriId() { + return getLong("tsk_pri_id"); + } + + public void setPriId(long tskPriId) { + put("tsk_pri_id", tskPriId); + } + + public long getPrcId() { + return getLong("tsk_prc_id"); + } + + public void setPrcId(long tskPrcId) { + put("tsk_prc_id", tskPrcId); + } + + public String getActId() { + return getStr("tsk_act_id"); + } + + public void setActId(String tskActId) { + put("tsk_act_id", tskActId); + } + + public String getActName() { + return getStr("tsk_act_name"); + } + + public void setActName(String tskActName) { + put("tsk_act_name", tskActName); + } + + public long getHandler() { + return getLong("tsk_handler"); + } + + public void setHandler(long tskHandler) { + put("tsk_handler", tskHandler); + } + + public long getStartTime() { + return getLong("tsk_start_time"); + } + + public void setStartTime(long tskStartTime) { + put("tsk_start_time", tskStartTime); + } + + public long getEndTime() { + return getLong("tsk_end_time"); + } + + public void setEndTime(long tskEndTime) { + put("tsk_end_time", tskEndTime); + } + + public int getStatu() { + return getInt("tsk_statu"); + } + + public void setStatu(int tskStatu) { + put("tsk_statu", tskStatu); + } + + public String getSubmitIdea() { + return getStr("tsk_submit_idea"); + } + + public void setSubmitIdea(String tskSubmitIdea) { + put("tsk_submit_idea", tskSubmitIdea); + } + + public boolean isMake() { + return getBool("tsk_is_make"); + } + + public void setMake(boolean tskIsMake) { + setBool("tsk_is_make", tskIsMake); + } + + public boolean isSign() { + return getBool("tsk_is_sign"); + } + + public void setSign(boolean tskIsSign) { + setBool("tsk_is_sign", tskIsSign); + } + + public String getSignTotal() { + return getStr("tsk_sign_total"); + } + + public void setSignTotal(String tskSignTotal) { + put("tsk_sign_total", tskSignTotal); + } + + public int getSignPass() { + return getInt("tsk_sign_pass"); + } + + public void setSignPass(int tskSignPass) { + put("tsk_sign_pass", tskSignPass); + } + + public int getSignAgree() { + return getInt("tsk_sign_agree"); + } + + public void setSignAgree(int tskSignAgree) { + put("tsk_sign_agree", tskSignAgree); + } + + public boolean getIsReject() { + return getBool("tsk_is_reject"); + } + + public void setReject(boolean tskIsReject) { + setBool("tsk_is_reject", tskIsReject); + } + + public boolean isRetake() { + return getBool("tsk_is_retake"); + } + + public void setIsRetake(boolean tskIsRetake) { + setBool("tsk_is_retake", tskIsRetake); + } + + public boolean isAuto() { + return getBool("tsk_is_auto"); + } + + public void setIsAuto(boolean tskIsAuto) { + setBool("tsk_is_auto", tskIsAuto); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskRelEntity.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskRelEntity.java new file mode 100644 index 0000000..d06feab --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskRelEntity.java @@ -0,0 +1,49 @@ +package cc.smtweb.system.bpm.web.engine.flow.define; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by Akmm at 2022/5/23 14:25 + * 活动之间的关系 + */ +@SwTable("WF_CARE") +public class TaskRelEntity extends DefaultEntity { + public static final String ENTITY_NAME = "WF_CARE"; + + public TaskRelEntity() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("trl_id"); + } + + public void setId(long trlId) { + put("trl_id", trlId); + } + + public long getPriId() { + return getLong("trl_pri_id"); + } + + public void setPriId(long trlPriId) { + put("trl_pri_id", trlPriId); + } + + public long getSrcTaskId() { + return getLong("trl_src_task_id"); + } + + public void setSrcTaskId(long trlSrcTaskId) { + put("trl_src_task_id", trlSrcTaskId); + } + + public long getDstTaskId() { + return getLong("trl_dst_task_id"); + } + + public void setDstTaskId(long trlDstTaskId) { + put("trl_dst_task_id", trlDstTaskId); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/AuthService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/AuthService.java new file mode 100644 index 0000000..ab05c4f --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/AuthService.java @@ -0,0 +1,86 @@ +package cc.smtweb.system.bpm.web.login; + +import cc.smtweb.framework.core.annotation.*; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.session.SessionManager; +import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.framework.core.db.DbEngine; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; + +@Slf4j +@SwService +public class AuthService { + @SwParam + private DbEngine dbEngine; + + @SwParam + private SessionManager sessionManager; + + @SwPerm(SwPerm.NONE) + public R login(@SwBody LoginVO loginPO) { + /*if (StringUtils.isBlank(loginPO.getUsername())) { + return R.error("账号不能为空"); + } + + if (StringUtils.isBlank(loginPO.getPassword())) { + return R.error("密码不能为空"); + } + + UserPO user = dbEngine.queryEntity("select user_id,user_nick_name,user_nick_code,user_pwd,user_create_party_id from sw_user.sys_user where user_nick_code=?", UserPO.class, loginPO.getUsername()); + + if (user == null) { + return R.error("账号不存在"); + } + + // digest:md5("goodpj" + user.userId + password) + String pass = DigestUtils.md5Hex("goodpj" + user.getUserId() + loginPO.getPassword()); + + if (!pass.equals(user.getUserPwd())) { + return R.error("账号或者密码出错"); + }*/ + + UserSession userSession = new UserSession(); + userSession.setUserId(1); + userSession.setSiteId(1); + + String token = sessionManager.login(userSession); + + LoginAckVO data = new LoginAckVO(); + + data.setUserId(1L); + data.setUserName("管理员"); + data.setUserAvatar(""); + data.setToken(token); + + return R.success(data); + } + + @SwPerm() + public R ping(@SwParam("msg") String msg) { + return R.success(msg); + } + + @SwPerm("user:edit") + public R config(@SwParam("username") String username) { + return R.success("config: " + username); + } + + + /** + * 退出登录 + * @return code + */ + public R logout() { + sessionManager.logout(); + return R.success(); + } + + // defaultRun 命名的函数是默认函数 +// @SwPerm(SwPerm.NONE) +// public R defaultRun(@SwPathParam String path) { +// return R.success(path).put("dao", authDao); +// } + +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginAckVO.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginAckVO.java new file mode 100644 index 0000000..00f8734 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginAckVO.java @@ -0,0 +1,11 @@ +package cc.smtweb.system.bpm.web.login; + +import lombok.Data; + +@Data +public class LoginAckVO { + private Long userId; + private String userAvatar; + private String userName; + private String token; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginVO.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginVO.java new file mode 100644 index 0000000..ad841f9 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginVO.java @@ -0,0 +1,12 @@ +package cc.smtweb.system.bpm.web.login; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class LoginVO implements Serializable { + private String username; + + private String password; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/MenuPO.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/MenuPO.java new file mode 100644 index 0000000..933b334 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/MenuPO.java @@ -0,0 +1,29 @@ +package cc.smtweb.system.bpm.web.login; + +import cc.smtweb.framework.core.annotation.SwColumn; +import cc.smtweb.framework.core.annotation.SwTable; +import lombok.Data; + +import java.io.Serializable; + +@Data +@SwTable("sw_user.sys_menu") +public class MenuPO implements Serializable { + @SwColumn(type={SwColumn.Type.ID}) + private Long menuId; + + @SwColumn(type={SwColumn.Type.PARENT_ID}) + private Long menuParentId; + + private String menuName; + + private Long menuSiteId; + + + private String menuPermiss; + + private String menuUrl; + + @SwColumn(type={SwColumn.Type.ORDER}) + private Integer menuSort; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/UserPO.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/UserPO.java new file mode 100644 index 0000000..af5c679 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/login/UserPO.java @@ -0,0 +1,28 @@ +package cc.smtweb.system.bpm.web.login; + +import cc.smtweb.framework.core.annotation.SwColumn; +import cc.smtweb.framework.core.annotation.SwTable; +import lombok.Data; + +import java.io.Serializable; + +@Data +@SwTable("sw_user.sys_user") +public class UserPO implements Serializable { + @SwColumn(type={SwColumn.Type.ID}) + private Long userId; + + private String userNickCode; + + private String userNickName; + + private Long userCreatePartyId; + + private String userPwd; + + private String userPhone; + + private Integer userStatus; + + private String userAvatar; +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/Area.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/Area.java new file mode 100644 index 0000000..484fbd3 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/Area.java @@ -0,0 +1,109 @@ +package cc.smtweb.system.bpm.web.sys.user.area; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by 1 at 2022-06-17 07:58:14 + * 实体【[行政区划](SYS_AREA)】的Entity类 + */ +@SwTable("SYS_AREA") +public class Area extends DefaultEntity { + public static final String ENTITY_NAME = "SYS_AREA"; + + public Area() { + super(ENTITY_NAME); + } + + /** 主键 */ + public long getId() { + return getLong("ar_id"); + } + + /** 主键 */ + public void setId(long ar_id) { + put("ar_id", ar_id); + } + /** 编码 */ + public String getCode() { + return getStr("ar_code"); + } + + /** 编码 */ + public void setCode(String ar_code) { + put("ar_code", ar_code); + } + /** 名称 */ + public String getName() { + return getStr("ar_name"); + } + + /** 名称 */ + public void setName(String ar_name) { + put("ar_name", ar_name); + } + /** 父ID */ + public long getParentId() { + return getLong("ar_parent_id"); + } + + /** 父ID */ + public void setParentId(long ar_parent_id) { + put("ar_parent_id", ar_parent_id); + } + /** 级次码 */ + public String getLevelCode() { + return getStr("ar_level_code"); + } + + /** 级次码 */ + public void setLevelCode(String ar_level_code) { + put("ar_level_code", ar_level_code); + } + /** 全称 */ + public String getFullName() { + return getStr("ar_full_name"); + } + + /** 全称 */ + public void setFullName(String ar_full_name) { + put("ar_full_name", ar_full_name); + } + /** 级次 */ + public int getType() { + return getInt("ar_type"); + } + + /** 级次 */ + public void setType(int ar_type) { + put("ar_type", ar_type); + } + /** 状态 */ + public boolean isStatu() { + return getBool("ar_statu"); + } + + /** 状态 */ + public void set(boolean ar_statu) { + setBool("ar_statu", ar_statu); + } + /** 备注 */ + public String getRemark() { + return getStr("ar_remark"); + } + + /** 备注 */ + public void setRemark(String ar_remark) { + put("ar_remark", ar_remark); + } + /** 排序码 */ + public int getSeq() { + return getInt("ar_seq"); + } + + /** 排序码 */ + public void setSeq(int ar_seq) { + put("ar_seq", ar_seq); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaCache.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaCache.java new file mode 100644 index 0000000..ec000b5 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaCache.java @@ -0,0 +1,42 @@ +package cc.smtweb.system.bpm.web.sys.user.area; + +import cc.smtweb.framework.core.annotation.SwCache; +import cc.smtweb.framework.core.cache.AbstractEntityCache; +import cc.smtweb.framework.core.cache.CacheManager; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +/** + * Created by 1 at 2022-06-17 07:58:14 + * 实体【[行政区划](SYS_AREA)】的缓存类 + */ +@SwCache(ident = "SYS_AREA", title = "行政区划") +public class AreaCache extends AbstractEntityCache { + //缓存key:按父ID + public final static String mk_pr = "pr"; + //缓存key:按编码 + public final static String mk_code = "code"; + + public static AreaCache getInstance() { + return CacheManager.getIntance().getCache(AreaCache.class); + } + + public AreaCache() { + //缓存key:按父ID + regList(mk_pr, "ar_parent_id"); + //缓存key:按编码 + regList(mk_code, "ar_code"); + } + + //缓存key:按父ID + public final Set getByPr(String key) { + return getListByKey(mk_pr, key); + } + //缓存key:按编码 + public final Set getByCode(String key) { + return getListByKey(mk_code, key); + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaHandler.java new file mode 100644 index 0000000..42cee9b --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaHandler.java @@ -0,0 +1,35 @@ +package cc.smtweb.system.bpm.web.sys.user.area; + +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.system.bpm.web.design.form.define.PageDataset; +import cc.smtweb.system.bpm.web.engine.dynPage.DynPageLoadHandler; +import cc.smtweb.system.bpm.web.engine.dynPage.DynPageSaveHandler; + +/** + * Created by Akmm at 2022/7/1 15:47 + * 区划保存 + */ +public class AreaHandler { + static class AreaSaveHandler extends DynPageSaveHandler { + @Override + protected void setNewId(DefaultEntity bean) { + if (bean instanceof Area) { + Area area = (Area) bean; + area.setEntityId(Long.parseLong(area.getCode())); + } else { + super.setNewId(bean); + } + } + } + + static class AreaLoadHandler extends DynPageLoadHandler { + @Override + protected void afterAddBean(PageDataset dataset, SwMap bean) { + super.afterAddBean(dataset, bean); + Area area = new Area(); + area.setData(bean); +// area.setSeq(); + } + } +} diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaService.java new file mode 100644 index 0000000..7d724b7 --- /dev/null +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaService.java @@ -0,0 +1,39 @@ +package cc.smtweb.system.bpm.web.sys.user.area; + +import cc.smtweb.framework.core.annotation.SwBody; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.system.bpm.web.engine.dynPage.DynPageDelHandler; +import cc.smtweb.system.bpm.web.engine.dynPage.DynPageLoadHandler; +import cc.smtweb.system.bpm.web.engine.dynPage.DynPageSaveHandler; +import cc.smtweb.system.bpm.web.engine.dynPage.DynPageService; +import cc.smtweb.framework.core.mvc.service.AbstractHandler; +import cc.smtweb.framework.core.session.UserSession; + +/** + * Created by 1 at 2022-06-17 07:58:14 + * 页面【[区划卡片]的服务类 + */ +@SwService +public class AreaService extends DynPageService { + //public final static String TYPE_DEMO = "demo"; + @Override + protected AbstractHandler createHandler(String type) { + switch (type) { + case TYPE_SAVE: + return new AreaHandler.AreaSaveHandler(); + case TYPE_LOAD: + return new AreaHandler.AreaLoadHandler(); + } + return super.createHandler(type); + } + +/* demo + //自定义 + public R demo(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_DEMO, handler -> ((DemoHandler)handler).demo()); + } +*/ + +} diff --git a/smtweb-framework/bpm/src/main/resources/META-INF/spring.factories b/smtweb-framework/bpm/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..86f1fdb --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cc.smtweb.system.bpm.spring.BpmAutoConfiguration diff --git a/smtweb-framework/bpm/src/main/resources/codegen/ts/dataset.ts b/smtweb-framework/bpm/src/main/resources/codegen/ts/dataset.ts new file mode 100644 index 0000000..45ed53b --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/ts/dataset.ts @@ -0,0 +1,730 @@ +import {onMounted, watch} from 'vue'; +import {RouteLocationNormalizedLoaded, useRoute} from 'vue-router'; +import Schema, {ErrorList, FieldErrorList} from 'async-validator'; +import api from '/@/api'; +import commonUtil from '/@/utils/commonUtil'; +import {confirm, notify} from '/@/utils/message'; +import {IPageParams} from './page.types'; +import {tabRouter} from '/@/pages/layout/tab/useTab'; + +interface IDatasetEvent { + action: string + dataset: any + row: any +} + +export class PageDataset { + private params: IPageParams; + readonly data: any; + readonly page: any; + private eventHandle?: Function; + + constructor(route: RouteLocationNormalizedLoaded, data: any, page: any) { + // title: this.$route.query.title, + // 页面参数 + + this.params = { + pageId: route.params.pageI || page.id, + id: route.params.id as string, + parentId: route.params.parentId as string, + }; + + this.data = data; + this.page = page; + // 混入的主页面需要提供 page 和 data + } + + setEventHandle(eventHandle: Function) { + this.eventHandle = eventHandle; + } + + // 通过dataset对象读取数据 + async loadDataset(dataset: any, row?: any, params?: any, callFn?: Function) { + if (row && dataset.masterFields) { + // 处理子表过滤条件 + const filter = []; + + for (const mapField of dataset.masterFields) { + filter.push({ field: mapField.slave, keyword: row[mapField.master] }); + } + + dataset.filter = filter; + } + + switch (dataset.listModel) { + case 1: + await this.loadList(dataset.name, params, callFn); + break; + case 2: + await this.loadTree(dataset.name, params, callFn); + break; + default: + await this.loadCard(dataset.name, params, callFn); + break; + } + } + + // async searchList() { + // // 点击搜索按钮 + // if (this.getMainDatasetId()) { + // await this.loadList(this.getMainDatasetId(), 0); + // } + // } + // + // async resetList() { + // // 重置按钮 + // if (this.getMainDatasetId()) { + // const dataset = this.getDatasetById(this.getMainDatasetId()); + // // this.$set(dataset, 'form', {}); + // dataset.form = {}; + // await this.loadList(this.getMainDatasetId(), 0); + // } + // } + // + // getMainDatasetId(): string | null { + // const { datasets } = this.page; + // if (datasets && datasets.length > 0) { + // return datasets[0].id; + // } + // return null; + // } + + findDatasetMeta(datasetName: string): any { + return this.page.datasets[datasetName]; + // 得到 datasets + // return this.page.datasets.find((e: any) => e.id === datasetId || e.name === datasetId); + // return Object.values(this.page.datasets).find((dataset: any) => { + // return dataset.id === datasetId || dataset.name === datasetId; + // }); + } + + // async loadDatasetById(datasetId: string) { + // await this.loadDataset(this.findDataset(datasetId)); + // } + + async loadDatasetByName(name: string, params?: any, callFn?: Function) { + await this.loadDataset(this.page.datasets[name], null, params, callFn); + } + + async doApi(name: string, params: any): Promise { + const dataset = this.findDatasetMeta(params.dataset); + let url = null; + if (dataset && dataset.apis) { + url = dataset.apis[name]; + } + + if (!url) { + switch (name) { + case 'cardGet': + url = 'bpm/DynFormCard/load'; + break; + case 'cardSave': + url = 'bpm/DynFormCard/save'; + break; + case 'cardDel': + url = 'bpm/DynFormCard/remove'; + break; + case 'listGet': + url = 'bpm/DynFormList/list'; + break; + case 'listCount': + url = 'bpm/DynFormList/count'; + break; + case 'treeAll': + url = 'bpm/DynFormTree/treeAll'; + break; + case 'treeGet': + url = 'bpm/DynFormTree/tree'; + break; + case 'treeMove': + url = 'bpm/DynFormTree/move'; + break; + } + } + if (url) { + return await api.post(url, params); + // return await api.post(url, params); + } + + return {}; + } + + // async doCustomApi(apiName: string, params: any, callFn: Function) { + // // 执行自定义的API + // const re = await api.post(apiName, params); + // if (callFn) { + // callFn(re); + // } + // } + + async loadCard(datasetName: string, params: any, callFn?: Function) { + const ds = this.loadDatasetData(datasetName); + console.log('loadCard= ', this.params.id, ds); + if (this.params.id) { + // 查询一条数据 + const { data } = await this.doApi('cardGet', { + pageId: this.page.id, + dataset: datasetName, + id: this.params.id, + filter: ds.filter, + }); + + if (data) { + ds.form = data; + + this.scrollDataset(datasetName, data); + } + + if (callFn) { + callFn(data); + } + } + } + + loadDatasetData(datasetName: string | null): any { + if (datasetName) { + return this.data[datasetName]; + } + + return null; + } + + async loadList(datasetName: string | null, pageIndex: number, callFn?: Function) { + const ds = this.loadDatasetData(datasetName); + + if (!ds) { + console.error(`not find dataset name: ${datasetName}`); + return; + } + + const params = { + pageId: this.page.id, + parentId: this.params.parentId, + dataset: datasetName, + pageIndex, + pageSize: ds.list.pageSize, + filter: ds.list.filter, + // search: ds.list.search || [], + // searchType: ds.list.searchType, + // params: { ...(ds.form || {}), ..._search }, + }; + + ds.list.loading = true; + const { data } = await this.doApi('listGet', params); + ds.list.loading = false; + + if (data) { + ds.list.data = data.rows; + + // console.log(this.data, data.rows.length); + + if (ds.list.total < 0) { // 不需要每次都查询条数和统计 + try { + // 更新总数 + if (data.total < 0) { + // 异步加载数据总数和统计数据 + const retCount = await this.doApi('listCount', params); + if (retCount.data) { + ds.list.total = retCount.data.total / 1; // (sql条数是java long类型) + ds.list.summary = retCount.data; + } + } else { + ds.list.total = data.total; + } + } catch (e) { + console.log('e', e); + } + } + + this.scrollDataset(datasetName!); + } + + if (callFn) { + callFn(data); + } + } + + async loadTree(datasetName: string, params = {}, callFn?: Function) { + // 加载树数据 + const ds = this.loadDatasetData(datasetName); + + ds.list.loading = true; + const ret = await this.doApi('treeAll', { + ...params, + pageId: this.page.id, + dataset: datasetName, + }); + ds.list.loading = false; + if (ret.data) { + ds.list.data = ret.data || []; + this.scrollDataset(datasetName, null); + if (callFn) { + callFn(); + } + } + } + + scrollDataset(datasetName: string, row?: any) { + // 加载从表数据 + Object.values(this.page.datasets).forEach((dataset: any) => { + if (dataset && dataset.tableType === 2 && dataset.master === datasetName) { + if (row) { + this.loadDataset(dataset, row); + } else { + // 直接清空 + this.scrollDataset(dataset.id, null); + const slaveData = this.loadDatasetData(dataset.name); + slaveData.list.data.length = 0; + } + } + }); + + this.doEvent({ action: 'afterScroll', dataset: datasetName, row }); + } + + _removeItem(listData: any, id: string, _mainField: string) { + if (!_mainField) { + _mainField = 'id'; // 对比的键 + } + for (let i = 0; i < listData.length; i++) { + const child = listData[i]; + if (child[_mainField] === id) { + listData.splice(i, 1); + return true; + } + + if (child.children) { + if (this._removeItem(child.children, id, _mainField)) { + return true; + } + } + } + + return false; + } + + _doSave(datasetName: string, formData: any, callFn: Function) { + this.doApi('cardSave', { + ...formData, + pageId: this.page.id, + id: this.params.id, + parentId: this.params.parentId, + dataset: datasetName, + }).then((ret) => { + this.params.id = ret.data; + notify.success('操作成功'); + if (callFn) { + callFn(ret); + } + }); + } + + onSubmit(datasetName: string, isReturn = false) { + if (datasetName) { + const ds = this.loadDatasetData(datasetName); + const formData = ds.form; + formData.parentId = this.params.parentId; + const dataset = this.findDatasetMeta(datasetName); + console.log('onSubmit', formData, dataset); + + if (dataset && dataset.rules && !commonUtil.isEmptyObj(dataset.rules)) { + const validator = new Schema(dataset.rules); + validator.validate(formData, {}, (errors: ErrorList, fields: FieldErrorList) => { + if (errors) { + // validation failed, errors is an array of all errors + // fields is an object keyed by field name with an array of + // errors per field + console.log(errors, fields); + notify.error('验证失败'); + } else { + this._doSave(datasetName, formData, () => { + if (isReturn) { + this.goBack(); + } + }); + } + // validation passed + }); + } else { + if (!this.customValidator(datasetName)) { + return; + } + this._doSave(datasetName, formData, () => { + if (isReturn) { + this.goBack(); + } + }); + } + } + } + + customValidator(datasetName: string) { + // 验证成功 返回 true 失败 返回 false + // 自定义 输入 验证 + const ds = this.loadDatasetData(datasetName); + if (ds) { + const formData = ds.form || {}; + let _b = true; + console.log('customValidator', formData); + if (this.page && this.page.widgets) { + const { widgets = {} } = this.page; + // 验证必填 (只验证是否有值,不能格式) + Object.values(widgets).forEach((_widget: any) => { + if (_widget.dataset === datasetName && _widget.required) { + const _name = _widget.name || _widget.field; + if (!commonUtil.isEmpty(_name)) { + if (commonUtil.isEmpty(formData[_name])) { + _b = false; + _widget.showError = true; + } else { + _widget.showError = false; + } + } + } + }); + } + return _b; + } + return false; + } + + goBack() { + // 返回上一页面 + tabRouter.back(); + // router.back(); + } + + getIdFieldByDataset(datasetName: string) { + // 得到 dataset 的ID属性值 + if (this.page && this.page.datasets && this.page.datasets[datasetName]) { + return this.page.datasets[datasetName].idField; + } + return null; + } + + // 生成查询条件用于向后台提交参数 + _buildSearch(datasetId: string, ds: any): Array { + // 用户输入的搜索条件 + const result: any[] = []; + + const { widgets } = this.page; + + Object.keys(this.page.widgets).forEach((key) => { + const widget = widgets[key]; + if (widget.dataset === datasetId && widget.field && widget.filterType) { + const keyword = ds.form[widget.field]; + if (keyword) { + result.push({ field: widget.field, keyword, op: widget.filterType }); + } + } + }); + + // const _search = {}; + // if (ds.list.search && ds.list.search.length > 0) { + // for (const _obj of ds.list.search) { + // if (_obj.field) { + // _search[_obj.field] = _obj.keyword; + // } + // } + // } + + return result; + } + + // 界面按钮产生的数据集动作 + async onWidgetAction(datasetName: string, params: any) { + const ds = this.loadDatasetData(datasetName); + const dsMeta = this.findDatasetMeta(datasetName); + // 得到主键值 + if (params.row && dsMeta && dsMeta.idField) { + params.id = params.row[dsMeta.idField]; + // params.mainField = _mainField; + } + + console.log('onWidgetAction', params, ds); + + if (params.link) { + const routeName = this.page.ref.routes[`id_${params.link}`]; + + if (routeName) { + const query = { + // pageId: params.link, + action: params.action, + } as any; + + switch (params.action) { + case 'button:add': + query.parentId = this.params.parentId; + // query.dataParentId = params.parentId; + break; + case 'button:edit': + // query.parentId = params.id || ''; + query.id = params.id; + // row = JSON.stringify(params.row || {}), + break; + } + await tabRouter.push(routeName, query); + // await router.push({ name: routeName, params: query }); + // } else { + // await router.push({ + // path: `/form/${params.link}`, + // query: { parentId: this.params.id }, + // }); + } else { + console.error(`not find link page by id ${params.link}`); + } + } else { + switch (params.action) { + case 'list:page': // list控件事件 + if (params.reset) { + ds.list.total = -1; + } + ds.list.pageSize = params.pageSize; + + await this.loadList(datasetName, params.pageIndex); + break; + case 'list:filter': // list控件事件,快速查询 + ds.list.total = -1; + ds.list.search = params.search; + ds.list.searchType = params.searchType; + ds.list.pageSize = params.pageSize; + + await this.loadList(datasetName, 0); + break; + case 'button:search': // 搜索按钮 + ds.list.total = -1; + ds.list.filter = this._buildSearch(datasetName, ds); + ds.list.pageSize = params.pageSize; + + await this.loadList(datasetName, 0); + break; + case 'button:return': + this.goBack(); + break; + case 'button:add': + // this._load({pageId: params.link, dataParentId: params.parentId, filter: ds.filter}); + // 弹出新页面 + // this.$router.push({ path: '/form/' + params.link, query: { dataParentId: params.parentId, filter: ds.filter }}); + // 替换当前新页面,path需要相同 + + // router.push({ + // path: `/form/${this.page.id}`, + // query: { + // pageId: params.link, + // parentId: this.params.parentId, + // dataParentId: params.parentId, + // filter: ds.filter, + // // title: this.title, + // }, + // }); + notify.warning('未配置链接页面'); + break; + case 'button:edit': + // this._load({pageId: params.link, id: params.id}); + // 替换当前新页面,path需要相同 + // router.push({ + // path: `/form/${this.page.id}`, + // query: { + // pageId: params.link, + // parentId: params.parentId, + // id: params.id, + // filter: ds.filter, + // // title: this.title, + // row: JSON.stringify(params.row || {}), + // }, + // }); + break; + case 'button:save': + this.onSubmit(datasetName, false); + break; + case 'button:saveAndReturn': + this.onSubmit(datasetName, true); + break; + case 'button:submit': { + const { isReturn } = params; + this.onSubmit(datasetName, isReturn); + } + break; + case 'button:remove': + // 删除一条数据 + this.onWidgetActionRemove('此操作将删除当前记录, 是否继续?', datasetName, [params.id], { + mainField: params.mainField || 'id', + }); + break; + case 'button:batchRemove': + if (params.sels && params.sels.length > 0) { + const ids = []; + + for (const item of params.sels) { + ids.push(item.id); + } + + this.onWidgetActionRemove(`此操作将删除选中的 "${ids.length}" 条记录, 是否继续?`, datasetName, ids); + } + break; + case 'button:move': + await this.doApi('treeMove', { + pageId: this.page.id, + dataset: datasetName, + id: params.id, + parentId: params.parentId, + dataOrders: params.orders, + }); + break; + case 'list:selected': + this.scrollDataset(datasetName, params.row); + break; + case 'tree:loadTreeAll': + await this.loadTree(params.dataset); + break; + // case 'event': { + // const { events, name, eventName } = params; + // params.datasetId = datasetId; + // if ((events && events.click) || name) { + // let _funName = null; + // if (events && events.click) { + // _funName = events.click; + // } else if (name || eventName) { + // _funName = eventName || name; + // } + // if (_funName && this[_funName]) { + // this[_funName](params); + // console.info(`call [${_funName}] function success`); + // } else { + // console.error(`dataset not found [${_funName}] function`); + // } + // } + // } + // break; + default: + console.log('unknown action', params); + break; + } + } + } + + onWidgetActionRemove(title: string, datasetName: string, ids: Array, otherArgsObj?: any, callFn?: Function) { + // console.log('onWidgetActionRemove', ids, ids.join()); + + confirm('删除确认', () => { + (async() => { + const ret = await this.doApi('cardDel', { + pageId: this.page.id, + dataset: datasetName, + ids: ids.join(), + }); + if (ret && (ret.data || ret.isSuccess)) { + const listData = this.loadDatasetData(datasetName).list.data; + let _mainField = null; + + if (otherArgsObj) { + _mainField = otherArgsObj.mainField; + } else { + _mainField = this.getIdFieldByDataset(datasetName); + } + + for (const id of ids) { + this._removeItem(listData, id, _mainField); + } + + callFn && callFn(); + notify.success('删除成功'); + } else { + notify.error('删除失败'); + } + })(); + }); + } + + // 处理事件 + doEvent(evtValue: IDatasetEvent) { + if (this.eventHandle) { + this.eventHandle(evtValue); + } + } + + getWidgetByName(name: string) { + if (this.page.widgets && name) { + Object.values(this.page.widgets).find((value: any) => { return value.name === name; }); + // for (const _key in this.page.widgets) { + // if (this.page.widgets[_key].name === name) { + // return this.page.widgets[_key]; + // } + // } + } + return null; + } + + updateData(params: any = {}) { + // 根据列表组件 更新 row 字段值 + const { dataset, id, fieldName, value } = params; + const ds = this.loadDatasetData(dataset); + const idField = this.getIdFieldByDataset(dataset); + if (ds && idField) { + const data = ds.list.data; + for (const _obj of data) { + if (_obj[idField] === id) { + _obj[fieldName] = value; + break; + } + } + } + } + + async init(loadLookup: boolean) { + const values = Object.values(this.page.datasets) as any[]; + + if (loadLookup) { + for (const dataset of values) { + if (dataset.tableType === 3) { + await this.loadDataset(dataset); + } + } + } + + for (const dataset of values) { + if (dataset.tableType === 1) { + await this.loadDataset(dataset); + } + } + // Object.values(this.page.datasets).forEach((dataset: any) => { + // if (dataset.tableType === 1 || dataset.tableType === 3) { // master/lookup + // this.loadDataset(dataset); + // } + // }); + } + + update(route: RouteLocationNormalizedLoaded) { + // title: this.$route.query.title, + // 页面参数 + const id = route.params.id as string; + + if (id !== this.params.id) { + this.params.id = id; + this.params.parentId = route.params.parentId as string; + this.init(false); + } + } +} + +export const useDataset = (props: any, data: any, page: any) => { + // console.log('useDataset', route.params); + const route = useRoute(); + + const pageDataset = new PageDataset(route, data, page); + + onMounted(() => { + pageDataset.init(true); + }); + + watch(() => props.id, () => { + pageDataset.update(route); + // console.log('watch', val, route.params); + }); + + // watch('$route.params.id', (val: any) => { + // console.log(page.id, val); + // }); + + return pageDataset; +}; diff --git a/smtweb-framework/bpm/src/main/resources/codegen/ts/events.ts b/smtweb-framework/bpm/src/main/resources/codegen/ts/events.ts new file mode 100644 index 0000000..c9bff89 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/ts/events.ts @@ -0,0 +1,13 @@ +import {PageDataset} from './dataset'; + +export class PageEvents { + private dataset: PageDataset; + + constructor(dataset: PageDataset) { + this.dataset = dataset; + } + + onWidgetAction(datasetId: string, params: any) { + this.dataset.onWidgetAction(datasetId, params); + } +} diff --git a/smtweb-framework/bpm/src/main/resources/codegen/ts/formatter.ts b/smtweb-framework/bpm/src/main/resources/codegen/ts/formatter.ts new file mode 100644 index 0000000..f292db8 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/ts/formatter.ts @@ -0,0 +1,28 @@ +/** + * 常用 table formatter 方法 + */ +export default { + methods: { + timeFormatter(row: string, column: any, cellValue: string) { + // 日期时间 + // temp 20210226113627 -> 2021-02-26 11:36:27 + if (cellValue && cellValue.length >= 14) { + const pattern = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/; + return cellValue.replace(pattern, '$1-$2-$3 $4:$5:$6'); + } else { + return cellValue || ''; + } + }, + statusFormatter(row: any, column: any, cellValue: any) { + if (cellValue === '0') { + return '正常'; + } else if (cellValue === '1') { + return '停用'; + } else if (cellValue === '2') { + return '锁定'; + } else { + return cellValue; + } + }, + }, +}; diff --git a/smtweb-framework/bpm/src/main/resources/codegen/ts/page.less b/smtweb-framework/bpm/src/main/resources/codegen/ts/page.less new file mode 100644 index 0000000..43509f2 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/ts/page.less @@ -0,0 +1,14 @@ +.sw-container { + height: 100%; +} + +.sw-layout { + &-col1 {} + &-col2 {grid-column-start: span 2;} + &-col3 {grid-column-start: span 3;} + &-col4 {grid-column-start: span 4;} + &-col5 {grid-column-start: span 5;} + &-col6 {grid-column-start: span 6;} + &-col7 {grid-column-start: span 7;} + &-col8 {grid-column-start: span 8;} +} diff --git a/smtweb-framework/bpm/src/main/resources/codegen/ts/page.types.ts b/smtweb-framework/bpm/src/main/resources/codegen/ts/page.types.ts new file mode 100644 index 0000000..f4d5425 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/ts/page.types.ts @@ -0,0 +1,5 @@ +export interface IPageParams { + pageId: string + id?: string + parentId?: string +} diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/dataset.ts.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/dataset.ts.vm new file mode 100644 index 0000000..f9295e7 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/dataset.ts.vm @@ -0,0 +1,2 @@ +// 数据集 +export default $vmTool.json($page.datasets); diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/events.ts.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/events.ts.vm new file mode 100644 index 0000000..52bc7d2 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/events.ts.vm @@ -0,0 +1,6 @@ +export default { + create({ pageDataset }) { + this.pageDataset = pageDataset; + } +} + diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/index.vue.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/index.vue.vm new file mode 100644 index 0000000..8d4cf15 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/index.vue.vm @@ -0,0 +1,62 @@ + + +#macro(printWidget $widget, $path) + <$widget.type + #if($widget.props.name && $widget.vars['$ref']) + ref="$widget.props.name.$ref" + #end + #if($widget.layout.col) + class="sw-layout-col$widget.layout.col" + #end + #foreach($prop in $widget.props.entrySet()) + #if($widget.vars[$prop.key]) + :$prop.key="wigets.$widget.props.name.$prop.key" + #else + $vmTool.htmlProp($prop.key, $prop.value) + #end + #end + #if($widget.props.dataset) + @action="onAction('$widget.props.dataset', $event)" + #end + #foreach($event in $widget.events.entrySet()) + @$event.key="onEvent('$widget.name', '$event.value', $event)" + #end + #if($widget.children) + > + #foreach($child in $widget.children) + #printWidget($child) + #end + + #else + /> + #end +#end + + + + + diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/router.ts.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/router.ts.vm new file mode 100644 index 0000000..007ce08 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/router.ts.vm @@ -0,0 +1,17 @@ +import {AppRouteRecordRaw} from "/@/router/types"; +// 导出根节点路由 +export const rootRoutes: AppRouteRecordRaw[] = []; +// 导出layout下的路由 +export const layoutRoutes: AppRouteRecordRaw[] = [ + #foreach($router in $routers) + { + path: "/$router.path", + name: "$router.name", + component: () => import("/@/pages/$router.filePath/index.vue"), + props: (route: any) => ({ json: route.params.json || "{}" }), + meta: { + title: "$router.title", + }, + }, + #end +]; diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/server/CardService.java.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/CardService.java.vm new file mode 100644 index 0000000..7411373 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/CardService.java.vm @@ -0,0 +1,37 @@ +package $package; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.system.bpm.core.ui.worker.IDatasetLoadWorker; +import cc.smtweb.system.bpm.core.ui.worker.IDatasetRemoveWorker; +import cc.smtweb.system.bpm.core.ui.worker.IDatasetSaveWorker; +import cc.smtweb.system.bpm.web.ui.DatasetCardService; + +import cc.smtweb.system.bpm.web.ui.DatasetCardService; + +/** + * 卡片数据模型服务 + * + * @author bpm + */ +@SwService +public class $className extends DatasetCardService { + @Override + protected String datasetPath() { + return "$resourceUrl/$dataset.name"; + } + + @Override + protected void onSetupLoad(IDatasetLoadWorker worker) { + // TODO 自定义表单读取处理方法 + } + + @Override + protected void onSetupSave(IDatasetSaveWorker worker) { + // TODO 自定义表单保存处理方法 + } + + @Override + protected void onSetupRemove(IDatasetRemoveWorker worker) { + // TODO 自定义表单删除处理方法 + } +} + diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/server/ListService.java.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/ListService.java.vm new file mode 100644 index 0000000..7e632ba --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/ListService.java.vm @@ -0,0 +1,28 @@ +package $package; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.system.bpm.core.ui.worker.IDatasetListAllWorker; +import cc.smtweb.system.bpm.core.ui.worker.IDatasetListPartWorker; +import cc.smtweb.system.bpm.web.ui.DatasetListService; + +/** + * 列表数据模型服务 + * + * @author bpm + */ +@SwService +public class $className extends DatasetListService { + @Override + protected String datasetPath() { + return "$resourceUrl"; + } + + @Override + protected void onSetupListPart(IDatasetListPartWorker worker) { + // TODO 自定义部分表(支持翻页)查询 + } + + @Override + protected void onSetupListAll(IDatasetListAllWorker worker) { + // TODO 自定义全表查询 + } +} diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/server/TreeService.java.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/TreeService.java.vm new file mode 100644 index 0000000..4542d58 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/TreeService.java.vm @@ -0,0 +1,30 @@ +package $package; + +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.system.bpm.core.ui.worker.IDatasetTreePartWorker; +import cc.smtweb.system.bpm.core.ui.worker.IDatasetTreeAllWorker; +import cc.smtweb.system.bpm.web.ui.DatasetTreeService; + +/** + * 树数据模型服务 + * + * @author LowCode + */ +@SwService +public class $className extends DatasetTreeService { + @Override + protected String datasetPath() { + return "$resourceUrl"; + } + + @Override + protected void onSetupTreePart(IDatasetTreePartWorker worker) { + // TODO 自定义部分树(延迟加载)查询 + }; + + @Override + protected void onSetupTreeAll(IDatasetTreeAllWorker worker) { + // TODO 自定义全树查询 + }; +} + diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/server/entity.java.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/entity.java.vm new file mode 100644 index 0000000..7d8be58 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/entity.java.vm @@ -0,0 +1,23 @@ +package $package; +import cc.smtweb.framework.core.annotation.SwColumn; +import cc.smtweb.framework.core.annotation.SwTable; +import lombok.Data; +/** + * 以下是机器生成代码,请勿修改! + * + * @author LowCode + * $table.name + * $table.remark + */ +@Data +@SwTable("$table.dbName.$table.name") +public class $vmTool.toUpperHump($table.name) { + #foreach($field in $table.fields) + /** $field.label $!{field.remark} */ + #if ($field.name == $table.idField) + @SwColumn(type = SwColumn.Type.ID) + #end + private $vmTool.javaType($field.dataType) $vmTool.toHump($field.name); + #end +} + diff --git a/smtweb-framework/bpm/src/main/resources/codegen/vm/server/event.js.vm b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/event.js.vm new file mode 100644 index 0000000..31a8031 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/codegen/vm/server/event.js.vm @@ -0,0 +1,28 @@ +/** + * 页面 ${url} 事件处理,有默认属性: + * $refs map, 控件ref引用,可以访问控件函数 + * $model map, 数据集对象 + * $widgets map, 控件响应变量 + */ +window["$swEvent"].setup("$url", { + /** + * FxPage的setup中调用的初始化对象函数 + * @param props FxPage的控件属性,其中用页面params参数 + * @param context FxPage的vue3上下文对象,包括常用的emit事件属性 + */ + init(props, context) { + }, + + page$onMounted(e) { + }, + + page$onUnmounted(e) { + }, + +#foreach($child in $events) + ${child}(e) { + console.log("${child}", e); + }, + +#end +}); diff --git a/smtweb-framework/bpm/src/main/resources/config/application.yaml b/smtweb-framework/bpm/src/main/resources/config/application.yaml new file mode 100644 index 0000000..3c54545 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/config/application.yaml @@ -0,0 +1,43 @@ +smtweb: + machine-id: 1 + file: + local-path: /data/sw/files/ + url: http://127.0.0.1:8888/sw/files/ + bpm: + debug: true + code-java-path: 'e:/jujia/git/6.0/smtweb2/smtweb-framework' + db: + type: mysql + default: + rule: + prefix: _smt_ + replace: smt_ +server: + port: 8888 + servlet: + context-path: / +logging: + level: + root: INFO + cc.smtweb: DEBUG +spring: + redis: + host: 127.0.0.1 + port: 6379 + password: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/smt_asp?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false + username: root + password: root + servlet: + multipart: + max-file-size: 104857600000 + max-request-size: 10485760000000 + cache: + type: caffeine + cache-names: + - core + - bpm + caffeine: + spec: maximumSize=1024,expireAfterWrite=2h diff --git a/smtweb-framework/bpm/src/main/resources/config/logback.xml b/smtweb-framework/bpm/src/main/resources/config/logback.xml new file mode 100644 index 0000000..ddd583f --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/config/logback.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/smtweb-framework/bpm/src/main/resources/static/event/defaultEvent.js b/smtweb-framework/bpm/src/main/resources/static/event/defaultEvent.js new file mode 100644 index 0000000..87f0f6e --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/event/defaultEvent.js @@ -0,0 +1,87 @@ +// 注册事件类 +window.$swEvent.setup("defaultEvent", { + /** + * + * @param page 当前页面对象 + * 1)page.$params 参数对象 + * 示例:给参数p1赋值: page.$params.p1 = “xxxx”; + * + * 2)page.$refs 控件的ref引用,ref引用指向控件的实例,可访问控件实例的属性和函数 + * 示例:调用页面的 标签的validate方法: page.$refs.form1.validate() + * + * 3)page.$model 数据集,内含data(数据对象)和dataset(数据集定义) + * 示例: 获取数据集ds1的表单数据 page.$model.ds1.data.form + * 获取数据集ds1的列表数据 page.$model.ds1.data.list + * 获取数据集ds1表单中a1的值 page.$model.ds1.getFormVal("a1") + * 给数据集ds1的表中的a1赋值 page.$model.ds1.setFormVal("a1","xxxx"); + * + * 4)page.$widgets 控件的属性,控制控件的响应属性 + * 示例 : 获取控件名为w1的required属性的值 page.$widgets.w1.required + * + * 5)page.$utils 工具包 + * $$message 消息提示 + * $$cookie, cookie + * $$driver, 用户操作引导引擎 + * $$http, http请求 + * $$validate, 校验 + * $$date, 日期处理工具 + * $$UtilPub, 其他 + * 示例: + * 弹出成功消息框:page.$utils.$$message.notify.success("xxx") + * post请求:page.$utils.$$http.post("/api/bpm/save",{id:"xxx"}) + * + * 6)page.$tabRouter 页面路由,控制页面切换 + * 示例:跳转到登录页:page.$tabRouter.push("login"); + * 返回: page.$tabRouter.back(); + * + * 7) page.$api 页面提供的公用api + * add: () => void 页面新增初始化(所有可编辑的数据集) + * addOne: (dataset: string) => void 指定数据集新增初始 + * load: (force?: boolean, params?: any) => void // 页面加载 + * loadOne: (dataset: string, params?: any) => void // 指定数据集加载 + * total: (dataset: string, params?: any) => void // 指定数据集求合计栏信息 + * save: (params?: any) => void // 页面保存 (所有可编辑的数据集) + * saveOne: (dataset: string, params?: any) => void // 指定数据集保存 + * del: () => void 页面删除 + * delOne: (dataset: string, row?: any) => void // 指定数据集删除 + * closeDialog: (dialogKey?: string) => void // 关闭弹出框 + * 示例: + * 加载数据集ds1:page.$api.loadOne("ds1"); + * + * @returns 返回给页面可配置的api方法 + * 如 : return { + * demoFunc(){ + * XXXX + * }, + * } + */ + setup(page){ + const { $params,$refs, $widgets, $model, $utils, $tabRouter, $api } = page; + const { $$message, $$http } = $utils || {}; + // 示例 + const demoFunc = () => { + // 1.从参数中获取p1 + const p1 = $params.p1; + // 2.从控件w1获取color属性 + const color = $widgets.w1.props.color; + // 3.调用控件w1的calc函数 + const calcVal = $refs.w1.calc(p1,color); + // 4.数据集ds1加载数据 + $api.loadOne("ds1"); + // 5.给数据集ds1的表单中的f1字段赋值calcVal + $model.ds1.setFormVal("f1",calcVal); + // 6.获取数据集ds1的表单数据 + const data = $model.ds1.data.form || {}; + // 7.调用http交互 + $$http.post("ap1/demo/doOpt",data).then((rt) => { + // 8.弹出成功消息 + $$message.notify.success("操作成功"); + // 9.返回上一个页面 + $tabRouter.back(); + }); + }; + return { + demoFunc, + } + } +}); diff --git a/smtweb-framework/bpm/src/main/resources/static/index.html b/smtweb-framework/bpm/src/main/resources/static/index.html new file mode 100644 index 0000000..2042999 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/index.html @@ -0,0 +1,14 @@ + + + + + BPM + + + + + diff --git a/smtweb-framework/bpm/src/main/resources/static/template/demo.ftl b/smtweb-framework/bpm/src/main/resources/static/template/demo.ftl new file mode 100644 index 0000000..f29f6b9 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/demo.ftl @@ -0,0 +1,5 @@ +{ + "form": [ + { + "page": { + "id": "p \ No newline at end of file diff --git a/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_filter.ftl b/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_filter.ftl new file mode 100644 index 0000000..f4bb800 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_filter.ftl @@ -0,0 +1,76 @@ +<#assign fields = group.cfilters> + { + "id": "${newId()}", + "type": "fx-form-panel", + "shape": "panel", + "props": { + "paddingY": 5, + "paddingX": 10, + "size": "35", + "colNum": 2 + }, + "children": [ +<#list fields as filter> + { + "id": "id${newId()}", + "type": "fx-${filter.editor}", + "props": { + "label": "${filter.label}", + "type": "text", + <#if filter.maxlength gt 0> + "maxlength": ${filter.maxlength}, + + "placeholder": "请输入查询内容", + "labelWidth": 100, + "dataset": "${filter.dataset}", + "field": "${filter.id}", + "name": "${filter.name}" + }, + "events": {} + }, + + { + "id": "id${newId()}", + "type": "fx-button-group", + "props": { + "menus": [] + }, + "slots": { + "default": [ + { + "type": "fx-button", + "props": { + "label": "查询", + "leftIcon": "history-query", + "type": "primary", + "action": "button:search", + "dataset": "${group.dataset}" + }, + "id": "id${newId()}" + }, + { + "type": "fx-button", + "props": { + "label": "重置", + "type": "danger", + "action": "button:reset", + "leftIcon": "figma-reset-instance" + }, + "id": "id${newId()}" + }, + { + "id": "id${newId()}", + "type": "fx-button", + "props": { + "label": "新增", + "type": "success", + "leftIcon": "shield-add", + "action": "button:add", + "dataset": "${group.dataset}" + } + } + ] + } + } + ] + }, \ No newline at end of file diff --git a/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_form.ftl b/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_form.ftl new file mode 100644 index 0000000..5ef0af9 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_form.ftl @@ -0,0 +1,33 @@ +<#assign fields = group.fields> + { + "shape": "panel", + "id": "form_panel", + "type": "fx-form-panel", + "props": { + "colNum": 2, + "paddingX": 5, + "paddingY": 5, + "size": "0" + }, + "children": [ +<#list fields as field> + { + "id": "id${newId()}", + "type": "fx-${field.editor}", + "props": { + "label": "${field.label}", + "type": "text", + <#if field.maxlength gt 0> + "maxlength": ${field.maxlength}, + + "placeholder": "请输入内容", + "labelWidth": 100, + "dataset": "${field.dataset}", + "field": "${field.id}", + "name": "${field.name}" + }, + "events": {} + }<#if field_has_next>, + + ] + } \ No newline at end of file diff --git a/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_grid_opt.ftl b/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_grid_opt.ftl new file mode 100644 index 0000000..70220b4 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_grid_opt.ftl @@ -0,0 +1,67 @@ +{ + "shape": "panel", + "id": "form_panel", + "type": "fx-form-panel", + "props": { + "colNum": 0, + "paddingX": 5, + "paddingY": 5, + "align": "full" + }, + "children": [ + { + "id": "id${newId()}", + "type": "fx-table", + "props": { + "label": "表格", + "border": true, + "stripe": true, + "showHeader": true, + "fit": true, + "dataset": "${group.dataset}", + "actionWidth": 120 + }, + "slots": { +<#assign fields = group.fields> + "default": [ +<#list fields as col> + { + "id": "id${newId()}", + "type": "fx-table-column", + "props": { + "field": "${col.id}", + "label": "${col.label}" + } + }<#if col_has_next>, + + ], + "button": [ + { + "type": "fx-button", + "props": { + "label": "编", + "type": "text", + "leftIcon": "edit", + "action": "button:edit", + "linkType": "dialog", + "dataset": "${group.dataset}" + }, + "id": "id1813718bf36" + }, + { + "type": "fx-button", + "props": { + "label": "删", + "type": "text", + "leftIcon": "delete", + "action": "button:del", + "dataset": "${group.dataset}" + }, + "id": "id${newId()}" + } + ] + }, + "events": {} + } + ] + } \ No newline at end of file diff --git a/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_model.ftl b/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_model.ftl new file mode 100644 index 0000000..bdda13c --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/incModel/inc_model.ftl @@ -0,0 +1,28 @@ +{ + "dataset": "${dataset.id}", + "label": "${dataset.label}", + "fields": [ + <#list dataset.fields as field> + { + "id": "${field.id}", + "field": "${field.field}"<#if field.widget gt 0>, + "lookup": { + "widgetId": "${field.widget?c}", + "widgetId_text": "${field.widgetText}", + "filters": [] + } + + }<#if field_has_next>, + + ], + "filters": [ + <#list dataset.filters as field> + { + "id": "${field.id}", + "field": "${field.field!0}", + "required": ${field.required?string ("true","false")}, + "type": "input" + }<#if field_has_next>, + + ] + } \ No newline at end of file diff --git a/smtweb-framework/bpm/src/main/resources/static/template/index.yaml b/smtweb-framework/bpm/src/main/resources/static/template/index.yaml new file mode 100644 index 0000000..8e2128e --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/index.yaml @@ -0,0 +1,35 @@ +model: + - + name: 'model_list' + label: '简单列表' + # list/card/view + type: 'list' + # 布局 + layout: + - + name: 'c1' + label: '简单列表' + type: 'list' + hasGroup: false + # 变量 + param: + - + name: 'queryDs' + type: 'ds' + - + name: 'model_card' + label: '简单卡片' + # list/card/view + type: 'card' + # 布局 + layout: + - + name: 'c1' + label: '客户区' + type: 'card' + hasGroup: false + # 变量 +# param: +# - +# name: 'p1' +# type: 'ds' diff --git a/smtweb-framework/bpm/src/main/resources/static/template/java_bean.ftl b/smtweb-framework/bpm/src/main/resources/static/template/java_bean.ftl new file mode 100644 index 0000000..eca1672 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/java_bean.ftl @@ -0,0 +1,42 @@ +package ${packageName}; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.impl.DefaultEntity; + +/** + * Created by ${user} at ${sysTime} + * 实体【[${tableTitle}](${tableName})】的Entity类 + */ +@SwTable("${tableName}") +public class ${beanName} extends DefaultEntity { + public static final String ENTITY_NAME = "${tableName}"; + + public ${beanName}() { + super(ENTITY_NAME); + } + + <#list fields as field> + <#if field.javaType == "boolean"> + /** ${field.title} */ + public boolean is${field.javaName}() { + return getBool("${field.name}"); + } + + /** ${field.title} */ + public void set${javaName}(boolean ${field.name}) { + setBool("${field.name}", ${field.name}); + } + <#else > + /** ${field.title} */ + public ${field.javaType} get${field.javaName}() { + return get${field.shortJavaType}("${field.name}"); + } + + /** ${field.title} */ + public void set${field.javaName}(${field.javaType} ${field.name}) { + put("${field.name}", ${field.name}); + } + + +} diff --git a/smtweb-framework/bpm/src/main/resources/static/template/java_cache.ftl b/smtweb-framework/bpm/src/main/resources/static/template/java_cache.ftl new file mode 100644 index 0000000..81fc0ad --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/java_cache.ftl @@ -0,0 +1,51 @@ +package ${packageName}; + +import cc.smtweb.framework.core.annotation.SwCache; +import cc.smtweb.framework.core.cache.AbstractEntityCache; +import cc.smtweb.framework.core.cache.CacheManager; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +/** + * Created by ${user} at ${sysTime} + * 实体【[${tableTitle}](${tableName})】的缓存类 + */ +@SwCache(ident = "${tableName}", title = "${tableTitle}") +public class ${beanName}Cache extends AbstractEntityCache<${beanName}> { +<#list caches as cache> + //缓存key:${cache.title} + public final static String mk_${cache.name} = "${cache.name}"; + + + public static ${beanName}Cache getInstance() { + return CacheManager.getIntance().getCache(${beanName}Cache.class); + } + + public ${beanName}Cache() { +<#list caches as cache> + //缓存key:${cache.title} + <#if cache.type=="M"> + regMap(mk_${cache.name}, "${cache.fields}"); + <#else> + regList(mk_${cache.name}, "${cache.fields}"); + + + } + +<#list caches as cache> + <#if cache.type=="M"> + //缓存key:${cache.title} + public final ${beanName} getBy${cache.nameUF}(String key) { + return getByKey(mk_${cache.name}, key); + } + <#else> + //缓存key:${cache.title} + public final Set<${beanName}> getBy${cache.nameUF}(String key) { + return getListByKey(mk_${cache.name}, key); + } + + +} diff --git a/smtweb-framework/bpm/src/main/resources/static/template/java_service.ftl b/smtweb-framework/bpm/src/main/resources/static/template/java_service.ftl new file mode 100644 index 0000000..aff420f --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/java_service.ftl @@ -0,0 +1,30 @@ +package ${packageName}; + +import cc.smtweb.framework.core.annotation.SwBody; +import cc.smtweb.framework.core.annotation.SwService; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.system.bpm.web.engine.dynPage.DynPageService; +import cc.smtweb.framework.core.mvc.service.AbstractHandler; +import cc.smtweb.framework.core.session.UserSession; + +/** + * Created by ${user} at ${sysTime} + * 页面【[${formTitle}]的服务类 + */ +@SwService +public class ${service}Service extends DynPageService { + //public final static String TYPE_DEMO = "demo"; + @Override + protected AbstractHandler createHandler(String type) { + return super.createHandler(type); + } + +/* demo + //自定义 + public R demo(@SwBody SwMap params, UserSession us) { + return pageHandler(params, us, TYPE_DEMO, handler -> ((DemoHandler)handler).demo()); + } +*/ + +} diff --git a/smtweb-framework/bpm/src/main/resources/static/template/js_event.ftl b/smtweb-framework/bpm/src/main/resources/static/template/js_event.ftl new file mode 100644 index 0000000..d74d428 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/js_event.ftl @@ -0,0 +1,17 @@ +/** + * Created by ${user} at ${sysTime} + * 注册事件类【${title}】,参看event.defaultEvent.js +*/ +window.$swEvent.setup("${eventPath}", { + setup(page){ + const { $params,$refs, $widgets, $model, $utils, $tabRouter, $api } = page; + const { $$message, $$http } = $utils; + // 示例 + const demoFunc = () => { + + }; + return { + demoFunc, + } + } +}); \ No newline at end of file diff --git a/smtweb-framework/bpm/src/main/resources/static/template/model_card.ftl b/smtweb-framework/bpm/src/main/resources/static/template/model_card.ftl new file mode 100644 index 0000000..713b23f --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/model_card.ftl @@ -0,0 +1,116 @@ +{ + "form": [ + { + "page": { + "id": "p${newId()}", + "type": "fx-page", + "props": { + "title": "${title}", + "key": "${newId()}" + } + }, + "graph": { + "shape": "panel", + "id": "root_panel", + "type": "fx-split-panel", + "props": { + "horizontal": false, + "shadow": "never" + }, + "children": [ +<#list layout.c1 as group> + <#if (group.type == "list")> + <#if (group.cfilters?size>0)> + <#include "incModel/inc_filter.ftl"/> + + <#include "incModel/inc_grid_opt.ftl"/> + <#elseif (group.type == "card")> + <#include "incModel/inc_form.ftl"/> + , + +{ + "id": "${newId()}", + "type": "fx-form-panel", + "shape": "panel", + "props": { + "paddingY": 3, + "paddingX": 10, + "size": 20 + }, + "children": [ + { + "id": "id${newId()}", + "type": "fx-button-group", + "props": { + "menus": [], + "textAlign": "center" + }, + "slots": { + "default": [ + { + "type": "fx-button", + "props": { + "label": "新增", + "leftIcon": "plus", + "type": "primary", + "action": "button:add" + }, + "id": "id${newId()}" + }, + { + "type": "fx-button", + "props": { + "label": "保存并新增", + "type": "primary", + "action": "button:saveAndAdd" + }, + "id": "id${newId()}" + }, + { + "type": "fx-button", + "props": { + "label": "保存", + "leftIcon": "save", + "type": "success", + "action": "button:save" + }, + "id": "id${newId()}" + }, + { + "type": "fx-button", + "props": { + "label": "删除", + "leftIcon": "delete", + "type": "danger", + "action": "button:remove" + }, + "id": "id${newId()}" + }, + { + "type": "fx-button", + "props": { + "label": "返回", + "leftIcon": "return", + "action": "button:return" + }, + "id": "id${newId()}" + } + ] + } + } + ] + } + ] + } + } + ], + "model": [ +<#list datasets as dataset> + <#include "incModel/inc_model.ftl"/><#if dataset_has_next>, + + ], + "option": { + "widgetRef": [${widgetRef}], + "vars": [] + } +} \ No newline at end of file diff --git a/smtweb-framework/bpm/src/main/resources/static/template/model_list.ftl b/smtweb-framework/bpm/src/main/resources/static/template/model_list.ftl new file mode 100644 index 0000000..1399c2f --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/model_list.ftl @@ -0,0 +1,392 @@ +{ +<#list layout.c1 as group> + "form": + [ + { + "page": { + "id": "p${newId()}", + "type": "fx-page", + "props": { + "title": "${title}", + "key": "${newId()}" + } + }, + "graph": { + "shape": "panel", + "id": "root_panel", + "type": "fx-split-panel", + "props": { + "horizontal": false, + "shadow": "" + }, + "children": [ + { + "shape": "panel", + "id": "form_panel", + "type": "fx-form-panel", + "props": { + "colNum": 3, + "name": "query", + "label": "按钮区", + "size": "80", + "shadow": "", + "alignY": "center", + "paddingRight": 10 + }, + "children": [ + + <#if (group.cfilters?size>0)> + <#assign fields = group.cfilters> + <#list fields as filter> + { + "id": "id${newId()}", + "type": "fx-${filter.editor}", + "props": { + "label": "${filter.label}", + "type": "text", + <#if filter.maxlength gt 0> + "maxlength": ${filter.maxlength}, + + "placeholder": "请输入查询内容", + "labelWidth": 100, + "dataset": "${filter.dataset}", + "field": "${filter.id}", + "name": "${filter.name}" + }, + "events": {} + }, + + + + { + "id": "id${newId()}", + "type": "fx-button-group", + "props": { + "menus": [], + "textAlign": "right" + }, + "slots": { + "default": [ + { + "type": "fx-button", + "props": { + "label": "重置", + "leftIcon": "clear", + "type": "", + "action": "button:reset", + "dataset": "", + "link": false, + "linkType": "" + }, + "id": "id${newId()}" + }, + { + "type": "fx-button", + "props": { + "label": "查询", + "leftIcon": "search", + "type": "primary", + "action": "button:search", + "dataset": "${param.queryDs}" + }, + "id": "id${newId()}" + } + <#if (group.sfilters?size>0)> + ,{ + "type": "fx-button", + "props": { + "label": "高级筛选", + "leftIcon": "hamburger-button", + "action": "button:link", + "link": true, + "linkType": "drawer", + "fxLink": "dialog:qrueydialog" + }, + "id": "id${newId()}" + } + + ] + }, + "layout": { + "col": 1 + } + } + ] + }, + { + "id": "${newId()}", + "type": "fx-form-panel", + "shape": "panel", + "props": { + "size": "20", + "backgroundColor": "transparent" + }, + "children": [] + }, + { + "id": "${newId()}", + "type": "fx-form-panel", + "shape": "panel", + "props": { + "size": "68", + "label": "查询条件", + "colNum": 2, + "alignY": "center", + "paddingLeft": 32, + "paddingRight": 32, + "shadow": "" + }, + "children": [ + { + "id": "id${newId()}", + "type": "fx-title", + "props": { + "label": "${title}", + "fontSize": 16, + "color": "#01070D", + "fontWeight": "bold", + "showPrefix": false, + "prefixWidth": 5, + "prefixHeight": 24, + "prefixColor": "#1E90FF" + } + }, + { + "id": "id${newId()}", + "type": "fx-button-group", + "props": { + "menus": [], + "textAlign": "right" + }, + "slots": { + "default": [ + { + "type": "fx-button", + "props": { + "label": "新增", + "leftIcon": "plus", + "type": "primary", + "action": "button:add", + "link": false, + "linkType": "", + "fxLink": "", + "dataset": "" + }, + "id": "id${newId()}" + } + ] + } + } + ] + }, + { + "id": "${newId()}", + "type": "fx-form-panel", + "shape": "panel", + "props": { + "size": "", + "label": "列表", + "colNum": 0, + "paddingLeft": 32, + "paddingRight": 32, + "shadow": "" + }, + "children": [ + { + "id": "id${newId()}", + "type": "fx-table", + "props": { + "label": "表格", + "border": true, + "stripe": true, + "showHeader": true, + "fit": true, + "dataset": "${group.dataset}", + "actionWidth": 150 + }, + "slots": { + <#if (group.fields?size>0)> + <#assign fields = group.fields> + "default": [ + <#list fields as col> + { + "id": "id${newId()}", + "type": "fx-table-column", + "props": { + "field": "${col.id}", + "label": "${col.label}" + } + }<#if col_has_next>, + + ], + + "button": [ + { + "type": "fx-button", + "props": { + "label": "编辑", + "type": "text", + "leftIcon": "edit", + "action": "button:edit", + "dataset": "", + "link": true, + "linkType": "", + "nextAction": "", + "fxLink": "" + }, + "id": "id${newId()}" + }, + { + "type": "fx-button", + "props": { + "label": "删除", + "type": "text", + "leftIcon": "delete-themes", + "action": "button:remove", + "preAction": "", + "link": true, + "confirm": "" + }, + "id": "id${newId()}" + } + ] + }, + "events": {} + } + ] + }, + { + "id": "${newId()}", + "type": "fx-form-panel", + "shape": "panel", + "props": { + "size": "24", + "backgroundColor": "transparent" + }, + "children": [] + } + ] + } + }, + { + "page": { + "id": "id${newId()}", + "type": "fx-dialog", + "props": { + "title": "查询条件", + "key": "qrueydialog", + "destroyOnClose": true, + "closeOnClickModal": true, + "width": "20%", + "height": "" + }, + "events": { + } + } + <#if (group.sfilters?size>0)> + ,"graph": { + "shape": "panel", + "id": "root_panel", + "type": "fx-split-panel", + "props": { + "horizontal": false, + "shadow": "never" + }, + "children": [ + { + "shape": "panel", + "id": "form_panel", + "type": "fx-form-panel", + "props": { + "colNum": 1, + "name": "query", + "label": "查询条件", + "size": "", + "paddingTop": 20, + "scroll": true + }, + "children": [ + + <#assign fields = group.sfilters> + <#list fields as filter> + { + "id": "id${newId()}", + "type": "fx-${filter.editor}", + "props": { + "label": "${filter.label}", + "type": "text", + <#if filter.maxlength gt 0> + "maxlength": ${filter.maxlength}, + + "placeholder": "请输入查询内容", + "labelWidth": 100, + "dataset": "${filter.dataset}", + "field": "${filter.id}", + "name": "${filter.name}" + }, + "events": {} + } + <#if filter_has_next>, + + + ] + }, + { + "id": "${newId()}", + "type": "fx-form-panel", + "shape": "panel", + "props": { + "size": "56", + "alignY": "center" + }, + "children": [ + { + "id": "id${newId()}", + "type": "fx-button-group", + "props": { + "menus": [], + "textAlign": "center" + }, + "slots": { + "default": [ + { + "type": "fx-button", + "props": { + "label": "重置", + "leftIcon": "clear", + "action": "button:return" + }, + "id": "id${newId()}" + }, + { + "type": "fx-button", + "props": { + "label": "查询", + "leftIcon": "save", + "type": "success", + "action": "button:search", + "dataset": "${param.queryDs}" + }, + "id": "id${newId()}" + } + ] + } + } + ] + } + ] + } + + } + ], + +"model": [ +<#list datasets as dataset> + <#include "incModel/inc_model.ftl"/><#if dataset_has_next>, + +], +"option": { +"widgetRef": [${widgetRef}], +"vars": [] +} +} diff --git a/smtweb-framework/bpm/src/main/resources/static/template/model_simple.ftl b/smtweb-framework/bpm/src/main/resources/static/template/model_simple.ftl new file mode 100644 index 0000000..7973c99 --- /dev/null +++ b/smtweb-framework/bpm/src/main/resources/static/template/model_simple.ftl @@ -0,0 +1,45 @@ +{ + "form": [ + { + "page": { + "id": "p${newId()}", + "type": "fx-page", + "props": { + "title": "${title}", + "key": "${newId()}" + } + }, + "graph": { + "shape": "panel", + "id": "root_panel", + "type": "fx-split-panel", + "props": { + "horizontal": false, + "shadow": "never" + }, + "children": [ +<#list layout.c1 as group> + <#if (group.type == "list")> + <#if (group.cfilters?size>0)> + <#include "incModel/inc_filter.ftl"/> + + <#include "incModel/inc_grid_opt.ftl"/> + <#elseif (group.type == "card")> + <#include "incModel/inc_form.ftl"/> + + <#if group_has_next>, + + ] + } + } + ], + "model": [ +<#list datasets as dataset> + <#include "incModel/inc_model.ftl"/><#if dataset_has_next>, + + ], + "option": { + "widgetRef": [${widgetRef}], + "vars": [] + } +} \ No newline at end of file diff --git a/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/BpmTest.java b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/BpmTest.java new file mode 100644 index 0000000..c408dcb --- /dev/null +++ b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/BpmTest.java @@ -0,0 +1,38 @@ +package cc.smtweb.system.bpm.test; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.mvc.controller.MethodAccessManager; +import cc.smtweb.system.bpm.spring.BpmApplication; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.Map; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = {BpmApplication.class}) +public class BpmTest { + @Autowired + private MethodAccessManager methodAccessManager; + + private R invoke(String url, Map body) throws Exception { +// Map params = new HashMap<>(); +// return methodAccessManager.invokeDirect(url, params, JsonUtil.encodeString(body)); + return null; + } + + @Test + public void load() throws Exception { + R r = invoke("bpm/BpmTaskCard/load", SwMap.of("flowId", 476347272070696960L)); + + System.out.println(r); + + Assertions.assertEquals(0, r.readInt("code")); + Assertions.assertNotEquals(null, r.get("data")); + } + +} diff --git a/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/BuildJavaBean.java b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/BuildJavaBean.java new file mode 100644 index 0000000..be57d3a --- /dev/null +++ b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/BuildJavaBean.java @@ -0,0 +1,54 @@ +package cc.smtweb.system.bpm.test; + +import cc.smtweb.system.bpm.util.CodeGenUtil; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + +/** + * Created by Akmm at 2022/3/1 9:41 + * 生成bean + */ +public class BuildJavaBean { + @Test + public void buildBean() { + String str = "`trl_id` bigint(20) NOT NULL COMMENT 'null',\n" + + " `trl_pri_id` bigint(20) DEFAULT NULL COMMENT 'null',\n" + + " `trl_src_task_id` bigint(20) DEFAULT NULL COMMENT 'null',\n" + + " `trl_dst_task_id` bigint(20) DEFAULT NULL COMMENT 'null',\n"; + String[] ss = str.split("\n"); + for (String s: ss) { + String[] s0 = s.trim().split(" "); + if (StringUtils.isEmpty(s0[0])) continue; + String tn = s0[0].substring(1, s0[0].indexOf("`", 2)); + String tnu = CodeGenUtil.underlineToUpperHump(tn.substring(tn.indexOf("_") + 1)); + String tnn = CodeGenUtil.underlineToHump(tn); + + String tt = s0[1]; + String ttj; + if (tt.contains("(")) tt = tt.substring(0, tt.indexOf("(")); + switch (tt) { + case "bigint": + tt = "long"; + ttj = "Long"; + break; + case "tinyint": + case "smallint": + case "int": + tt = "int"; + ttj = "Int"; + break; + default: + tt = "String"; + ttj = "Str"; + break; + } + System.out.println("public " + tt + " get" + tnu + "(){\n" + + "return get" + ttj + "(\"" + tn + "\");\n" + + "}\n" + + "" + + "public void set" + tnu + "(" + tt + " " + tnn + "){\n" + + "put(\"" + tn + "\", " + tnn + ");\n" + + "}\n"); + } + } +} diff --git a/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/HexTest.java b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/HexTest.java new file mode 100644 index 0000000..277a042 --- /dev/null +++ b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/HexTest.java @@ -0,0 +1,36 @@ +package cc.smtweb.system.bpm.test; + +import org.apache.commons.codec.binary.Hex; +import org.junit.jupiter.api.Test; + +import java.io.FileInputStream; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Set; + +public class HexTest { + + @Test + public void hexToText() throws Exception { + + FileInputStream fis = new FileInputStream("/var/1.txt"); + + byte[] data = new byte[2 * 1024 * 1024]; + int len = fis.read(data); + + byte[] buf = Hex.decodeHex(new String(data, 0, len)); + + System.out.println(new String(buf, StandardCharsets.UTF_8)); + } + + @Test + public void joinTest() { + Set ids = new HashSet<>(); + ids.add("1"); + ids.add("2"); + ids.add("3"); + ids.add("1"); + + System.out.println(String.join(",", ids)); + } +} diff --git a/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/ModelFormTest.java b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/ModelFormTest.java new file mode 100644 index 0000000..f1b4be8 --- /dev/null +++ b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/ModelFormTest.java @@ -0,0 +1,98 @@ +package cc.smtweb.system.bpm.test; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.system.bpm.spring.BpmApplication; +import cc.smtweb.system.bpm.web.design.form.ModelForm; +import cc.smtweb.system.bpm.web.design.form.ModelFormHelper; +import cc.smtweb.system.bpm.web.design.form.ModelFormService; +import cc.smtweb.system.bpm.web.engine.dynPage.DynPageService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Akmm at 2022/4/26 9:46 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BpmApplication.class) +public class ModelFormTest { + @Test + public void testLoad() { + SwMap params = new SwMap(); + params.put("pageId", 1); + params.put("dataset", "modelProject"); + SwMap filter = new SwMap(); + filter.put("prj_name", "测试"); + params.put("filter", filter); + DynPageService service = new DynPageService(); + R r = service.load(params, null); + System.out.println(r.readSuccess()); + } + + @Test + public void testSave() { + //{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}} + SwMap params = new SwMap(); + params.put("pageId", 1); + params.put("dataset", "modelProject"); + SwMap data = new SwMap(); + SwMap form = new SwMap(); + form.put("prj_id", "12345"); + form.put("prj_name", "test12345"); + form.put("prj_desc", "this is test12345"); + data.put("form", form); + params.put("data", data); + SwMap filter = new SwMap(); + filter.put("prj_name", "测试"); + params.put("filter", filter); + DynPageService service = new DynPageService(); + R r = service.saveOne(params, null); + System.out.println(r.readSuccess()); + } + + @Test + public void testDel() { + //{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}} + SwMap params = new SwMap(); + params.put("pageId", 1); + params.put("id", 12345); + + DynPageService service = new DynPageService(); + R r = service.del(params, null); + System.out.println(r.readSuccess()); + } + + @Test + public void testBuildModelByTmpl() { + ModelForm form = new ModelForm(); + form.setTitle("测试呀"); + form.setDataset("[{\"id\":\"ds_18147381016\",\"name\":\"master\",\"label\":\"主数据集\",\"type\":\"form\",\"masterTable\":\"2\",\"masterTable_text\":\"目录\",\"idField\":\"mc_id\",\"lazy\":false,\"canEdit\":true,\"fields\":[{\"id\":\"id_1814738101b\",\"table\":\"2\",\"field\":\"mc_id\",\"name\":\"mc_id\",\"fieldType\":1,\"notNull\":1,\"link\":\"0\"},{\"id\":\"id_1814738101c\",\"table\":\"2\",\"field\":\"mc_parent_id\",\"name\":\"mc_parent_id\",\"fieldType\":4,\"notNull\":0,\"link\":\"2\"},{\"id\":\"id_1814738101d\",\"table\":\"2\",\"field\":\"mc_level_code\",\"name\":\"mc_level_code\",\"fieldType\":5,\"notNull\":0,\"link\":\"0\"},{\"id\":\"id_1814738101e\",\"table\":\"2\",\"field\":\"mc_prj_id\",\"name\":\"mc_prj_id\",\"fieldType\":0,\"notNull\":1,\"link\":\"1\"},{\"id\":\"id_1814738101f\",\"table\":\"2\",\"field\":\"mc_code\",\"name\":\"mc_code\",\"fieldType\":2,\"notNull\":0,\"link\":\"0\"},{\"id\":\"id_18147381020\",\"table\":\"2\",\"field\":\"mc_name\",\"name\":\"mc_name\",\"fieldType\":3,\"notNull\":0,\"link\":\"0\"}],\"filters\":[],\"data\":[],\"dynCond\":{\"opt\":\"and\"},\"sortFields\":[]}]"); + form.setTmpl("{\"param\":{},\"layout\":{\"c1\":[{\"id\":\"id18147381019\",\"name\":\"group1\",\"label\":\"分组1\",\"type\":\"card\",\"fields\":[{\"field\":\"id_1814738101c\",\"field_text\":\"mc_parent_id\",\"field_label\":\"父ID\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"},{\"field\":\"id_1814738101d\",\"field_text\":\"mc_level_code\",\"field_label\":\"级次码\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"},{\"field\":\"id_1814738101e\",\"field_text\":\"mc_prj_id\",\"field_label\":\"所属项目\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"},{\"field\":\"id_1814738101f\",\"field_text\":\"mc_code\",\"field_label\":\"编码\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"},{\"field\":\"id_18147381020\",\"field_text\":\"mc_name\",\"field_label\":\"编码\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"}],\"sfilters\":[],\"cfilters\":[]}]}}"); + ModelFormHelper.buildSaveModelByTmpl(form, "model_simple"); + System.out.println(form.getContent()); + } + + @Test + public void testBuildJavaBean() { + //{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}} + SwMap params = new SwMap(); + params.put("pageId", 718479207767740416L); + params.put("service", true); + List table = new ArrayList<>(); + params.put("table", table); + SwMap map = new SwMap(); + map.put("tableId", 718391823709507584L); + map.put("bean", true); + map.put("cache", true); + table.add(map); + + ModelFormService service = new ModelFormService(); + R r = service.buildJavaCode(params, null); + System.out.println(r.readSuccess()); + } +} diff --git a/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/SpelTest.java b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/SpelTest.java new file mode 100644 index 0000000..ad0990f --- /dev/null +++ b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/SpelTest.java @@ -0,0 +1,41 @@ +package cc.smtweb.system.bpm.test; + +import cc.smtweb.framework.core.common.SwMap; +import lombok.Data; +import org.junit.jupiter.api.Test; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +public class SpelTest { + @Test + public void test() { + //创建ExpressionParser解析表达式 + ExpressionParser parser = new SpelExpressionParser(); + //表达式放置 +// Expression exp = parser.parseExpression("T(java.lang.Math).random() + name + obj['name']"); + Expression exp = parser.parseExpression("T(java.lang.Math).random() > 10"); + + //向容器内添加bean + SpelContext spelContext = new SpelContext(); + spelContext.setName("ddd999"); + spelContext.getObj().put("name", "111abc"); +// ctx.setVariable("obj", beanA); + + StandardEvaluationContext ctx = new StandardEvaluationContext(spelContext); + /** 如果使用其他的容器,则用下面的方法 */ + //setRootObject并非必须;一个EvaluationContext只能有一个RootObject,引用它的属性时,可以不加前缀 +// ctx.setRootObject(XXX); + + //getValue有参数ctx,从新的容器中根据SpEL表达式获取所需的值 + Object value = exp.getValue(ctx, Boolean.class); + System.out.println(value); + } +} + +@Data +class SpelContext { + private String name; + private SwMap obj = new SwMap(); +} \ No newline at end of file diff --git a/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/TestMain.java b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/TestMain.java new file mode 100644 index 0000000..9b2943c --- /dev/null +++ b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/TestMain.java @@ -0,0 +1,110 @@ +package cc.smtweb.system.bpm.test; + +import cc.smtweb.framework.core.util.JsonUtil; +import cc.smtweb.system.bpm.web.design.form.ModelFormHelper; +import cc.smtweb.system.bpm.web.design.form.define.PageDatasetDynCond; + +import java.util.Collections; + +/** + * Created by Akmm at 2021/12/25 22:21 + */ +public class TestMain { + + public static void main(String[] args) throws Exception { + String js = "// 注册事件类\n" + + "window.$swEvent.setup(\"defaultEvent\", {\n" + + " /**\n" + + " *\n" + + " * @param page 当前页面对象\n" + + " * 1)page.$params 参数对象\n" + + " * 示例:给参数p1赋值: page.$params.p1 = “xxxx”;\n" + + " *\n" + + " * 2)page.$refs 控件的ref引用,ref引用指向控件的实例,可访问控件实例的属性和函数\n" + + " * 示例:调用页面的 标签的validate方法: page.$refs.form1.validate()\n" + + " *\n" + + " * 3)page.$model 数据集,内含data(数据对象)和dataset(数据集定义)\n" + + " * 示例: 获取数据集ds1的表单数据 page.$model.ds1.data.form\n" + + " * 获取数据集ds1的列表数据 page.$model.ds1.data.list\n" + + " * 获取数据集ds1表单中a1的值 page.$model.ds1.getFormVal(\"a1\")\n" + + " * 给数据集ds1的表中的a1赋值 page.$model.ds1.setFormVal(\"a1\",\"xxxx\");\n" + + " *\n" + + " * 4)page.$widgets 控件的属性,控制控件的响应属性\n" + + " * 示例 : 获取控件名为w1的required属性的值 page.$widgets.w1.required\n" + + " *\n" + + " * 5)page.$utils 工具包\n" + + " * $$message 消息提示\n" + + " * $$cookie, cookie\n" + + " * $$driver, 用户操作引导引擎\n" + + " * $$http, http请求\n" + + " * $$validate, 校验\n" + + " * $$date, 日期处理工具\n" + + " * $$UtilPub, 其他\n" + + " * 示例:\n" + + " * 弹出成功消息框:page.$utils.$$message.notify.success(\"xxx\")\n" + + " * post请求:page.$utils.$$http.post(\"/api/bpm/save\",{id:\"xxx\"})\n" + + " *\n" + + " * 6)page.$tabRouter 页面路由,控制页面切换\n" + + " * 示例:跳转到登录页:page.$tabRouter.push(\"login\");\n" + + " * 返回: page.$tabRouter.back();\n" + + " *\n" + + " * 7) page.$api 页面提供的公用api\n" + + " * add: () => void 页面新增初始化(所有可编辑的数据集)\n" + + " * addOne: (dataset: string) => void 指定数据集新增初始\n" + + " * load: (force?: boolean, params?: any) => void // 页面加载\n" + + " * loadOne: (dataset: string, params?: any) => void // 指定数据集加载\n" + + " * total: (dataset: string, params?: any) => void // 指定数据集求合计栏信息\n" + + " * save: (params?: any) => void // 页面保存 (所有可编辑的数据集)\n" + + " * saveOne: (dataset: string, params?: any) => void // 指定数据集保存\n" + + " * del: () => void 页面删除\n" + + " * delOne: (dataset: string, row?: any) => void // 指定数据集删除\n" + + " * closeDialog: (dialogKey?: string) => void // 关闭弹出框\n" + + " * 示例:\n" + + " * 加载数据集ds1:page.$api.loadOne(\"ds1\");\n" + + " *\n" + + " * @returns 返回给页面可配置的api方法\n" + + " * 如 : return {\n" + + " * demoFunc(){\n" + + " * XXXX\n" + + " * },\n" + + " * }\n" + + " */\n" + + " setup(page){\n" + + " const { $params,$refs, $widgets, $model, $utils, $tabRouter, $api } = page;\n" + + " const { $$message, $$http } = $utils || {};\n" + + " // 示例\n" + + " const demoFunc = () => {\n" + + " // 1.从参数中获取p1\n" + + " const p1 = $params.p1;\n" + + " // 2.从控件w1获取color属性\n" + + " const color = $widgets.w1.props.color;\n" + + " // 3.调用控件w1的calc函数\n" + + " const calcVal = $refs.w1.calc(p1,color);\n" + + " // 4.数据集ds1加载数据\n" + + " $api.loadOne(\"ds1\");\n" + + " // 5.给数据集ds1的表单中的f1字段赋值calcVal\n" + + " $model.ds1.setFormVal(\"f1\",calcVal);\n" + + " // 6.获取数据集ds1的表单数据\n" + + " const data = $model.ds1.data.form || {};\n" + + " // 7.调用http交互\n" + + " $$http.post(\"ap1/demo/doOpt\",data).then((rt) => {\n" + + " // 8.弹出成功消息\n" + + " $$message.notify.success(\"操作成功\");\n" + + " // 9.返回上一个页面\n" + + " $tabRouter.back();\n" + + " });\n" + + " };\n" + + " return {\n" + + " demoFunc, demoFunc1, demoFunc2,\n" + + " }\n" + + " }\n" + + "});"; + int index = js.lastIndexOf("return "); + if (index < 0) { + return; + } + index = js.indexOf("{", index); + js = js.substring(index + 1, js.indexOf("}", index)).trim(); + System.out.println(js.split(",")); + } +} diff --git a/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/ToolTest.java b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/ToolTest.java new file mode 100644 index 0000000..bb385c8 --- /dev/null +++ b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/ToolTest.java @@ -0,0 +1,54 @@ +package cc.smtweb.system.bpm.test; + +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.util.JsonUtil; +import cc.smtweb.system.bpm.spring.BpmApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by Akmm at 2022/5/24 18:40 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BpmApplication.class) +public class ToolTest { + @Test + public void resetTable() { + ModelTableCache cache = ModelTableCache.getInstance(); + EntityDao dao = DbEngine.getInstance().findDao(ModelTable.class); + Collection list = new ArrayList<>(cache.getAll()); + for (ModelTable table: list) { + table.setName(table.getName().toUpperCase()); + List fields = table.getFields(); + for (ModelField field: fields) { + field.setName(field.getName().toLowerCase()); + if ("COMMENT".equalsIgnoreCase(field.getDataType())) field.setDataType(SwEnum.DataType.REMARK.value); + SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(field.getDataType()); + if (dtb == null) { + System.out.println(table.getName() + "." + field.getName() + "字段类型错误:[" + field.getDataType() + "]"); + continue; + } + field.setDataType(dtb.value); + } + SwMap map = new SwMap(); + map.put("fields", table.getFields()); + map.put("indexes", table.getIndexes()); + map.put("caches", table.getCaches()); + table.getData().put("tb_content", JsonUtil.encodeString(map)); + dao.updateEntity(table); + cache.put(table); + } + } +} diff --git a/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/TreeDataBuilderTest.java b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/TreeDataBuilderTest.java new file mode 100644 index 0000000..06f5271 --- /dev/null +++ b/smtweb-framework/bpm/src/test/java/cc/smtweb/system/bpm/test/TreeDataBuilderTest.java @@ -0,0 +1,97 @@ +package cc.smtweb.system.bpm.test; + +import cc.smtweb.system.bpm.util.ITreeDataLevelHandler; +import cc.smtweb.system.bpm.util.TreeDataUtil; +import lombok.Data; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +public class TreeDataBuilderTest { + @Test + public void testFindParent() { + // 树结构数据句柄 + TreeDataHandler handler = new TreeDataHandler(); + + List list = new ArrayList<>(); + list.add(new TreeData(1L, null)); + list.add(new TreeData(2L, 1L)); + list.add(new TreeData(3L, 2L)); + list.add(new TreeData(4L, 3L)); + list.add(new TreeData(5L, 6L)); + + TreeData root = new TreeData(); + + TreeDataUtil.buildTree(root, list, handler); + + { + TreeData node = TreeDataUtil.findParent(root, 4L, 1, handler); + Assertions.assertEquals(1L, node.getId()); + } + + { + TreeData node = TreeDataUtil.findParent(root, 3L, 1, handler); + Assertions.assertEquals(1L, node.getId()); + } + + { + TreeData node = TreeDataUtil.findParent(root, 3L, 2, handler); + Assertions.assertEquals(2L, node.getId()); + } + + { + TreeData node = TreeDataUtil.findParent(root, 1L, 2, handler); + Assertions.assertNull(node); + } + } +} + +@Data +class TreeData { + private Long id; + private Long parentId; + private int level; + private List children; + + TreeData() { + } + + TreeData(Long id, Long parentId) { + this.id = id; + this.parentId = parentId; + } +} + +class TreeDataHandler implements ITreeDataLevelHandler { + @Override + public Long getId(TreeData node) { + return node.getId(); + } + + @Override + public Long getParentId(TreeData node) { + return node.getParentId(); + } + + @Override + public List getChildren(TreeData node) { + return node.getChildren(); + } + + @Override + public void setChildren(TreeData node, List children) { + node.setChildren(children); + } + + @Override + public int getLevel(TreeData node) { + return node.getLevel(); + } + + @Override + public void setLevel(TreeData node, int level) { + node.setLevel(level); + } +} diff --git a/smtweb-framework/bpm/src/test/resources/code/index.vue b/smtweb-framework/bpm/src/test/resources/code/index.vue new file mode 100644 index 0000000..b0cf895 --- /dev/null +++ b/smtweb-framework/bpm/src/test/resources/code/index.vue @@ -0,0 +1,116 @@ + + + + + + + + diff --git a/smtweb-framework/bpm/src/test/resources/code/index.vue.tmp b/smtweb-framework/bpm/src/test/resources/code/index.vue.tmp new file mode 100644 index 0000000..44e8a73 --- /dev/null +++ b/smtweb-framework/bpm/src/test/resources/code/index.vue.tmp @@ -0,0 +1,119 @@ + + + + + + + + diff --git a/smtweb-framework/bpm/src/test/resources/code/list.xml b/smtweb-framework/bpm/src/test/resources/code/list.xml new file mode 100644 index 0000000..22bebe5 --- /dev/null +++ b/smtweb-framework/bpm/src/test/resources/code/list.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/smtweb-framework/bpm/src/test/resources/db/smt_uc.json b/smtweb-framework/bpm/src/test/resources/db/smt_uc.json new file mode 100644 index 0000000..3505ab3 --- /dev/null +++ b/smtweb-framework/bpm/src/test/resources/db/smt_uc.json @@ -0,0 +1 @@ +{"type":"chart","props":{"name":"_test_user","label":"测试用户数据库"},"nodes":[{"id":"node-172fda7eb8f","type":"table","props":{"label":"用户信息","name":"sys_user"},"columns":[{"type":"field","props":{"label":"ID","name":"user_id","dataType":"long","notNull":true,"keyType":"primary"},"id":"column-172fda7eb90"},{"id":"col-173284e59df","type":"field","label":"name","props":{"label":"姓名","name":"user_name","dataType":"char","notNull":true,"dataLength":"50"}},{"id":"column-175ba645939","type":"field","props":{"label":"部门ID","name":"user_dept_id","dataType":"long","keyType":"foreign","fkTable":"sys_dept"}},{"id":"column-175ba64593b","type":"field","props":{"label":"性别","name":"user_sex","dataType":"int","defaultValue":"0"}}],"left":101.3125,"top":34,"selected":false},{"id":"node-1746c68deac","type":"table","props":{"name":"sys_dept","label":"部门"},"columns":[{"id":"column-1746c68dead","type":"field","props":{"name":"dept_id","label":"ID","dataType":"long","notNull":true,"keyType":"primary"}},{"id":"column-175923f5b94","type":"field","props":{"label":"名称","name":"dept_name","dataType":"char"}},{"id":"column-175923f5b95","type":"field","props":{"label":"上级ID","name":"dept_parent_id","dataType":"long","keyType":"foreign","fkTable":"sys_dept"}},{"id":"column-175923f5b96","type":"field","props":{"label":"显示顺序","name":"dept_order","dataType":"int","defaultValue":"0"}}]},{"id":"node-174b89aabaf","type":"table","props":{"name":"fire_base_info","label":"基本概况"},"columns":[{"id":"column-174b89aabb0","type":"field","props":{"label":"ID","name":"bi_id","dataType":"long","keyType":"primary","notNull":true}},{"id":"column-174b89aabb1","type":"field","props":{"label":"单位名称","dataType":"char"}},{"id":"column-174b89aabb2","type":"field","props":{"label":"地址","dataType":"char"}},{"id":"column-174b89aabb3","type":"field","props":{"label":"登记类别","dataType":"char"}},{"id":"column-174b89aabb4","type":"field","props":{"label":"消防安全重点单位序码","dataType":"char"}},{"id":"column-174b89aabb5","type":"field","props":{"label":"单位性质","dataType":"char"}},{"id":"column-174b89aabb6","type":"field","props":{"label":"上级主管部门","dataType":"char"}},{"id":"column-174b89aabb7","type":"field","props":{"label":"消防安全责任人","dataType":"char"}},{"id":"column-174b89aabb8","type":"field","props":{"label":"消防安全责任人联系电话","dataType":"char"}},{"id":"column-174b89aabb9","type":"field","props":{"label":"消防安全责任人归口管理部门负责人","dataType":"char"}},{"id":"column-174b89aabba","type":"field","props":{"label":"消防安全责任人联系电话","dataType":"char"}},{"id":"column-174b89aabbb","type":"field","props":{"label":"消防安全管理人","dataType":"char"}},{"id":"column-174b89aabbc","type":"field","props":{"label":"消防安全管理人联系电话","dataType":"char"}},{"id":"column-174b89aabbd","type":"field","props":{"label":"消防安全管理人归口管理部门负责人","dataType":"char"}},{"id":"column-174b89aabbe","type":"field","props":{"label":"消防安全管理人联系电话","dataType":"char"}},{"id":"column-174b89aabbf","type":"field","props":{"label":"专职消防队负责人","dataType":"char"}},{"id":"column-174b89aabc0","type":"field","props":{"label":"专职消防队人数","dataType":"char"}},{"id":"column-174b89aabc1","type":"field","props":{"label":"专职消防队电话","dataType":"char"}},{"id":"column-174b89aabc2","type":"field","props":{"label":"主要灭火装备","dataType":"char"}},{"id":"column-174b89aabc3","type":"field","props":{"label":"供电情况","dataType":"char"}},{"id":"column-174b89aabc4","type":"field","props":{"label":"电力负荷等级","dataType":"char"}},{"id":"column-174b89aabc5","type":"field","props":{"label":"用电设备负荷(KW)","dataType":"char"}},{"id":"column-174b89aabc6","type":"field","props":{"label":"实际用电量(KW)","dataType":"char"}},{"id":"column-174b89aabc7","type":"field","props":{"label":"市政进水管数量及管径","dataType":"char"}},{"id":"column-174b89aabc8","type":"field","props":{"label":"天然消防水源数及容量","dataType":"char"}},{"id":"column-174b89aabc9","type":"field","props":{"label":"室内管网形式","dataType":"char"}},{"id":"column-174b89aabca","type":"field","props":{"label":"室外管网形式","dataType":"char"}},{"id":"column-174b89aabcb","type":"field","props":{"label":"室内最不利点消火栓压力","dataType":"char"}},{"id":"column-174b89aabcc","type":"field","props":{"label":"室外最不利点消火栓压力","dataType":"char"}},{"id":"column-174b89aabcd","type":"field","props":{"label":"消防安全重点部位名称","dataType":"char"}},{"id":"column-174b89aabce","type":"field","props":{"label":"是否已审核","dataType":"bool","notNull":true,"defaultValue":"false"}},{"id":"column-174b89aabcf","type":"field","props":{"label":"是否已验收","dataType":"bool","notNull":true,"defaultValue":"false"}},{"id":"column-174b89aabd0","type":"field","props":{"label":"备注","dataType":"char"}}]},{"id":"node-174b89aabd1","type":"table","props":{"name":"fire_emergency_plan","label":"灭火和应急疏散方案"},"columns":[{"id":"column-174b89aabd2","type":"field","props":{"label":"ID","name":"ep_id","dataType":"long","notNull":true,"keyType":"primary"}},{"id":"column-174b89aabd3","type":"field","props":{"label":"单位名称","dataType":"char"}},{"id":"column-174b89aabd4","type":"field","props":{"label":"单位地址","dataType":"char"}},{"id":"column-174b89aabd5","type":"field","props":{"label":"辖区公安消防队","dataType":"char"}},{"id":"column-174b89aabd6","type":"field","props":{"label":"增援消防队","dataType":"char"}},{"id":"column-174b89aabd7","type":"field","props":{"label":"消防安全责任人","dataType":"char"}},{"id":"column-174b89aabd8","type":"field","props":{"label":"联系电话","dataType":"char"}},{"id":"column-174b89aabd9","type":"field","props":{"label":"专职消防队队长","dataType":"char"}},{"id":"column-174b89aabda","type":"field","props":{"label":"专职消防队人数","dataType":"char"}},{"id":"column-174b89aabdb","type":"field","props":{"label":"专职消防队车辆数","dataType":"char"}},{"id":"column-174b89aabdc","type":"field","props":{"label":"义务消防队队长","dataType":"char"}},{"id":"column-174b89aabdd","type":"field","props":{"label":"义务消防队人数","dataType":"char"}},{"id":"column-174b89aabde","type":"field","props":{"label":"义务消防队主要装备","dataType":"char"}},{"id":"column-174b89aabdf","type":"field","props":{"label":"机构组织总指挥","dataType":"char"}},{"id":"column-174b89aabe0","type":"field","props":{"label":"机构组织副总指挥","dataType":"char"}},{"id":"column-174b89aabe1","type":"field","props":{"label":"机构组织灭火组","dataType":"char"}},{"id":"column-174b89aabe2","type":"field","props":{"label":"机构组织通讯组","dataType":"char"}},{"id":"column-174b89aabe3","type":"field","props":{"label":"机构组织疏散组","dataType":"char"}},{"id":"column-174b89aabe4","type":"field","props":{"label":"机构组织救护组","dataType":"char"}},{"id":"column-174b89aabe5","type":"field","props":{"label":"报警方式","dataType":"char"}},{"id":"column-174b89aabe6","type":"field","props":{"label":"报警和接警程序","dataType":"char"}},{"id":"column-174b89aabe7","type":"field","props":{"label":"重点部位1","dataType":"char"}},{"id":"column-174b89aabe8","type":"field","props":{"label":"重点部位2","dataType":"char"}},{"id":"column-174b89aabe9","type":"field","props":{"label":"应急疏散程序及措施","dataType":"char"}},{"id":"column-174b89aabea","type":"field","props":{"label":"扑救初起火灾程序及措施","dataType":"char"}},{"id":"column-174b89aabeb","type":"field","props":{"label":"通讯联络、安全防护的程序和措施","dataType":"char"}}]},{"id":"node-174de176370","type":"table","props":{"name":"fire_important_part","label":"消防安全重点部位","remark":"基本概况的子表"},"columns":[{"id":"column-174de176371","type":"field","props":{"label":"ID","name":"ip_id","dataType":"long","keyType":"primary","notNull":true}},{"id":"column-174de176373","type":"field","props":{"label":"基本概况","name":"ip_bi_id","keyType":"foreign","notNull":true,"remark":"基本概况ID","fkTable":"fire_base_info"}},{"id":"column-174de176372","type":"field","props":{"label":"部位名称","name":"ip_name","dataType":"char"}}]}]} \ No newline at end of file diff --git a/smtweb-framework/bpm/src/test/resources/template/index.vm b/smtweb-framework/bpm/src/test/resources/template/index.vm new file mode 100644 index 0000000..65568b5 --- /dev/null +++ b/smtweb-framework/bpm/src/test/resources/template/index.vm @@ -0,0 +1,63 @@ +#set($ui_widgets = []) +#macro(ui_print_vue $parent) + #if($parent.shape == 'ui-panel') + <$parent.data.type v-bind="pages.widgets.$parent.data.id"> + #foreach($child in $parent.children) + #ui_print_vue(${child}) + #end + + #else + <$parent.data.type v-bind="pages.widgets.$parent.data.id" @action="onWidgetAction($parent.data.id.props.dataset, $event)" :data="data"/> + #end + $ui_widgets.add($parent.data) +#end + + + + + diff --git a/smtweb-framework/bpm/src/test/resources/ui/508660168293093376.json b/smtweb-framework/bpm/src/test/resources/ui/508660168293093376.json new file mode 100644 index 0000000..3eb4063 --- /dev/null +++ b/smtweb-framework/bpm/src/test/resources/ui/508660168293093376.json @@ -0,0 +1,1115 @@ +{ + "version": 2, + "page": { + "type": "fx-page", + "props": { + "title": "基本情况编辑" + } + }, + "graph": { + "x": 1, + "y": 1, + "w": 1000, + "h": 720, + "zIndex": 1, + "shape": "ui-panel", + "data": { + "id": "root", + "type": "fz-split-panel", + "layout": { + "name": "split" + }, + "props": { + "horizontal": true + } + }, + "children": [{ + "x": 1, + "y": 1, + "w": 1000, + "h": 720, + "zIndex": 2, + "shape": "ui-panel", + "data": { + "id": "p1", + "type": "fz-form-panel", + "layout": { + "name": "form" + }, + "props": { + "paddingX": 4, + "paddingY": 4, + "label": "面板", + "colNum": 2, + "minHeight": 400, + "dataset": "widget-17424353df4" + } + }, + "children": [{ + "x": 503, + "y": 797, + "w": 494, + "h": 40, + "zIndex": 101, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9fb", + "type": "fx-switch", + "props": { + "label": "是否已验收", + "labelWidth": 120, + "activeValue": "1", + "inactiveValue": "0", + "activeColor": "#409EFF", + "inactiveColor": "#C0CCDA", + "field": "id-1755410a9db", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 797, + "w": 494, + "h": 40, + "zIndex": 102, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f8", + "type": "fx-text", + "props": { + "label": "室外最不利点消火栓压力", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d8", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 753, + "w": 494, + "h": 40, + "zIndex": 103, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f6", + "type": "fx-text", + "props": { + "label": "室外管网形式", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d6", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 753, + "w": 494, + "h": 40, + "zIndex": 104, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f1", + "type": "fx-text", + "props": { + "label": "用电设备负荷(KW)", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d1", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 709, + "w": 494, + "h": 40, + "zIndex": 105, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9ec", + "type": "fx-text", + "props": { + "label": "人数", + "type": "text", + "maxlength": 50, + "placeholder": "专职消防队人数", + "labelWidth": 120, + "field": "id-1755410a9cc", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 709, + "w": 494, + "h": 40, + "zIndex": 106, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9ea", + "type": "fx-text", + "props": { + "label": "联系电话", + "type": "text", + "maxlength": 50, + "placeholder": "归口管理部门负责人联系电话", + "labelWidth": 120, + "field": "id-1755410a9ca", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 665, + "w": 494, + "h": 40, + "zIndex": 107, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e8", + "type": "fx-text", + "props": { + "label": "联系电话", + "type": "text", + "maxlength": 50, + "placeholder": "消防安全管理人联系电话", + "labelWidth": 120, + "field": "id-1755410a9c8", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 665, + "w": 494, + "h": 40, + "zIndex": 108, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e6", + "type": "fx-text", + "props": { + "label": "联系电话", + "type": "text", + "maxlength": 50, + "placeholder": "归口管理部门负责人联系电话", + "labelWidth": 120, + "field": "id-1755410a9c6", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 621, + "w": 494, + "h": 40, + "zIndex": 109, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e4", + "type": "fx-text", + "props": { + "label": "联系电话", + "type": "text", + "maxlength": 50, + "placeholder": "消防安全责任人联系电话", + "labelWidth": 120, + "field": "id-1755410a9c4", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 621, + "w": 494, + "h": 40, + "zIndex": 110, + "shape": "vue-shape", + "data": { + "id": "widget-1755456a2bc", + "type": "fx-textarea", + "props": { + "label": "备注", + "type": "textarea", + "maxlength": 200, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9dc", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 577, + "w": 494, + "h": 40, + "zIndex": 111, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9df", + "type": "fx-text", + "props": { + "label": "登记类别", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9bf", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 577, + "w": 494, + "h": 40, + "zIndex": 112, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e0", + "type": "fx-text", + "props": { + "label": "消防安全重点单位序码", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9c0", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 533, + "w": 494, + "h": 40, + "zIndex": 113, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9fa", + "type": "fx-switch", + "props": { + "label": "是否已审核", + "labelWidth": 120, + "activeValue": "1", + "inactiveValue": "0", + "activeColor": "#409EFF", + "inactiveColor": "#C0CCDA", + "field": "id-1755410a9da", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 533, + "w": 494, + "h": 40, + "zIndex": 114, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f5", + "type": "fx-text", + "props": { + "label": "室内管网形式", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d5", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 489, + "w": 494, + "h": 40, + "zIndex": 115, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f0", + "type": "fx-text", + "props": { + "label": "电力负荷等级", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d0", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 489, + "w": 494, + "h": 40, + "zIndex": 116, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e1", + "type": "fx-text", + "props": { + "label": "单位性质", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9c1", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 445, + "w": 494, + "h": 40, + "zIndex": 117, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e2", + "type": "fx-text", + "props": { + "label": "上级主管部门", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9c2", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 445, + "w": 494, + "h": 40, + "zIndex": 118, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f3", + "type": "fx-text", + "props": { + "label": "市政进水管数量及管径", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d3", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 401, + "w": 494, + "h": 40, + "zIndex": 119, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f4", + "type": "fx-text", + "props": { + "label": "天然消防水源数及容量", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d4", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 401, + "w": 494, + "h": 40, + "zIndex": 120, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f9", + "type": "fx-text", + "props": { + "label": "消防安全重点部位名称", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d9", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 357, + "w": 494, + "h": 40, + "zIndex": 121, + "shape": "vue-shape", + "data": { + "id": "widget-1755456a2bb", + "type": "fx-divider", + "props": { + "label": "", + "contentPosition": "left", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 357, + "w": 494, + "h": 40, + "zIndex": 122, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f7", + "type": "fx-text", + "props": { + "label": "室内最不利点消火栓压力", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d7", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 313, + "w": 494, + "h": 40, + "zIndex": 123, + "shape": "vue-shape", + "data": { + "id": "widget-1755456a2ba", + "type": "fx-divider", + "props": { + "label": "消防给水情况", + "contentPosition": "left", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 313, + "w": 494, + "h": 40, + "zIndex": 124, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9f2", + "type": "fx-text", + "props": { + "label": "实际用电量(KW)", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9d2", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 269, + "w": 494, + "h": 40, + "zIndex": 125, + "shape": "vue-shape", + "data": { + "id": "widget-1755456a2b9", + "type": "fx-divider", + "props": { + "label": "供电情况", + "contentPosition": "left", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 269, + "w": 494, + "h": 40, + "zIndex": 126, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9ee", + "type": "fx-text", + "props": { + "label": "主要灭火装备", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9ce", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 225, + "w": 494, + "h": 40, + "zIndex": 127, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9ed", + "type": "fx-text", + "props": { + "label": "电话", + "type": "text", + "maxlength": 50, + "placeholder": "专职消防队电话", + "labelWidth": 120, + "field": "id-1755410a9cd", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 225, + "w": 494, + "h": 40, + "zIndex": 128, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9eb", + "type": "fx-text", + "props": { + "label": "负责人", + "type": "text", + "maxlength": 50, + "placeholder": "专职消防队负责人", + "labelWidth": 120, + "field": "id-1755410a9cb", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 181, + "w": 494, + "h": 40, + "zIndex": 129, + "shape": "vue-shape", + "data": { + "id": "widget-1755456a2b8", + "type": "fx-divider", + "props": { + "label": "专职消防队", + "contentPosition": "left", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 181, + "w": 494, + "h": 40, + "zIndex": 130, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e9", + "type": "fx-text", + "props": { + "label": "归口管理部门负责人", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9c9", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 137, + "w": 494, + "h": 40, + "zIndex": 131, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e7", + "type": "fx-text", + "props": { + "label": "消防安全管理人", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9c7", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 137, + "w": 494, + "h": 40, + "zIndex": 132, + "shape": "vue-shape", + "data": { + "id": "widget-1755456a2b7", + "type": "fx-divider", + "props": { + "label": "消防安全管理人", + "contentPosition": "left", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 93, + "w": 494, + "h": 40, + "zIndex": 133, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e5", + "type": "fx-text", + "props": { + "label": "归口管理部门负责人", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9c5", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 93, + "w": 494, + "h": 40, + "zIndex": 134, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9e3", + "type": "fx-text", + "props": { + "label": "消防安全责任人", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9c3", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 49, + "w": 494, + "h": 40, + "zIndex": 135, + "shape": "vue-shape", + "data": { + "id": "widget-1755456a2b6", + "type": "fx-divider", + "props": { + "label": "消防安全责任人", + "contentPosition": "left", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 49, + "w": 494, + "h": 40, + "zIndex": 136, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9de", + "type": "fx-text", + "props": { + "label": "地址", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9be", + "required": true, + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 503, + "y": 5, + "w": 494, + "h": 40, + "zIndex": 137, + "shape": "vue-shape", + "data": { + "id": "id-1755410a9dd", + "type": "fx-text", + "props": { + "label": "单位名称", + "type": "text", + "maxlength": 50, + "placeholder": "请输入内容", + "labelWidth": 120, + "field": "id-1755410a9bc", + "required": true, + "dataset": "widget-17424353df4" + } + }, + "children": [] + }, { + "x": 5, + "y": 5, + "w": 494, + "h": 40, + "zIndex": 138, + "shape": "vue-shape", + "data": { + "id": "widget-175547b3b04", + "type": "fx-button-group", + "props": { + "gutter": 16, + "LineSpace": 8, + "buttons": [{ + "id": "col-175547b3b11", + "type": "fx-button", + "w": 1, + "h": 1, + "value": null, + "props": { + "label": "返回", + "span": 8, + "type": "success", + "size": "mini", + "plain": true, + "action": "return" + } + }, { + "type": "fx-button", + "props": { + "label": "提交", + "type": "primary", + "size": "mini", + "plain": false, + "round": false, + "circle": false, + "autofocus": false, + "action": "submit" + }, + "id": "id-175547b3b05" + }, { + "id": "col-175547b3b09", + "type": "fx-button", + "w": 1, + "h": 1, + "value": null, + "props": { + "label": "删除", + "span": 8, + "type": "danger", + "size": "mini", + "action": "remove" + } + }], + "lineSpace": 8, + "justifyContent": "flex-start", + "slot": "header", + "dataset": "widget-17424353df4" + } + }, + "children": [] + }] + }] + }, + "model": [{ + "id": "widget-17424353df4", + "type": "fz-dataset", + "value": null, + "props": { + "label": "数据集", + "fields": [{ + "id": "id-1755410a9bc", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb1", + "label": "单位名称" + } + }, { + "id": "id-1755410a9bd", + "type": "fz-field-long", + "props": { + "field": "column-174b89aabb0", + "name": "bi_id", + "label": "ID" + } + }, { + "id": "id-1755410a9be", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb2", + "label": "地址" + } + }, { + "id": "id-1755410a9bf", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb3", + "label": "登记类别" + } + }, { + "id": "id-1755410a9c0", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb4", + "label": "消防安全重点单位序码" + } + }, { + "id": "id-1755410a9c1", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb5", + "label": "单位性质" + } + }, { + "id": "id-1755410a9c2", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb6", + "label": "上级主管部门" + } + }, { + "id": "id-1755410a9c3", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb7", + "label": "消防安全责任人" + } + }, { + "id": "id-1755410a9c4", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb8", + "label": "消防安全责任人联系电话" + } + }, { + "id": "id-1755410a9c5", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabb9", + "label": "消防安全责任人归口管理部门负责人" + } + }, { + "id": "id-1755410a9c6", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabba", + "label": "消防安全责任人联系电话" + } + }, { + "id": "id-1755410a9c7", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabbb", + "label": "消防安全管理人" + } + }, { + "id": "id-1755410a9c8", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabbc", + "label": "消防安全管理人联系电话" + } + }, { + "id": "id-1755410a9c9", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabbd", + "label": "消防安全管理人归口管理部门负责人" + } + }, { + "id": "id-1755410a9ca", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabbe", + "label": "消防安全管理人联系电话" + } + }, { + "id": "id-1755410a9cb", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabbf", + "label": "专职消防队负责人" + } + }, { + "id": "id-1755410a9cc", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc0", + "label": "专职消防队人数" + } + }, { + "id": "id-1755410a9cd", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc1", + "label": "专职消防队电话" + } + }, { + "id": "id-1755410a9ce", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc2", + "label": "主要灭火装备" + } + }, { + "id": "id-1755410a9cf", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc3", + "label": "供电情况" + } + }, { + "id": "id-1755410a9d0", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc4", + "label": "电力负荷等级" + } + }, { + "id": "id-1755410a9d1", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc5", + "label": "用电设备负荷(KW)" + } + }, { + "id": "id-1755410a9d2", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc6", + "label": "实际用电量(KW)" + } + }, { + "id": "id-1755410a9d3", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc7", + "label": "市政进水管数量及管径" + } + }, { + "id": "id-1755410a9d4", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc8", + "label": "天然消防水源数及容量" + } + }, { + "id": "id-1755410a9d5", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabc9", + "label": "室内管网形式" + } + }, { + "id": "id-1755410a9d6", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabca", + "label": "室外管网形式" + } + }, { + "id": "id-1755410a9d7", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabcb", + "label": "室内最不利点消火栓压力" + } + }, { + "id": "id-1755410a9d8", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabcc", + "label": "室外最不利点消火栓压力" + } + }, { + "id": "id-1755410a9d9", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabcd", + "label": "消防安全重点部位名称" + } + }, { + "id": "id-1755410a9da", + "type": "fz-field-bool", + "props": { + "field": "column-174b89aabce", + "label": "是否已审核" + } + }, { + "id": "id-1755410a9db", + "type": "fz-field-bool", + "props": { + "field": "column-174b89aabcf", + "label": "是否已验收" + } + }, { + "id": "id-1755410a9dc", + "type": "fz-field-char", + "props": { + "field": "column-174b89aabd0", + "label": "备注" + } + }], + "datasource": "smt_uc", + "table": "node-174b89aabaf", + "tableType": "master" + }, + "events": {}, + "apis": {} + }] +} diff --git a/smtweb-framework/core/pom.xml b/smtweb-framework/core/pom.xml new file mode 100644 index 0000000..1c29d60 --- /dev/null +++ b/smtweb-framework/core/pom.xml @@ -0,0 +1,207 @@ + + + cc.smtweb + sw-framework-core + 3.1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.5.6 + + + + 4.0.0 + + + + UTF-8 + UTF-8 + 1.8 + 1.8 + 1.8 + true + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + + com.fasterxml.jackson.core + jackson-core + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + + io.lettuce + lettuce-core + 6.1.5.RELEASE + + + org.apache.commons + commons-pool2 + 2.11.1 + + + + commons-codec + commons-codec + 1.15 + + + + + com.esotericsoftware + kryo + 4.0.0 + + + org.projectlombok + lombok + 1.18.22 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + org.apache.commons + commons-jexl3 + 3.2.1 + + + + org.apache.tika + tika-core + 2.1.0 + + + + com.github.ben-manes.caffeine + caffeine + + + + mysql + mysql-connector-java + 8.0.27 + runtime + + + commons-collections + commons-collections + 3.2.2 + compile + + + + org.junit.platform + junit-platform-launcher + 1.6.2 + test + + + + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + org.junit.vintage + junit-vintage-engine + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-params + 5.6.2 + test + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + verify + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + config/*.yaml + + + + + + + + + + + + + + + + + + + nexus-releases + Nexus Release Repository + http://47.92.149.153:7000/repository/maven-releases/ + + + nexus-snapshots + Nexus Snapshot Repository + http://47.92.149.153:7000/repository/maven-snapshots/ + + + diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplication.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplication.java new file mode 100644 index 0000000..5c73f81 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplication.java @@ -0,0 +1,11 @@ +package cc.smtweb.framework.core; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CoreApplication { + public static void main(String[] args) { + SpringApplication.run(CoreApplication.class, args); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwAttr.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwAttr.java new file mode 100644 index 0000000..e9c3675 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwAttr.java @@ -0,0 +1,16 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.*; + +/** + * 参数注解,request定制的上下文内容,定制使用 + * @author kevin + * + */ + +@Target( { ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SwAttr { + String value() default ""; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwBean.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwBean.java new file mode 100644 index 0000000..31b4376 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwBean.java @@ -0,0 +1,22 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 被该注释修饰的类提供服务,如Dao,Service等 + * @author kevin + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface SwBean { + String value() default ""; + + /** + * 是否强行生成对象,不检查单例 + * @return 是否强行生成对象 + */ + boolean alwaysCreate() default false; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwBody.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwBody.java new file mode 100644 index 0000000..50ff91b --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwBody.java @@ -0,0 +1,15 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.*; + +/** + * 参数注解,当编译器无法找到参数名称时,需要用该注解标明参数名称,当然你也可以用该参数标注参数别名与表单域字段名同意 + * @author kevin + * + */ +@Target( { ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SwBody { + String value() default ""; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwColumn.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwColumn.java new file mode 100644 index 0000000..c4d88ed --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwColumn.java @@ -0,0 +1,38 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 被该注释修饰的方法对应了字段名和类型 + * @author kevin + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface SwColumn { + String value() default ""; + + /** 字段作用,前端用RefType表示 */ + Type[] type() default {}; + + public static enum Type { + // 主键 + ID, + // 上级ID,树结构需要 + PARENT_ID, + // 排序字段,树结构需要 + ORDER, + // 编码字段 + CODE, + // 名词字段 + NAME, + // 主表ID,MapToOne + MASTER_ID, + // 创建时间 + CREATE_TIME, + // 更新时间 + LAST_TIME, + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwConstruct.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwConstruct.java new file mode 100644 index 0000000..ed9eef5 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwConstruct.java @@ -0,0 +1,20 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 通过对@SwService/@SwBean类中的函数注解,服务启动时会调用一次被注解的函数 + * @author kevin + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface SwConstruct { + /** + * 销毁顺序,值越小越先创建 + * @return 销毁顺序值 + */ + int order() default 0; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwDestroy.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwDestroy.java new file mode 100644 index 0000000..da89811 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwDestroy.java @@ -0,0 +1,20 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 通过对@SwService/@SwBean类中的函数注解,服务停止时会调用一次被注解的函数 + * @author kevin + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface SwDestroy { + /** + * 销毁顺序,值越大越先销毁 + * @return 销毁顺序值 + */ + int order() default 0; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwParam.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwParam.java new file mode 100644 index 0000000..033d671 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwParam.java @@ -0,0 +1,18 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.*; + + +/** + * 参数注解,当编译器无法找到参数名称时,需要用该注解标明参数名称,当然你也可以用该参数标注参数别名与表单域字段名同意 + * @author kevin + * + */ +@Target( { ElementType.PARAMETER, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SwParam { + String value() default ""; + /** 注入类型,有多个类实现/子类时使用 */ + Class type() default Object.class; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwPerm.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwPerm.java new file mode 100644 index 0000000..0ef2c48 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwPerm.java @@ -0,0 +1,21 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 被该注释修饰的方法都会经过切面拦截校验权限,默认是需要已登录权限 + * @author kevin + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface SwPerm { + /** 无权限控制的值,在函数上注解@SwPerm(SwPerm.NONE) */ + static final String NONE = "*"; + static final String SESSION = ""; + + /** 权限定义值 */ + String value() default SESSION; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwScheduling.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwScheduling.java new file mode 100644 index 0000000..261f1f0 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/annotation/SwScheduling.java @@ -0,0 +1,30 @@ +package cc.smtweb.framework.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 通过对@SwService/@SwBean类中的函数注解,定时任务方法注解 + * + * @author xkliu + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value={ElementType.METHOD}) +public @interface SwScheduling { + /** + * 时间触发条件,如果值是单数字就是用秒定时,否则就是采用linux/unux crondtab 样式 + */ + String value(); + + /** + * 定时任务分组条件, 有值时同一分组不允许并发执行 + */ + String group() default ""; + + /** + * 是否支持多服务同时运行 + */ + boolean multiServer() default false; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java new file mode 100644 index 0000000..8ba38ba --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java @@ -0,0 +1,515 @@ +package cc.smtweb.framework.core.cache; + +import cc.smtweb.framework.core.annotation.SwCache; +import cc.smtweb.framework.core.cache.redis.RedisBroadcastEvent; +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.util.CommUtil; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.io.Serializable; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * 封装caffeine的抽象Cache类,实现内存缓存,并支持用redis广播进行数据缓存同步 + * + * @param <> 缓存的值类 + * @author zhenggm + */ +@Slf4j +public abstract class AbstractCache implements ISwCache { + + protected final static int LS_NONE = 0; + protected final static int LS_LOADING = 1; + protected final static int LS_LOADED = 2; + + //唯一标识 + protected String ident; + //展示名称 + protected String title; + //是否懒加载,懒加载时,将不从库loadall + protected boolean lazy; + //依赖 + protected String[] depends; + + //数据加载状态 + private short loadStatu = LS_NONE; + protected Class pTypeClass = null; + + + private LoadingCache cache; + private Map cacheOrg = new ConcurrentHashMap<>(); + //本地缓存对象,按List缓存,减轻redis压力 + protected Map> mapListLocal = new ConcurrentHashMap<>(); + //本地按其他键值缓存的对象 + protected Map> mapMapLocal = new ConcurrentHashMap<>(); + + /*注册要按list缓存的信息,key=list的类别,按什么字段来缓存。IGetBeanKey为根据bean获取此bean的key + 如资金科目明细项,需按资金科目缓存List。key=sc,value=class_id + */ + protected Map> mapListReg = new HashMap<>(); + protected Map> mapListRegEx = new HashMap<>(); + protected Map> mapMapReg = new HashMap<>(); + + public AbstractCache() { + pTypeClass = CommUtil.getParameterizedType(getClass()); + } + + //注册 + protected void install(ScheduledExecutorService executorService) { + SwCache swCache = this.getClass().getAnnotation(SwCache.class); + if (swCache != null) { + ident = swCache.ident(); + title = swCache.title(); + lazy = swCache.lazy(); + depends = StringUtils.split(swCache.depends(), ","); + } + final @NonNull Caffeine kvCaffeine = Caffeine.newBuilder() + .scheduler(Scheduler.forScheduledExecutorService(executorService)); + if (swCache != null && swCache.timeout() > 0) { + kvCaffeine.expireAfterAccess(swCache.timeout(), TimeUnit.MINUTES); + } + this.cache = kvCaffeine.build(this::onLoad); + } + + public boolean isNotInited() { + return loadStatu == LS_NONE; + } + + /** + * 注册标识,用于同步数据事件通知 + */ + public String getIdent() { + return ident; + } + + public String getTitle() { + return title; + } + + public boolean isLazy() { + return lazy; + } + + public String[] getDepends() { + return depends; + } + + /** + * 初始化 + * redis有,则从redis下载; + * 否则,非lazy,从数据库加载,并更新redis + */ + protected void init() { + if (RedisManager.getInstance().exists(getIdent())) { + log.info("从redis同步缓存!(" + getTitle() + ")"); + //从缓存服务器下载到本地 + syncCache(); + } else if (!lazy) { + log.info("从数据库同步缓存!(" + getTitle() + ")"); + refresh(); + } + } + + /** + * 注册其他key的List缓存,如tree的children + * + * @param key + * @param iGetBeanKey + */ + protected void regList(String key, IGetBeanKey iGetBeanKey) { + mapListReg.put(key, iGetBeanKey); + } + + protected void regListEx(String key, IGetBeanKeys iGetBeanKey) { + mapListRegEx.put(key, iGetBeanKey); + } + + /** + * 注册其他key的Map缓存,如按code缓存 + * + * @param key + * @param iGetBeanKey + */ + + protected void regMap(String key, IGetBeanKey iGetBeanKey) { + mapMapReg.put(key, iGetBeanKey); + } + + //获取bean的id + protected abstract String getId(T bean); + + /** + * 从redis获取全部缓存 + * redis上只保留,拉下来后,自行组织其他格式缓存 + */ + public void syncCache() { + loadStatu = LS_LOADING; + + cache.invalidateAll(); + cacheOrg.clear(); + mapListLocal.clear(); + mapMapLocal.clear(); + + List vals = RedisManager.getInstance().hVals(getIdent()); + for (byte[] v : vals) { + T bean = CommUtil.readObject(v, pTypeClass); + doUpdate(bean); + } + loadStatu = LS_LOADED; + } + + /** + * 监听redis同步事件 + * + * @param event + */ + public void syncCache(RedisBroadcastEvent event) { + //加载中,忽略 + if (loadStatu == LS_LOADING) { + log.info("加载中,忽略本次同步通知:" + event.toString()); + return; + } + switch (event.getAction()) { + case RedisBroadcastEvent.CODE_REMOVE: + doRemove(event.getKey()); + break; + case RedisBroadcastEvent.CODE_CLEAR: + doClear(); + break; + case RedisBroadcastEvent.CODE_CACHE_UPDATE: + T bean = RedisManager.getInstance().hGet(getIdent(), event.getKey(), pTypeClass); + if (bean != null) { + doRemove(getId(bean)); + doUpdate(bean); + } + break; + case RedisBroadcastEvent.CODE_CACHE_REFRESH: + syncCache(); + break; + default: + throw new IllegalStateException("Unexpected value: " + event.getAction()); + } + } + + + /** + * 通过指定的key获取缓存对象值 + * + * @param key 缓存key值 + * @return 缓存对象值 + */ + protected T load(String key) { + return null; + } + + /** + * 从数据库加载全部,lazy模式可以不用实现 + */ + protected List loadAll() { + return null; + } + + /** + * @param key + * @return + */ + private T onLoad(String key) { + if (lazy) {//非懒加载,不管 + T result = load(key); + + if (result != null) { + this.put(result); + } + + return result; + } + return null; + } + + /** + * 删除时,需要拿原来的对象;对象被取出后,可能被修改 + * + * @param key + * @return + */ + public T getOrg(String key) { + return cacheOrg.get(key); + } + + /** + * 本地删除缓存 + * + * @param key + */ + protected void doRemove(String key) { + T oldbean = getOrg(key); + T bean = get(key); + if (bean != null) { + for (Map.Entry> entry : mapListReg.entrySet()) { + doRemoveList(entry.getKey(), getBeanKey(entry.getValue(), oldbean), bean); + } + + for (Map.Entry> entry : mapListRegEx.entrySet()) { + String[] keys = entry.getValue().getKey(oldbean); + for (String k: keys) { + doRemoveList(entry.getKey(), k, bean); + } + } + + for (Map.Entry> entry : mapMapReg.entrySet()) { + doRemoveMap(entry.getKey(), getBeanKey(entry.getValue(), oldbean)); + } + } + cache.invalidate(key); + cacheOrg.remove(key); + } + + /** + * 插入新对象 + */ + protected void doUpdate(T value) { + final String key = getId(value); + cache.put(key, value); + cacheOrg.put(key, CommUtil.cloneObj(value, pTypeClass)); + + for (Map.Entry> entry : mapListReg.entrySet()) { + doUpdateList(entry.getKey(), getBeanKey(entry.getValue(), value), value); + } + + for (Map.Entry> entry : mapListRegEx.entrySet()) { + String[] keys = entry.getValue().getKey(value); + for (String k: keys) { + doUpdateList(entry.getKey(), k, value); + } + } + + for (Map.Entry> entry : mapMapReg.entrySet()) { + doUpdateMap(entry.getKey(), getBeanKey(entry.getValue(), value), value); + } + } + + //本地调用,删除一个对象时,更新列表缓存 + private void doRemoveList(String regionKey, String key, T value) { + if (StringUtils.isEmpty(key)) return; + Set list = mapListLocal.get(regionKey + SwConsts.SPLIT_CHAR + key); + if (list == null) { + return; + } + list.remove(value); + } + + //本地调用,删除对象时,更新map缓存 + private void doRemoveMap(String regionKey, String key) { + if (StringUtils.isEmpty(key)) return; + Map map = mapMapLocal.get(regionKey); + if (map != null) { + map.remove(key); + } + } + + //本地调用,更新列表缓存 + private void doUpdateList(String regionKey, String key, T value) { + if (StringUtils.isEmpty(key)) return; + Set list = mapListLocal.computeIfAbsent(regionKey + SwConsts.SPLIT_CHAR + key, k -> new LinkedHashSet<>()); + list.add(value); + } + + //本地调用,更新对象时,更新map缓存 + private void doUpdateMap(String regionKey, String key, T value) { + if (StringUtils.isEmpty(key)) return; + Map map = mapMapLocal.computeIfAbsent(regionKey, k -> new HashMap<>()); + map.put(key, value); + } + + /** + * 外部调用,更新缓存:先删除,再更新本地缓存,更新并通知redis + * + * @param bean + */ + public final void put(T bean) { + doRemove(getId(bean)); + doUpdate(bean); + if (loadStatu != LS_LOADING) { + RedisManager.getInstance().hSet(getIdent(), getId(bean), bean); + //通知redis + publishUpdate(getId(bean)); + } + } + + /** + * 将对象重置为修改前的值,用于取出修改后,事务提交失败 + * + * @param bean + */ + public final void reset(T bean) { + final String id = getId(bean); + T b = getOrg(id); + if (b != null) { + cache.put(id, b); + } + } + + @Override + public final T get(String key) { + return cache.get(key); + } + + public final T get(long key) { + return cache.get(String.valueOf(key)); + } + + /** + * 按其他key取bean + * + * @param rk 注册类型 + * @param key + * @return + */ + protected final T getByKey(String rk, String key) { + Map map = mapMapLocal.get(rk); + if (map != null) { + return map.get(key); + } + return null; + } + + public final Set getListByKey(String rk, String key) { + return mapListLocal.get(rk + SwConsts.SPLIT_CHAR + key); + } + + /** + * 通知redis更新:更新单个bean + * + * @param key + */ + protected final void publishUpdate(String key) { + RedisBroadcastEvent message = new RedisBroadcastEvent(); + message.setIdent(getIdent()); + message.setKey(key); + message.setAction(RedisBroadcastEvent.CODE_CACHE_UPDATE); + RedisManager.getInstance().publish(message); + } + + /** + * 通知redis更新:删除单个bean + * + * @param key + */ + @Override + public final void publishRemove(String key) { + RedisBroadcastEvent message = new RedisBroadcastEvent(); + message.setIdent(getIdent()); + message.setKey(key); + message.setAction(RedisBroadcastEvent.CODE_REMOVE); + RedisManager.getInstance().publish(message); + } + + /** + * 通知redis更新:清空缓存 + */ + @Override + public final void publishClear() { + RedisBroadcastEvent message = new RedisBroadcastEvent(); + message.setIdent(getIdent()); + message.setAction(RedisBroadcastEvent.CODE_CLEAR); + RedisManager.getInstance().publish(message); + } + + /** + * 通知redis更新:刷新缓存 * + */ + public final void publishRefresh() { + RedisBroadcastEvent message = new RedisBroadcastEvent(); + message.setIdent(getIdent()); + message.setAction(RedisBroadcastEvent.CODE_CACHE_REFRESH); + RedisManager.getInstance().publish(message); + } + + /** + * 外部调用,删除单个对象 + * + * @param key + */ + public void remove(String key) { + this.doRemove(key); + RedisManager.getInstance().hdel(getIdent(), key); + publishRemove(key); + } + + public void remove(long key) { + remove(String.valueOf(key)); + } + + /** + * 本地调用,清空缓存 + */ + protected void doClear() { + cache.cleanUp(); + cacheOrg.clear(); + mapListLocal.clear(); + mapMapLocal.clear(); + } + + /** + * 外部调用,清空缓存:清空本地缓存,并更新redis,通知其他服务 + */ + public void clear() { + doClear(); + RedisManager.getInstance().del(getIdent()); + publishClear(); + } + + /** + * 重载缓存:先清空,再重载 + */ + public void refresh() { + loadStatu = LS_LOADING; + doClear(); + List list = loadAll(); + if (list != null) { + for (T bean : list) { + doUpdate(bean); + } + } + loadStatu = LS_LOADED; + RedisManager.getInstance().hmSet(getIdent(), cacheOrg); + publishRefresh(); + } + + /** + * 根据接口,得到bean的缓存key + * + * @param iGetBeanKey + * @param bean + * @return + */ + protected String getBeanKey(IGetBeanKey iGetBeanKey, T bean) { + return iGetBeanKey.getKey(bean); + } + + public Collection getAll() { + return cacheOrg.values(); + } + + /** + * 获取bean缓存key的接口类,用于按非id的缓存,如code等 + * + * @param + */ + public interface IGetBeanKey { + String getKey(T bean); + } + + public interface IGetBeanKeys { + String[] getKey(T bean); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/CacheManager.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/CacheManager.java new file mode 100644 index 0000000..af521d0 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/CacheManager.java @@ -0,0 +1,110 @@ +package cc.smtweb.framework.core.cache; + +import cc.smtweb.framework.core.cache.redis.RedisBroadcastEvent; +import cc.smtweb.framework.core.db.cache.EntityCache; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.util.SpringUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +/** + * 内存缓存管理器,管理lazy加载的缓存,长时间不使用会失效 + */ +@Slf4j +public class CacheManager { + //所有缓存对象 + private final Map cacheMap = new HashMap<>(); + private final Map cacheMapCls = new HashMap<>(); + //记录顺序用 + private List listCache = new ArrayList<>(); + //缓存清理线程池 + private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); + + public AbstractCache getCache(String ident) { + final AbstractCache cache = cacheMap.get(ident.toUpperCase()); + if (cache != null && cache.isNotInited()) { + cache.init(); + } + return cache; + } + + public T getCache(Class clazz) { + final T cache = (T) cacheMapCls.get(clazz); + if (cache != null && cache.isNotInited()) { + cache.init(); + } + return cache; + } + + public static CacheManager getIntance() { + return SpringUtil.getBean(CacheManager.class); + } + + // 初始化cache + public boolean install(AbstractCache cache) { + cache.install(executorService); + if (cacheMap.putIfAbsent(cache.getIdent(), cache) == null) { + cacheMapCls.put(cache.getClass(), cache); + listCache.add(cache); + return true; + } + + return false; + } + + /** + * 启动时的初始化及预加载 + * 1、按依赖关系排序 + * 2、预加载(lazy模式不从库加载) + */ + public void init() { + listCache.sort((o1, o2) -> { + //o1依赖o2 + if (isContains(o1.getDepends(), o2.getIdent())) return 1; + //o2依赖o1 + if (isContains(o2.getDepends(), o1.getIdent())) return -1; + + return 0;//getPluginIndex(o1) - getPluginIndex(o2); + }); + for (AbstractCache cache : listCache) { + if (cache.isNotInited()) { + cache.init(); + } + } + //按表加载并初始化 + for (ModelTable table : ModelTableCache.getInstance().getAll()) { + if (table.isNeedCache() && !cacheMap.containsKey(table.getName())) { + EntityCache cache = new EntityCache(table.getName()); + cache.install(executorService); + cacheMapCls.put(cache.getClass(), cache); + cacheMap.put(table.getName(), cache); + } + } + } + + private boolean isContains(String[] src, String dest) { + if (src == null || src.length == 0) return false; + for (String s : src) { + if (s.trim().equals(dest)) return true; + } + return false; + } + + @EventListener + public void onRedisBroadcastEvent(RedisBroadcastEvent event) { + AbstractCache cache = getCache(event.getIdent()); + if (cache == null) { + log.info("接收到不存在的缓存更新!(" + event.toString() + ")"); + return; + } + cache.syncCache(event); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/ISwCache.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/ISwCache.java new file mode 100644 index 0000000..59d3c8a --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/ISwCache.java @@ -0,0 +1,24 @@ +package cc.smtweb.framework.core.cache; + +public interface ISwCache { + /** 权限缓存名称 */ + String REALM_CACHE = "RealmCache"; + + /** + * 根据键值获取缓存对象 + * @param key 缓存唯一键值 + * @return 缓存对象 + */ + V get(K key); + + /** + * 给redis发送广播消息,多服务同步删除相同key值的缓存对象 + * @param key 缓存键值 + */ + void publishRemove(K key); + + /** + * 给redis发送广播消息,多服务同步清空相同类型的缓存对象 + */ + void publishClear(); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/SessionCache.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/SessionCache.java new file mode 100644 index 0000000..7b32a62 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/SessionCache.java @@ -0,0 +1,36 @@ +package cc.smtweb.framework.core.cache; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; + +import java.util.concurrent.TimeUnit; + +/** + * Created by Akmm at 2022/3/14 10:22 + */ +public class SessionCache { + private Cache cache; + + public SessionCache(long timeout) { + if (timeout <= 0L) timeout = Long.MAX_VALUE; + this.cache = Caffeine.newBuilder() + .expireAfterAccess(timeout, TimeUnit.MINUTES).build(); + } + + public void put(String id, Object bean) { + if (bean != null) cache.put(id, bean); + } + + public void remove(String id) { + cache.invalidate(id); + } + + public void clear() { + cache.invalidateAll(); + } + + @SuppressWarnings({"unchecked"}) + public T get(String id) { + return (T) cache.getIfPresent(id); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisBroadcastEvent.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisBroadcastEvent.java new file mode 100644 index 0000000..f9d00bf --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisBroadcastEvent.java @@ -0,0 +1,24 @@ +package cc.smtweb.framework.core.cache.redis; + +import lombok.Data; + +/** + * redis 广播消息 + */ +@Data +public class RedisBroadcastEvent { + public static final int CODE_REMOVE = 1; + public static final int CODE_CLEAR = 2; + /** 缓存更新 */ + public static final int CODE_CACHE_UPDATE = 3; + public static final int CODE_CACHE_REFRESH = 4; + + private int action; + private String ident; + private String key; + + @Override + public String toString() { + return "ident=" + ident + "&&key=" + key + "&&act=" + action; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisPooledObjectFactory.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisPooledObjectFactory.java new file mode 100644 index 0000000..0c0c4c6 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisPooledObjectFactory.java @@ -0,0 +1,39 @@ +package cc.smtweb.framework.core.cache.redis; + +import io.lettuce.core.RedisClient; +import io.lettuce.core.api.StatefulRedisConnection; +import io.lettuce.core.codec.ByteArrayCodec; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.PooledObjectFactory; +import org.apache.commons.pool2.impl.DefaultPooledObject; + +class RedisPooledObjectFactory implements PooledObjectFactory> { + private RedisClient redisClient; + + public RedisPooledObjectFactory(RedisClient redisClient) { + this.redisClient = redisClient; + } + + @Override + public void activateObject(PooledObject> pooledObject) throws Exception { + } + + @Override + public void destroyObject(PooledObject> pooledObject) throws Exception { + pooledObject.getObject().close(); + } + + @Override + public PooledObject> makeObject() throws Exception { + return new DefaultPooledObject<>(redisClient.connect(ByteArrayCodec.INSTANCE)); + } + + @Override + public void passivateObject(PooledObject> pooledObject) throws Exception { + } + + @Override + public boolean validateObject(PooledObject> pooledObject) { + return pooledObject.getObject().isOpen(); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisSysTask.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisSysTask.java new file mode 100644 index 0000000..b679838 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisSysTask.java @@ -0,0 +1,61 @@ +package cc.smtweb.framework.core.cache.redis; + +import cc.smtweb.framework.core.systask.ISysTask; +import cc.smtweb.framework.core.util.JsonUtil; +import io.lettuce.core.RedisClient; +import io.lettuce.core.pubsub.RedisPubSubAdapter; +import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; +import io.lettuce.core.pubsub.api.sync.RedisPubSubCommands; +import org.springframework.context.ApplicationContext; + +public class RedisSysTask implements ISysTask { + private ApplicationContext applicationContext; + private StatefulRedisPubSubConnection connection; + private RedisClient redisClient; + //订阅消息的channel,一般带通配符 + private String scribeChannel; + //自己的唯一标记,自己发的消息不处理 + private String selfChannel; + + public RedisSysTask(ApplicationContext applicationContext, RedisClient redisClient, String scribeChannel, String selfChannel) { + this.applicationContext = applicationContext; + this.redisClient = redisClient; + this.scribeChannel = scribeChannel; + this.selfChannel = selfChannel; + } + + @Override + public int run() { + // 非集群模式下的发布订阅 + if (connection == null) { + connection = redisClient.connectPubSub(); + + if (connection != null) { + connection.addListener(new RedisPubSubAdapter() { + @Override + public void message(String channel, String message) { + if (channel.equalsIgnoreCase(selfChannel)) return; + RedisBroadcastEvent redisBroadcast = JsonUtil.parse(message, RedisBroadcastEvent.class); + + applicationContext.publishEvent(redisBroadcast); + +// log.debug("Redis [" + channel + "] message:" + redisBroadcast); + } + }); + + // 订阅 + RedisPubSubCommands sync = connection.sync(); + sync.subscribe(scribeChannel); + } + } + + return 0; + } + + public void close() { + if (connection != null) { + connection.close(); + connection = null; + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/AbstractEnum.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/AbstractEnum.java new file mode 100644 index 0000000..29f6bb9 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/AbstractEnum.java @@ -0,0 +1,106 @@ +package cc.smtweb.framework.core.common; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Created by Akmm at 2017/5/3 17:25 + * 枚举基类 + */ +public abstract class AbstractEnum { + public Map mapAll = new LinkedHashMap<>(); + + public V addEnum(K value, String name) { + final V bean = buildBean(value, name); + mapAll.put(value, bean); + return bean; + } + + public void delEnum(K value) { + mapAll.remove(value); + } + + protected abstract V buildBean(K value, String name); + + protected Object getSqlValue(V pbs) { + return pbs.value; + } + + //根据值获取对象 + public V getByValue(K value) { + V v = mapAll.get(value); + if (v != null) return v; + return getDefault(); + } + + public V getByName(String name) { + for (V bs : mapAll.values()) { + if (bs.name.equals(name)) return bs; + } + return null; + } + + //根据value获取name + public String getName(K value) { + V bean = getByValue(value); + return bean != null ? bean.name: ""; + } + + //默认值 + public V getDefault() { + return null; + } + + //所有枚举定义 + public Collection values() { + return mapAll.values(); + } + + public boolean contains(K value) { + return mapAll.containsKey(value); + } + + //遍历枚举类 + public void doEnum(IEnumWorker worker) { + for (V bean: mapAll.values()) { + worker.work(bean); + } + } + + /** + * 枚举值对象定义 + */ + public static class EnumBean { + public T value; + public String name; + + public EnumBean(T value, String name) { + this.value = value; + this.name = name; + } + } + + /** + * Int、Text 枚举值对象定义 + */ + public static class IntEnumBean extends EnumBean { + public IntEnumBean(Integer value, String name) { + super(value, name); + } + } + + /** + * Str、Text 枚举值对象定义 + */ + public static class StrEnumBean extends EnumBean { + public StrEnumBean(String value, String name) { + super(value, name); + } + } + + //枚举回调类 + public interface IEnumWorker { + public void work(V enumBean); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/IntEnum.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/IntEnum.java new file mode 100644 index 0000000..7cdd183 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/IntEnum.java @@ -0,0 +1,12 @@ +package cc.smtweb.framework.core.common; + +/** + * Created by Akmm at 2017/5/3 17:25 + * int、text型枚举 + */ +public class IntEnum extends AbstractEnum { + @Override + protected AbstractEnum.IntEnumBean buildBean(Integer value, String name) { + return new AbstractEnum.IntEnumBean(value, name); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/R.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/R.java new file mode 100644 index 0000000..4a91157 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/R.java @@ -0,0 +1,118 @@ +package cc.smtweb.framework.core.common; + +import cc.smtweb.framework.core.exception.ExceptionMessage; + +import java.util.Date; + +/** + * 〈返回结果集〉 + * + * @author kevin + * @since 1.0.0 + */ +public class R extends SwMap { + protected R() { + this(0); + } + + protected R(int code) { + put("now", new Date()); + put("code", code); + } + + public static R success() { + return new R(); + } + + public static R success(Object data) { + return new R().put("data", data); + } + + public static R success(String name, Object data) { + return new R().put(name, data); + } + + public static R error() { + return error(ExceptionMessage.INNER_ERROR.getMsg()); + } + + public static R error(String msg) { + R r = new R(ExceptionMessage.INNER_ERROR.getCode()); + r.put("msg", msg); + return r; + } + + public static R error(int code, String msg) { + R r = new R(code); + r.put("msg", msg); + return r; + } + + public static R errorf(String format, Object...args) { + R r = new R(ExceptionMessage.INNER_ERROR.getCode()); + r.put("msg", String.format(format, args)); + return r; + } + +// public static R error(ExceptionMessage cm) { +// R r = new R(cm.getCode()); +// r.put("msg", cm.getMsg()); +// return r; +// } + +// public static R error(ExceptionMessage cm, Throwable ex) { +// R r = new R(cm.getCode()); +// r.put("msg", cm.getMsg()); +// r.put("exception", ex.getMessage()); +// return r; +// } + + public static R error(String msg, Throwable ex) { + R r = new R(ExceptionMessage.INNER_ERROR.getCode()); + r.put("msg", msg); + r.put("exception", ex.getMessage()); + ex.printStackTrace(); + return r; + } + + public static R error(ExceptionMessage cm, String msg) { + R r = new R(cm.getCode()); + r.put("msg", msg); + return r; + } + + @Override + public R put(String key, Object value) { + super.put(key, value); + return this; + } + + public R putNotNull(String key, Object value) { + if (value != null) { + super.put(key, value); + } + + return this; + } + + public void setMessage(ExceptionMessage cm) { + this.put("code", cm.getCode()); + this.put("msg", cm.getMsg()); + } + + public void setData(Object data) { + this.put("data", data); + } + + public int readCode() { + return this.readInt("code"); + } + + public String readMsg() { + return this.readString("msg"); + } + + public boolean readSuccess() { + return this.readInt("code", -1) == 0; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/StrEnum.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/StrEnum.java new file mode 100644 index 0000000..2ada2ae --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/StrEnum.java @@ -0,0 +1,30 @@ +package cc.smtweb.framework.core.common; + +import org.apache.commons.lang3.StringUtils; + +/** + * Created by Akmm at 2017/5/3 17:25 + * int、text型枚举 + */ +public class StrEnum extends AbstractEnum { + @Override + protected Object getSqlValue(StrEnumBean pbs) { + return "'" + pbs.value + "'"; + } + + @Override + protected AbstractEnum.StrEnumBean buildBean(String value, String name) { + return new AbstractEnum.StrEnumBean(value, name); + } + + //根据value获取name + public String getNames(String value) { + if (StringUtils.isEmpty(value)) return ""; + StringBuilder sb = new StringBuilder(128); + for (String s : value.split(",")) { + String n = getName(s); + if (StringUtils.isNotEmpty(n)) sb.append(",").append(n); + } + return sb.substring(1); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java new file mode 100644 index 0000000..65df21a --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java @@ -0,0 +1,19 @@ +package cc.smtweb.framework.core.common; + +/** + * Created by Akmm at 2022/3/23 9:46 + */ +public interface SwConsts { + //缓存中:树节点按parent的key + String KEY_PARENT_ID = "pr"; + //级次码、字符串连接符 + String SPLIT_CHAR = "-"; + //默认根节点 + String DEF_ROOT_ID = "-1"; + + //列表分页的页码和每页记录数 + String PARAM_PAGE = "page"; + String PARAM_ROWS = "rows"; + String TOTAL_KEY = "total_count"; + String DEF_DB_NAME = "sys"; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwIpAddr.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwIpAddr.java new file mode 100644 index 0000000..ab2b357 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwIpAddr.java @@ -0,0 +1,9 @@ +package cc.smtweb.framework.core.common; + +import lombok.Data; + +@Data +public class SwIpAddr { + private String ip; + private int port; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwMap.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwMap.java new file mode 100644 index 0000000..e55fe7a --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwMap.java @@ -0,0 +1,116 @@ +package cc.smtweb.framework.core.common; + +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.util.MapUtil; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 通用map对象,用于无具体类型的传值 + * + * @author kevin + */ +public class SwMap extends HashMap { + public SwMap() { + } + + public SwMap(int initialCapacity) { + super(initialCapacity); + } + + public String readString(String name) { + return MapUtil.readString(this, name); + } + + public SwMap readMap(String name) { + Object v = get(name); + if (v == null) return null; + if (v instanceof SwMap) return (SwMap)v; + if (v instanceof Map) { + Map m = (Map)v; + SwMap map = new SwMap(m.size()); + map.putAll(m); + put(name, map); + return map; + } + throw new SwException("不是合法的Map对象!" + v.getClass().getName()); + } + + public List> readListMap(String name) { + return MapUtil.readListMap(this, name); + } + + public String readString(String name, String defaultValue) { + return MapUtil.readString(this, name, defaultValue); + } + + public long readLong(String name) { + return MapUtil.readLong(this, name); + } + + public Long readLong(String name, Long defaultValue) { + return MapUtil.readLong(this, name, defaultValue); + } + + public Long[] readLongArray(String name) { + return MapUtil.readLongArray(this, name); + } + + public Long[] readLongArray(String name, Long[] defaultValue) { + return MapUtil.readLongArray(this, name, defaultValue); + } + + public Set readLongSet(String name) { + return MapUtil.readLongSet(this, name); + } + + public int readInt(String name) { + return MapUtil.readInt(this, name); + } + + public int readInt(String name, Integer defaultValue) { + return MapUtil.readInt(this, name, defaultValue); + } + + public float readFloat(String name) { + return MapUtil.readFloat(this, name); + } + + public float readFloat(String name, Float defaultValue) { + return MapUtil.readFloat(this, name, defaultValue); + } + + public double readDouble(String name) { + return MapUtil.readDouble(this, name); + } + + public double readDouble(String name, Double defaultValue) { + return MapUtil.readDouble(this, name, defaultValue); + } + + public boolean readBool(String name) { + return MapUtil.readBool(this, name); + } + + public boolean readBool(String name, Boolean defaultValue) { + return MapUtil.readBool(this, name, defaultValue); + } + + @Override + public SwMap put(String name, Object value) { + if (value != null) { + super.put(name, value); + } else { + super.remove(name); + } + + return this; + } + + public static SwMap of(String name, Object value) { + return new SwMap().put(name, value); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java new file mode 100644 index 0000000..d0b77ba --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java @@ -0,0 +1,278 @@ +package cc.smtweb.framework.core.db; + +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.jdbc.IdGenerator; +import cc.smtweb.framework.core.db.jdbc.JdbcEngine; +import cc.smtweb.framework.core.mvc.controller.scan.BeanManager; +import cc.smtweb.framework.core.util.SpringUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 提供数据库基本操作和代理EntityDao操作,在DbEngineConfiguration中初始化 + * + * @author xkliu + */ +@Slf4j +public class DbEngine extends JdbcEngine { + private String dbSchema; + private final Map, EntityDao> daoMap = new ConcurrentHashMap<>(); + private final Map> tableDaoMap = new ConcurrentHashMap<>(); + + public static DbEngine getInstance() { + return SpringUtil.getBean(DbEngine.class); + } + + public DbEngine(NamedParameterJdbcTemplate namedJdbcTemplate, IdGenerator idGenerator, String type) { + super(namedJdbcTemplate, idGenerator, type); + } + + /** + * bean为Data格式,调用此方法 + * @param type bean类 + * @param + * @return + */ + public EntityDao findDao(Class type) { + EntityDao handler = (EntityDao) daoMap.get(type); + + if (handler == null) { + synchronized (daoMap) { + handler = new EntityDao<>(type, this); + daoMap.put(type, handler); + } + } + + return handler; + } + + public EntityDao findDao(String tableName) { + Class clazz = BeanManager.getInstance().getTableClass(tableName); + if (clazz != null) { + return findDao(clazz); + } + EntityDao handler = tableDaoMap.get(tableName); + + if (handler == null) { + synchronized (tableDaoMap) { + handler = new EntityDao<>(tableName, this); + tableDaoMap.put(tableName, handler); + } + } + + return handler; + } + + public String getDbSchema() { + if (dbSchema == null) { + synchronized (DbEngine.class) { + if (dbSchema == null) { + try { + final ResultSetExtractor rse = new ResultSetExtractor() { + @Override + public String extractData(ResultSet rs) throws SQLException { + if (rs.next()) return rs.getString(1); + throw new SQLException("未指定当前数据库,请检查您的链接!"); + } + }; + + dbSchema = query("SELECT database()", rse); + + } catch (Exception e) { + log.error("获取mysql的数据库失败", e); + return null; + } + } + } + } + return dbSchema; + } + + /** + * 根据PO对象的ID值更新其余所有字段 + * + * @param entity PO对象 + * @param PO对象类型 + * @return 更新数量 + */ + public int updateEntity(T entity) { + return updateEntity(entity, null, null); + } + + /** + * 使用ID字段更新单行数据 + * + * @param entity PO值对象,对象属性是需要更新的值 + * @param fields 需要更新额字段列表,逗号分隔 + * @param PO值对象类型 + * @return 更新数量 + */ + public int updateEntity(T entity, String fields) { + return updateEntity(entity, fields, null); + } + + /** + * 指定自定义条件更新对象 + * + * @param entity PO值对象,对象属性是需要更新的值和更新条件值 + * @param fields 需要更新额字段列表,逗号分隔 + * @param whereFields 更新条件字段列表,逗号分隔 + * @param PO值对象类型 + * @return 更新数量 + */ + public int updateEntity(T entity, String fields, String whereFields) { + EntityDao dao = findDao((Class) entity.getClass()); + return dao.updateEntity(entity, fields, whereFields); + } + + /** + * 用PO对象所有字段入单行数据 + * + * @param entity PO对象 + * @param PO对象类型 + * @return 更新数量 + */ + public int insertEntity(T entity) { + return insertEntity(entity, null); + } + + /** + * 插入单行数据 + * + * @param entity PO对象 + * @param fields 逗号分隔的字段列表 + * @param PO对象类型 + * @return 更新数量 + */ + public int insertEntity(T entity, String fields) { + EntityDao dao = findDao((Class) entity.getClass()); + return dao.insertEntity(entity, fields); + } + + /** + * 根据ID值删除单行数据 + * + * @param entity PO对象 + * @param PO对象类型 + * @return 删除数量 + */ + public int deleteEntity(T entity) { + EntityDao dao = findDao((Class) entity.getClass()); + return dao.deleteEntity(entity); + } + + /** + * 根据ID值删除单行数据 + * + * @param entityType PO对象类型 + * @param id 记录主建值 + * @param PO对象 + * @return 删除数量 + */ + public int deleteEntity(Class entityType, Long id) { + EntityDao dao = findDao(entityType); + return dao.deleteEntity(id); + } + + /** + * 根据ID值删除单行数据 + * + * @param entityType PO对象类型 + * @param whereSql Where条件SQL语句,以where开头 + * @param params 条件的值,可以多个 + * @param PO对象 + * @return 删除数量 + */ + public int deleteEntity(Class entityType, String whereSql, Object... params) { + EntityDao dao = findDao(entityType); + return dao.deleteEntity(whereSql, params); + } + + /** + * 读取实体对象ID值 + * + * @param entity + * @param + * @return + */ + public Long readEntityId(T entity) { + EntityDao dao = findDao((Class) entity.getClass()); + return dao.readId(entity); + } + + /** + * 查询单行数据,返回bean + */ + public T queryEntity(Class type, Long id) { + return queryEntity(type, id, null); + } + + public T queryEntity(Class type, Long id, String fields) { + return findDao(type).queryEntity(id, fields); + } + + /** + * 查询对象所有数据,返回列表 + */ + public List query(Class type) { + return query(type, null); + } + + /** + * 查询对象所有数据,返回列表 + */ + public List query(Class type, String fields) { + return findDao(type).query(fields); + } + + /** + * 传入where条件查询实体类别 + * + * @param type 实体类型类 + * @param sqlWhere sql的where语句部分,不包含from + * @param params 条件参数值 + * @param 实体类型 + * @return + */ + public List queryWhere(Class type, String sqlWhere, Object... params) { + return findDao(type).queryWhere(sqlWhere, params); + } + + /** + * 批量插入单行数据 + * + * @param entities PO对象列表 + * @param 实体类型 + * @return 更新数量 + */ + public int[] batchInsertEntity(List entities) { + if (entities == null || entities.isEmpty()) { + return null; + } + return findDao((Class) entities.get(0).getClass()).batchInsertEntity(entities, null); + } + + /** + * 批量插入单行数据 + * + * @param entities PO对象列表 + * @param fields 逗号分隔的字段列表 + * @param 实体类型 + * @return 更新数量 + */ + public int[] batchInsertEntity(List entities, String fields) { + if (entities == null || entities.isEmpty()) { + return null; + } + return findDao((Class) entities.get(0).getClass()).batchInsertEntity(entities, fields); + } + + +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityDao.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityDao.java new file mode 100644 index 0000000..8318c2c --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityDao.java @@ -0,0 +1,367 @@ +package cc.smtweb.framework.core.db; + +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.db.dao.AbstractEntityDao; +import cc.smtweb.framework.core.db.dao.EntityColumn; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.jdbc.JdbcEngine; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.util.CommUtil; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; + +/** + * 提供数据对象Dao操作 + * + * @author xkliu + */ +public class EntityDao extends AbstractEntityDao { + @Getter + protected JdbcEngine jdbcEngine; + + public EntityDao(Class type, JdbcEngine jdbcEngine) { + super(type); + this.jdbcEngine = jdbcEngine; + } + + public EntityDao(String tableName, JdbcEngine jdbcEngine) { + super(tableName); + this.jdbcEngine = jdbcEngine; + } + + /** + * 获取数据库唯一id + * + * @return 返回ID值 + */ + public long nextId() { + return this.jdbcEngine.nextId(); + } + + /** + * 根据PO对象的ID值更新其余所有字段 + * + * @param entity PO对象 + * @return 更新数量 + */ + public int updateEntity(T entity) { + return updateEntity(entity, null, null); + } + + /** + * 使用ID字段更新单行数据 + * + * @param entity PO值对象,对象属性是需要更新的值 + * @param fields 需要更新额字段列表,逗号分隔 + * @return 更新数量 + */ + public int updateEntity(T entity, String fields) { + return updateEntity(entity, fields, null); + } + + public int updateEntityEx(T entity, String... exfields) { + if (exfields == null || exfields.length == 0) { + return updateEntity(entity, null, null); + } + Set excludeFields = new HashSet<>(exfields.length); + for (String f: exfields) { + excludeFields.add(f.toLowerCase()); + } + StringBuilder fields = new StringBuilder(512); + for (ModelField field: modelTable.getFields()) { + if (!excludeFields.contains(field.getName())) { + fields.append(",").append(field.getName()); + } + } + return updateEntity(entity, fields.substring(1), null); + } + + /** + * 指定自定义条件更新对象 + * + * @param entity PO值对象,对象属性是需要更新的值和更新条件值 + * @param fields 需要更新额字段列表,逗号分隔 + * @param whereFields 更新条件字段列表,逗号分隔 + * @return 更新数量 + */ + public int updateEntity(T entity, String fields, String whereFields) { + StringBuilder sb = new StringBuilder(); + Object[] params = this.handleUpdate(entity, sb, fields, whereFields); + + return jdbcEngine.update(sb.toString(), params); + } + + /** + * 用PO对象所有字段入单行数据 + * + * @param type PO对象字段范围的类,是entity的父类 + * @param entity PO对象 + * @return 更新数量 + */ + public int insertEntity(Class type, T entity) { + return insertEntity(type, entity, null); + } + + /** + * 用PO对象所有字段入单行数据 + * + * @param entity PO对象 + * @return 更新数量 + */ + public int insertEntity(T entity) { + return insertEntity(entity.getClass(), entity, null); + } + + /** + * 插入单行数据 + * + * @param entity PO对象 + * @param fields 逗号分隔的字段列表 + * @return 更新数量 + */ + public int insertEntity(T entity, String fields) { + return insertEntity(entity.getClass(), entity, fields); + } + + private int insertEntity(Class type, T entity, String fields) { + StringBuilder sb = new StringBuilder(); + + Object[] params = handleInsert(entity, sb, fields); + + return jdbcEngine.update(sb.toString(), params); + } + + /** + * 批量插入单行数据 + * + * @param entities PO对象列表 + * @return 更新数量 + */ + public int[] batchInsertEntity(List entities) { + return batchInsertEntity(entities, null); + } + + /** + * 批量插入单行数据 + * + * @param entities PO对象列表 + * @param fields 逗号分隔的字段列表 + * @return 更新数量 + */ + public int[] batchInsertEntity(List entities, String fields) { + StringBuilder sql = new StringBuilder(); + + sql.append("insert into ").append(modelTable.getSchemaTableName()).append("("); + + List listFields = adjustFields(fields, SwEnum.FieldType.CREATE_TIME.value, SwEnum.FieldType.LAST_TIME.value); + List insertColumns = new ArrayList<>(this.columns.size()); + + if (listFields == null) { + for (EntityColumn column : this.columns.values()) { + sql.append(column.getField().getName()).append(","); + insertColumns.add(column); + } + } else { + + for (String name : listFields) { + EntityColumn column = this.columns.get(name.trim()); + sql.append(column.getField().getName()).append(","); + insertColumns.add(column); + } + } + + sql.setCharAt(sql.length() - 1, ')'); + + // values(?,?) + sql.append(" values("); + for (int i = insertColumns.size(); i > 0; i--) { + sql.append("?,"); + } + sql.setCharAt(sql.length() - 1, ')'); + + // 参数列表 + List listParams = new ArrayList<>(entities.size()); + for (T obj : entities) { + List params = new ArrayList<>(this.columns.size()); + + for (EntityColumn column : this.columns.values()) { + params.add(column.readValue(obj)); + } + + listParams.add(params.toArray()); + } + + return jdbcEngine.batchUpdate(sql.toString(), listParams); + } + + + /** + * 根据ID值删除单行数据 + * + * @param entity PO对象 + * @return 删除数量 + */ + public int deleteEntity(T entity) { + StringBuilder sb = new StringBuilder(); + + Object[] params = handleDelete(entity, sb); + + return jdbcEngine.update(sb.toString(), params); + } + + /** + * 根据ID值删除单行数据 + * + * @param id 记录主建值 + * @return 删除数量 + */ + public int deleteEntity(Long id) { + StringBuilder sb = new StringBuilder(); + handleDelete(sb); + + return jdbcEngine.update(sb.toString(), id); + } + + /** + * 根据ID值删除单行数据 + * + * @param whereSql Where条件SQL语句,以where开头 + * @param params 条件的值,可以多个 + * @return 删除数量 + */ + public int deleteEntity(String whereSql, Object... params) { + StringBuilder sb = new StringBuilder("DELETE FROM "); + sb.append(modelTable.getSchemaTableName()).append(" ").append(whereSql); + + return jdbcEngine.update(sb.toString(), params); + } + + public int deleteEntity(List ids) { + return deleteEntity(" where " + modelTable.getIdField() + " in (" + CommUtil.getSqlInIds(ids) + ")"); + } + + private void setTableName(T bean) { + if (bean instanceof DefaultEntity) { + ((DefaultEntity) bean).setTableName(this.tableName); + } + } + + private void setTableName(List list) { + if (!list.isEmpty() && list.get(0) instanceof DefaultEntity) { + for (T bean: list) { + ((DefaultEntity) bean).setTableName(this.tableName); + } + } + } + + /** + * 查询单行数据,返回bean + */ + public T queryEntity(Long id) { + return queryEntity(id, null); + } + + public T queryEntity(Long id, String fields) { + StringBuilder sb = new StringBuilder(); + handleSelectOne(sb, fields); + + List list = jdbcEngine.query(sb.toString(), type, id); + + if (list != null && !list.isEmpty()) { + T bean = list.get(0); + setTableName(bean); + return bean; + } + + return null; + } + + /** + * 查询对象所有数据,返回列表 + */ + public List query() { + return query(null); + } + + /** + * 查询对象所有数据,返回列表 + */ + public Map queryNames(List ids) { + if (ids == null || ids.isEmpty()) return new HashMap<>(); + ModelField field = modelTable.findFieldByType(SwEnum.FieldType.NAME.value); + if (field == null) return new HashMap<>(); + + StringBuilder sb = new StringBuilder(); + handleSelect(sb, modelTable.getIdField() + "," + field.getName()); + sb.append("\nwhere " + modelTable.getIdField() + " in (" + CommUtil.getSqlInIds(ids) + ")"); + + return jdbcEngine.query(sb.toString(), rs -> { + Map map = new HashMap<>(); + while (rs.next()) { + map.put(rs.getString(1), rs.getString(2)); + } + return map; + }); + } + + /** + * 查询对象所有数据,返回列表 + */ + public List query(String fields) { + StringBuilder sb = new StringBuilder(); + handleSelect(sb, fields); + + List list = jdbcEngine.query(sb.toString(), type); + setTableName(list); + return list; + } + + /** + * 查询对象所有数据,返回列表 + */ + public List queryWhere(String sqlWhere, Object... params) { + StringBuilder sb = new StringBuilder(); + handleSelect(sb, null); + if (StringUtils.isNotEmpty(sqlWhere)) { + sb.append(" where ").append(sqlWhere); + } + + List list = jdbcEngine.query(sb.toString(), type, params); + setTableName(list); + return list; + } + + public List queryIdListWhere(String sqlWhere, Object... params) { + StringBuilder sb = new StringBuilder(); + handleSelect(sb, modelTable.getIdField()); + if (StringUtils.isNotEmpty(sqlWhere)) { + sb.append(" where ").append(sqlWhere); + } + + return jdbcEngine.queryLongList(sb.toString(), type, params); + } + + /** + * 检查表字段是否违反唯一索引 + * @param bean + * @param fields + */ + public void checkUnique(T bean, String... fields) { + if (fields.length == 0) return; + String ss = "", sTitle = ""; + List args = new ArrayList<>(fields.length + 1); + args.add(readId(bean)); + for (String f : fields) { + if (StringUtils.isEmpty(f)) continue; + ss += " and " + f + "=?"; + args.add(readValue(bean, f)); + sTitle += "+" + modelTable.findFieldTitle(f); + } + if (jdbcEngine.isExists("select 1 from " + modelTable.getSchemaTableName() + " where " + modelTable.getIdField() + "=? " + ss, args.toArray())) + throw new BizException(sTitle.substring(1) + " 不能重复!"); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java new file mode 100644 index 0000000..f427081 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java @@ -0,0 +1,193 @@ +package cc.smtweb.framework.core.db; + +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelLinkName; +import cc.smtweb.framework.core.db.vo.ModelTable; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; + +/** + * Created by Akmm at 2022/5/6 15:43 + * 实体辅助类 + */ +public class EntityHelper { + //获取字段别名 + private static String getFieldAlias(Map mapFieldAlias, String field) { + return (mapFieldAlias != null && mapFieldAlias.containsKey(field)) ? mapFieldAlias.get(field) : field; + } + + /** + * 添加关联字段值 + * @param tableName + * @param bean + */ + public static void loadBeanLink(String tableName, SwMap bean, Map mapFieldAlias) { + //添加关联字段值 + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + if (table == null) return; + List listLink = table.findLinkeNames(); + if (listLink.isEmpty()) return; + + //有缓存的,从缓存拿,无缓存的放Map,最后从数据库去拿 + Map> mapIds = new HashMap<>(); + + for (ModelLinkName l : listLink) { + final String fieldName = getFieldAlias(mapFieldAlias, l.getFieldName()); + String value = bean.readString(fieldName); + if (StringUtils.isEmpty(value)) continue; + String[] ids = StringUtils.split(value, ","); + if (l.getLinkTable().isNeedCache()) { + EntityDao dao = DbEngine.getInstance().findDao(l.getLinkTable().getName()); + AbstractCache cache = CacheManager.getIntance().getCache(l.getLinkTable().getName()); + String names = ""; + for (String sId : ids) { + Object b = cache.get(sId); + String sn = (String) dao.readValue(b, l.getLinkNameField()); + if (StringUtils.isNotEmpty(sn)) names += "," + sn; + } + bean.put(fieldName + "_text", names.length() > 1 ? names.substring(1) : ""); + } else { + List list = mapIds.computeIfAbsent(l.getLinkTable().getName(), k -> new ArrayList<>()); + Collections.addAll(list, ids); + } + } + + + if (mapIds.isEmpty()) return; + //数据库查询 + Map> mapValue = new HashMap<>(); + for (Map.Entry> entry : mapIds.entrySet()) { + EntityDao dao = DbEngine.getInstance().findDao(entry.getKey()); + mapValue.put(entry.getKey(), dao.queryNames(entry.getValue())); + } + //加值 + + for (ModelLinkName l : listLink) { + if (!mapValue.containsKey(l.getLinkTable().getName())) continue; + Map mapV = mapValue.get(l.getLinkTable().getName()); + + final String fieldName = getFieldAlias(mapFieldAlias, l.getFieldName()); + String value = bean.readString(fieldName); + if (StringUtils.isEmpty(value)) continue; + + String[] ids = StringUtils.split(value, ","); + String names = ""; + for (String sId : ids) { + String sn = mapV.get(sId); + if (StringUtils.isNotEmpty(sn)) names += "," + sn; + } + bean.put(fieldName + "_text", names.substring(1)); + } + } + + public static void loadBeanLink(String tableName, List listData, Map mapFieldAlias) { + //添加关联字段值 + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + if (table == null) return; + List listLink = table.findLinkeNames(); + if (listLink.isEmpty()) return; + + //有缓存的,从缓存拿,无缓存的放Map,最后从数据库去拿 + Map> mapIds = new HashMap<>(); + for (SwMap row : listData) { + for (ModelLinkName l : listLink) { + final String fieldName = getFieldAlias(mapFieldAlias, l.getFieldName()); + String value = row.readString(fieldName); + if (StringUtils.isEmpty(value)) continue; + String[] ids = StringUtils.split(value, ","); + if (l.getLinkTable().isNeedCache()) { + EntityDao dao = DbEngine.getInstance().findDao(l.getLinkTable().getName()); + AbstractCache cache = CacheManager.getIntance().getCache(l.getLinkTable().getName()); + String names = ""; + for (String sId : ids) { + Object b = cache.get(sId); + String sn = (String) dao.readValue(b, l.getLinkNameField()); + if (StringUtils.isNotEmpty(sn)) names += "," + sn; + } + if (StringUtils.isNotEmpty(names)) { + row.put(fieldName + "_text", names.substring(1)); + } else { + row.put(fieldName + "_text", ""); + } + } else { + List list = mapIds.computeIfAbsent(l.getLinkTable().getName(), k -> new ArrayList<>()); + for (String id : ids) { + list.add(Long.parseLong(id)); + } + } + } + } + + if (mapIds.isEmpty()) return; + //数据库查询 + Map> mapValue = new HashMap<>(); + for (Map.Entry> entry : mapIds.entrySet()) { + EntityDao dao = DbEngine.getInstance().findDao(entry.getKey()); + mapValue.put(entry.getKey(), dao.queryNames(entry.getValue())); + } + //加值 + for (SwMap row : listData) { + for (ModelLinkName l : listLink) { + if (!mapValue.containsKey(l.getLinkTable().getName())) continue; + Map mapV = mapValue.get(l.getLinkTable().getName()); + + final String fieldName = getFieldAlias(mapFieldAlias, l.getFieldName()); + String value = row.readString(fieldName); + if (StringUtils.isEmpty(value)) continue; + + String[] ids = StringUtils.split(value, ","); + String names = ""; + for (String sId : ids) { + String sn = mapV.get(sId); + if (StringUtils.isNotEmpty(sn)) names += "," + sn; + } + row.put(fieldName + "_text", names.substring(1)); + } + } + } + + //检查表记录是否被引用 + public static void checkExists(long tableId, long id) { + ModelTable fkTable = ModelTableCache.getInstance().get(tableId); + if (fkTable == null) throw new BizException("待检查表(" + tableId + ")为空!"); + checkExists(fkTable, id); + } + public static void checkExists(String tableName, long id) { + ModelTable fkTable = ModelTableCache.getInstance().getByName(tableName); + if (fkTable == null) throw new BizException("待检查表(" + tableName + ")为空!"); + checkExists(fkTable, id); + } + + /** + * 检查记录是否被使用 + * @param fkTable + * @param id + */ + public static void checkExists(ModelTable fkTable, long id) { + Set list = ModelTableCache.getInstance().getByLink(fkTable.getId()); + if (list == null || list.isEmpty()) return; + for (ModelTable table: list) { + StringBuilder sql = new StringBuilder(256); + List args = new ArrayList<>(); + for (ModelField field: table.getFields()) { + if (field.getLink() == fkTable.getId()) { + sql.append(" or ").append(field.getName()).append("=?"); + args.add(id); + } + } + if (sql.length() == 0) continue; + if (DbEngine.getInstance().isExists("select 1 from " + table.getSchemaTableName() + " where " + sql.substring(4), args.toArray())) { + throw new BizException("该记录被表【" + table.getTitle() + "(" + table.getName() + ")】引用,不能删除!"); + } + } + } + + +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/cache/EntityCache.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/cache/EntityCache.java new file mode 100644 index 0000000..b95d305 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/cache/EntityCache.java @@ -0,0 +1,66 @@ +package cc.smtweb.framework.core.db.cache; + +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.vo.ModelCache; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.mvc.controller.scan.BeanManager; +import cc.smtweb.framework.core.util.CommUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +/** + * Created by Akmm at 2022/2/19 17:19 + */ +public class EntityCache extends AbstractCache { + private String tableName; + + public EntityCache(String tableName) { + this.tableName = tableName; + Class clazz = (Class)BeanManager.getInstance().getTableClass(tableName); + if (clazz != null) { + this.pTypeClass = clazz; + } + + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + + ident = tableName; + title = table.getTitle(); + lazy = false; + + if (!table.isNeedCache() || CommUtil.isEmpty(table.getCaches())) return; + + for (ModelCache cache : table.getCaches()) { + final IGetBeanKey key = bean -> { + String ret = ""; + for (String s : StringUtils.split(cache.getFields(), ",")) { + if (StringUtils.isNotEmpty(s)) { + ret += SwConsts.SPLIT_CHAR + bean.getStr(s); + } + } + return ret.substring(1); + }; + if (cache.isMapType()) { + regMap(cache.getName(), key); + } else { + regList(cache.getName(), key); + } + } + } + + @Override + protected String getId(DefaultEntity bean) { + return String.valueOf(bean.getEntityId()); + } + + @Override + protected List loadAll() { + EntityDao dao = DbEngine.getInstance().findDao(tableName); + return dao.query(); + } + +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java new file mode 100644 index 0000000..4029d60 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java @@ -0,0 +1,46 @@ +package cc.smtweb.framework.core.db.cache; + +import cc.smtweb.framework.core.annotation.SwCache; +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.vo.ModelDatabase; + +import java.util.List; + +/** + * Created by Akmm at 2022/1/12 18:34 + */ +@SwCache(ident = "ASP_MODEL_DATABASE", title = "数据库") +public class ModelDatabaseCache extends AbstractCache { + private final static String mk = "k"; + + public static ModelDatabaseCache getInstance() { + return CacheManager.getIntance().getCache(ModelDatabaseCache.class); + } + + public ModelDatabaseCache() { + regMap(mk, ModelDatabase::getName); + } + + @Override + protected String getId(ModelDatabase bean) { + return String.valueOf(bean.getId()); + } + + @Override + protected List loadAll() { + EntityDao dao = DbEngine.getInstance().findDao(ModelDatabase.class); + return dao.query(); + } + + public final ModelDatabase getByName(String key) { + return getByKey(mk, key); + } + + public final String getName(long id) { + ModelDatabase db = get(id); + return db != null ? db.getName() : ""; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/config/DbEngineConfiguration.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/config/DbEngineConfiguration.java new file mode 100644 index 0000000..774420e --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/config/DbEngineConfiguration.java @@ -0,0 +1,41 @@ +package cc.smtweb.framework.core.db.config; + +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.jdbc.IdGenerator; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +/** + * 默认数据源 + * @author xkliu + */ +@Configuration +public class DbEngineConfiguration { + @Value("${smtweb.db.type}") + private String dbType; +// @Bean +// public DataSource dataSource() { +// return DataSourceBuilder.create().build(); +// } +// +// @Bean +// public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) { +// return new NamedParameterJdbcTemplate(dataSource); +// } + + /** + * 产生数据库数据库访问对象 dbEngine + * @param namedJdbcTemplate Spring框架Jdbc,通过 spring.datasource 配置 + * @param idGenerator ID生成器对象,思想数据库ID生成 + * @return dbEngine对象 + */ + @Bean + @ConfigurationProperties(prefix = "smtweb.db.default") + public DbEngine dbEngine(NamedParameterJdbcTemplate namedJdbcTemplate, IdGenerator idGenerator) { + System.out.println("create dbEngine============="); + return new DbEngine(namedJdbcTemplate, idGenerator, dbType); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/config/YamlPropertyLoaderFactory.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/config/YamlPropertyLoaderFactory.java new file mode 100644 index 0000000..24c0c05 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/config/YamlPropertyLoaderFactory.java @@ -0,0 +1,23 @@ +package cc.smtweb.framework.core.db.config; + +import org.springframework.boot.env.YamlPropertySourceLoader; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.support.DefaultPropertySourceFactory; +import org.springframework.core.io.support.EncodedResource; + +import java.io.IOException; + +/** + * 实现yaml配置文件加载工厂,以使用@PropertySource注解加载指定yaml文件的配置 + */ +public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory { + @Override + public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException { + + if (null == resource) { + super.createPropertySource(name, resource); + } + return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource()).get(0); + } + +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java new file mode 100644 index 0000000..45570e1 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java @@ -0,0 +1,399 @@ +package cc.smtweb.framework.core.db.dao; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.exception.DbException; +import cc.smtweb.framework.core.util.DateUtil; +import cc.smtweb.framework.core.util.SpringUtil; +import cc.smtweb.framework.core.util.VariableUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.ClassUtils; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 抽象的值对象数据库访问 + * + * @param 数据库值对象类型 + */ +public abstract class AbstractEntityDao { + protected ModelTable modelTable; + protected String tableName; + protected Map columns = new HashMap<>(); + protected Class type; + protected CacheManager cacheManager = SpringUtil.getBean(CacheManager.class); +// public AbstractEntityDao(String tableName) { +// this.tableName = tableName; +// } + + /** + * 通过值对象类型构造值对象数据库访问 + * + * @param type 值对象类型 + */ + public AbstractEntityDao(Class type) { + this.type = type; + // type.isAnnotationPresent(Table.class); + SwTable table = type.getAnnotation(SwTable.class); + Class superclass = type.getSuperclass(); + + if (table == null && superclass != null) { + table = superclass.getAnnotation(SwTable.class); + } + + if (table == null) { + throw new IllegalAccessError("not find annotation @SwTable"); + } + + tableName = table.value(); + modelTable = ModelTableCache.getInstance().getByName(tableName); + if (DefaultEntity.class.isAssignableFrom(type)) { + for (ModelField field : modelTable.getFields()) { + add(field, null, null); + } + } else { + for (ModelField field : modelTable.getFields()) { + String voFieldName = getVoFieldName(modelTable.getAbbr(), field.getName()); + // 处理get method + try { + PropertyDescriptor pd = new PropertyDescriptor(voFieldName, type); + // 获得get方法 + Method readMethod = pd.getReadMethod(); + Method writeMethod = pd.getWriteMethod(); + + if (readMethod != null && writeMethod != null) { + Class[] parameterTypes = writeMethod.getParameterTypes(); + if (parameterTypes.length == 1 && ClassUtils.isAssignable(parameterTypes[0], readMethod.getReturnType())) { + add(field, readMethod, writeMethod); + } + } + } catch (IntrospectionException ignore) { + } + } + } + } + + /** + * 通过值对象类型构造值对象数据库访问 + * + * @param tableName 表名 + */ + public AbstractEntityDao(String tableName) { + this.tableName = tableName; + this.type = (Class) DefaultEntity.class; + modelTable = cacheManager.getCache(ModelTableCache.class).getByName(tableName); + + for (ModelField field : modelTable.getFields()) { + add(field, null, null); + } + } + + /** + * 根据字段名,得到类中的字段属性名 + * + * @param tbAbbr 表缩写,一般是字段的前缀 + * @param fieldName 字段名 + * @return + */ + private String getVoFieldName(String tbAbbr, String fieldName) { + fieldName = fieldName.toLowerCase(); + tbAbbr = tbAbbr.toLowerCase() + "_"; + if (fieldName.startsWith(tbAbbr)) return VariableUtil.underlineToHump(fieldName.substring(tbAbbr.length())); + return VariableUtil.underlineToHump(fieldName); + } + + /** + * 添加值对象的属性访问方法何注解值 + * + * @param field 字段名 + * @param readMethod 读值对象属性方法 + * @param writeMethod 写值值对象属性方法 + */ + protected void add(ModelField field, Method readMethod, Method writeMethod) { + EntityColumn beanColumn = new EntityColumn(field, readMethod, writeMethod); + columns.put(field.getName(), beanColumn); + } + + protected void updateTime(T obj, int type) { + ModelField field = modelTable.findFieldByType(type); + if (field == null) return; + EntityColumn col = columns.get(field.getName()); + if (col != null) { + col.writeValue(obj, DateUtil.nowDateTimeLong()); + } + } + + /** + * 校验传入的字段,如没有创建时间和最后更改时间,则加上 + * + * @param fields + * @return + */ + protected List adjustFields(String fields, int... types) { + if (StringUtils.isEmpty(fields)) return null; + String[] fieldNames = fields.toLowerCase().split(","); + List listFields = new ArrayList<>(fieldNames.length + 2); + boolean[] includeTypes = new boolean[types.length]; + for (int i = 0, len = includeTypes.length; i < len; i++) { + includeTypes[i] = false; + } + + for (String name : fieldNames) { + EntityColumn column = this.columns.get(name.trim()); + for (int i = 0, len = types.length; i < len; i++) { + if (types[i]== column.getField().getFieldType()) { + includeTypes[i] = true; + } + } + listFields.add(name); + } + for (int i = 0, len = types.length; i < len; i++) { + if (!includeTypes[i]) { + ModelField field = modelTable.findFieldByType(types[i]); + if (field != null) listFields.add(field.getName()); + } + } + return listFields; + } + + /** + * 拼接插入SQL语句 + * + * @param obj 值对象 + * @param sql 记录sql的字符缓存 + * @param fields 逗号分割字段列表,设置为null表示使用所有字段 + * @return SQL参数列表 + */ + protected Object[] handleInsert(T obj, StringBuilder sql, String fields) { + List result; + List listFields = adjustFields(fields, SwEnum.FieldType.CREATE_TIME.value, SwEnum.FieldType.LAST_TIME.value); + sql.append("insert into ").append(modelTable.getSchemaTableName()).append("("); + + updateTime(obj, SwEnum.FieldType.CREATE_TIME.value); + updateTime(obj, SwEnum.FieldType.LAST_TIME.value); + + if (listFields == null) { + result = new ArrayList<>(this.columns.size()); + + for (EntityColumn column : this.columns.values()) { + result.add(column.readValue(obj)); + sql.append(column.getField().getName()).append(","); + } + } else { + result = new ArrayList<>(listFields.size()); + + for (String name : listFields) { + EntityColumn column = this.columns.get(name.trim()); + result.add(column.readValue(obj)); + sql.append(column.getField().getName()).append(","); + } + } + + sql.setCharAt(sql.length() - 1, ')'); + + // values(?,?) + sql.append(" values("); + for (int i = result.size(); i > 0; i--) { + sql.append("?,"); + } + sql.setCharAt(sql.length() - 1, ')'); + + return result.toArray(); + } + + /** + * 拼接更新SQL语句 + * + * @param obj 值对象 + * @param sql 记录sql的字符缓存 + * @param fields 逗号分割更新字段列表,设置为null表示使用所有字段 + * @param whereFields 逗号分割查询字段列表,设置为null表示使用ID字段作为查询条件 + * @return SQL参数列表 + */ + protected Object[] handleUpdate(T obj, StringBuilder sql, String fields, String whereFields) { + EntityColumn idColumn = findIdColumn(); + + List listFields = adjustFields(fields, SwEnum.FieldType.LAST_TIME.value); + updateTime(obj, SwEnum.FieldType.LAST_TIME.value); + + sql.append("update ").append(modelTable.getSchemaTableName()).append(" set "); + List result = new ArrayList<>(); + + if (listFields == null) { + for (EntityColumn column : this.columns.values()) { + if (idColumn != column) { + sql.append(column.getField().getName()).append("=?,"); + result.add(column.readValue(obj)); + } + } + sql.setCharAt(sql.length() - 1, ' '); + + // 默认使用Id字段条件 + result.add(idColumn.readValue(obj)); + + sql.append("where ").append(idColumn.getField().getName()).append("=?"); + } else { + + for (String name : listFields) { + name = name.trim(); + EntityColumn beanColumn = getBeanColumn(name); + + sql.append(name).append("=?,"); + result.add(beanColumn.readValue(obj)); + + } + + sql.setCharAt(sql.length() - 1, ' '); + + if (StringUtils.isNotBlank(whereFields)) { + sql.append("where "); + boolean first = true; + for (String name : whereFields.split(",")) { + name = name.trim(); + if (first) { + first = false; + } else { + sql.append(" and "); + } + + sql.append(name).append("=?"); + result.add(readValue(obj, name)); + } + } else { + // 默认使用Id字段条件 + result.add(idColumn.readValue(obj)); + sql.append("where ").append(idColumn.getField().getName()).append("=?"); + } + } + return result.toArray(); + } + + private EntityColumn findIdColumn() { + ModelField field = modelTable.findIdField(); + EntityColumn idColumn = field != null ? columns.get(field.getName()) : null; + if (idColumn == null) { + throw new DbException(tableName + " not define id column"); + } + + return idColumn; + } + + /** + * 拼接删除值对象语句 + * + * @param obj 值对象 + * @param sql 记录sql的字符缓存 + * @return SQL参数列表 + */ + protected Object[] handleDelete(T obj, StringBuilder sql) { + EntityColumn idColumn = findIdColumn(); + + sql.append("DELETE FROM ").append(modelTable.getSchemaTableName()).append(" WHERE ").append(idColumn.getField()).append("=?"); + + return new Object[]{idColumn.readValue(obj)}; + } + + /** + * 拼接删除值对象语句,条件由外部设置 + * + * @param sql 记录sql的字符缓存 + */ + protected void handleDelete(StringBuilder sql) { + EntityColumn idColumn = findIdColumn(); + sql.append("DELETE FROM ").append(modelTable.getSchemaTableName()).append(" WHERE ").append(idColumn.getField().getName()).append("=?"); + } + + public Object readValue(T obj, String fieldName) { + if (obj == null) return null; + EntityColumn beanColumn = getBeanColumn(fieldName); + + return beanColumn.readValue(obj); + } + + private EntityColumn getBeanColumn(String fieldName) { + EntityColumn beanColumn = this.columns.get(fieldName); + + if (beanColumn == null) { + throw new DbException("not define column:" + fieldName); + } + + return beanColumn; + } + + /** + * 拼接查询SQL语句 + * + * @param sql SQL字符缓存 + * @param fields 逗号分割的查询字段列表,传入null表示全部值对象字段 + */ + public void handleSelect(StringBuilder sql, String fields) { + sql.append("select "); + + if (fields != null) { + sql.append(fields).append(' '); + } else { + for (String fieldName : columns.keySet()) { + sql.append(fieldName).append(','); + } + sql.setCharAt(sql.length() - 1, ' '); + } + + sql.append("from ").append(modelTable.getSchemaTableName()); + } + + protected void handleSelectOne(StringBuilder sql, String fields) { + EntityColumn idColumn = findIdColumn(); + + sql.append("select "); + + if (fields != null) { + sql.append(fields).append(' '); + } else { + for (EntityColumn field : columns.values()) { + sql.append(field.getField().getName()).append(","); + } + sql.setCharAt(sql.length() - 1, ' '); + } + + sql.append("from ").append(modelTable.getSchemaTableName()).append(" where ").append(idColumn.getField().getName()).append("=?"); + } + + /** + * 读取ID值 + * + * @param entity + * @return + */ + public Long readId(T entity) { + EntityColumn idColumn = findIdColumn(); + + return (Long) idColumn.readValue(entity); + } + + public T createBean() { + try { + T bean = this.type.newInstance(); + if (bean instanceof DefaultEntity) { + DefaultEntity b = (DefaultEntity)bean; + b.init(); + b.setTableName(this.tableName); + } + return bean; + } catch (Exception e) { + throw new SwException(e); + } + } +} + diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumnForeign.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumnForeign.java new file mode 100644 index 0000000..49c4d7d --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumnForeign.java @@ -0,0 +1,26 @@ +package cc.smtweb.framework.core.db.dao; + +import lombok.Getter; + +/** + * 字段外键属性 + * @author admin + */ +@Getter +public class EntityColumnForeign { + private final String table; + private final String id; + private final String name; + + /** + * 构造字段外键属性 + * @param table 外键表名 + * @param id 外键ID字段名 + * @param name 外键名称字段名 + */ + public EntityColumnForeign(String table, String id, String name) { + this.table = table; + this.id = id; + this.name = name; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java new file mode 100644 index 0000000..f73b50d --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java @@ -0,0 +1,556 @@ +package cc.smtweb.framework.core.db.impl; + +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelIndex; +import cc.smtweb.framework.core.db.vo.ModelTable; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.text.MessageFormat; +import java.util.*; + +/** + * Created with IntelliJ IDEA. + * User: AKhh + * Date: 12-12-21 下午2:41 + * 启动时检查数据库并自动建表、字段、索引; + */ +@Slf4j +@SuppressWarnings("UnusedDeclaration") +public class DatabaseUtil { + private static final int INDEX_NAME_MAX_LENGTH = 30; //索引名称长度; + private static final String MODULE = DatabaseUtil.class.getName(); + private IDatabaseInfo databaseInfo; + //是否需要根据实体定义清理数据库字段 + private boolean is_db_clean_field = false; + //是否需要根据实体定义清理数据库表 + private boolean is_db_clean_table = false; + + public DatabaseUtil(boolean is_db_clean_field, boolean is_db_clean_table) { + this.is_db_clean_field = is_db_clean_field; + this.is_db_clean_table = is_db_clean_table; + this.databaseInfo = new DefaultDatabaseInfoImpl(); + } + + /** + * 检测数据库结构和配置是否一致,根据配置增加表或字段信息; + */ + public void checkDb() { + UtilTime timer = new UtilTime(); + timer.setLog(true); + timer.timerString("Start - 开始获取连接的数据库的元信息!"); + this.databaseInfo.printDatabaseInfo(); + // get ALL tables from this database + Map tableNames = this.databaseInfo.getTables(); + //Set fkTableNames = (tableNames == null ? null : new HashSet(tableNames.values())); + //Set indexTableNames = (tableNames == null ? null : new HashSet(tableNames.values())); + if (tableNames == null) { + String message = "不能从数据库获取表名信息,将被跳过..."; + log.error(message, MODULE); + return; + } + timer.timerString("已从数据库获取所有的表名信息!"); + // get ALL column info, put into hashmap by table name + Map> colInfo = this.databaseInfo.getColumnInfo(tableNames); + if (colInfo == null) { + String message = "不能从数据库获取字段列信息,将被跳过..."; + log.error(message, MODULE); + return; + } + timer.timerString("已获取所有的数据库字段列信息。"); + //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + timer.timerString("开始检查表,列定义信息....................................."); + Collection ModelTableDefList = ModelTableCache.getInstance().getAll(); + Iterator ModelTableIter = ModelTableDefList.iterator(); + int curEnt = 0; + int totalEnt = ModelTableDefList.size(); + List entitiesAdded = new LinkedList<>(); // 数据库中没有的实体, 通过建表 + // 数据库中有表, 也有对应的实体 + Map entitiesExist = new HashMap<>(); + while (ModelTableIter.hasNext()) { + curEnt++; + ModelTable entity = ModelTableIter.next(); + String entMessage = "(" + timer.timeSinceLast() + "ms) Checking #" + curEnt + "/" + totalEnt + " Entity " + entity.getName(); + log.info(entMessage, MODULE); + String k = entity.getName(); //表名 + // -make sure all entities have a corresponding table + if (tableNames.containsKey(k)) { + IDatabaseInfo.TableCheckInfo table = tableNames.remove(k); + entitiesExist.put(table, entity); + if (colInfo != null) { + List delCols = new ArrayList<>(); + Map fieldColNames = new HashMap<>(); + for (int fnum = 0, len = entity.getFields().size(); fnum < len; fnum++) { + ModelField field = entity.getFields().get(fnum); + fieldColNames.put(field.getName().toUpperCase(), field); // XML读出来是小写,数据库读取来是大写. + } + List colList = colInfo.get(entity.getName()); + int numCols = 0; + if (colList != null) { + for (; numCols < colList.size(); numCols++) { + IDatabaseInfo.ColumnCheckInfo ccInfo = colList.get(numCols); + ccInfo.columnName = ccInfo.columnName.toUpperCase(); + // -list all columns that do not have a corresponding field + if (fieldColNames.containsKey(ccInfo.columnName)) { + ModelField field = fieldColNames.remove(ccInfo.columnName); + SwEnum.DataTypeBean modelFieldType = SwEnum.DataType.instance.getByValue(field.getDataType()); + if (modelFieldType != null) { + // make sure each corresponding column is of the correct type + if (!ccInfo.typeName.equalsIgnoreCase(modelFieldType.sqlType)) { + String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段类型不一致:::数据库:[" + ccInfo.typeName + "], " + + "实体定义:[" + modelFieldType.sqlType + "]!"; + log.error(message, MODULE); + } + if (modelFieldType.dataLength != 0 && ccInfo.columnSize != -1 && modelFieldType.dataLength != ccInfo.columnSize) { + String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段长度不一致:::数据库:[" + ccInfo.columnSize + "], " + + "实体定义:[" + modelFieldType.dataLength + "]!"; + log.debug(message, MODULE); + } + /*if (decimalDigits != -1 && decimalDigits != ccInfo.decimalDigits) { + String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 小数位数不一致:::数据库:[" + ccInfo.decimalDigits + "], " + + "实体定义:[" + decimalDigits + "]!"; + log.debug(message, MODULE); + }*/ + } else { + String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段类型定义错误[" + field.getDataType() + "]!"; + + log.error(message, MODULE); + } + } else { + String message = "表\"" + entity.getName() + "\"字段\"" + ccInfo.columnName + "\"没有定义!"; + log.debug(message, MODULE); + if (is_db_clean_field) { + delCols.add(ccInfo.columnName); + } + } + } + } + // -display message if number of table columns does not match number of entity fields + if (!is_db_clean_field) { + if (numCols != entity.getFields().size()) { + String message = "表[" + entity.getName() + "]定义了" + entity.getFields().size() + "个字段,但数据库有" + numCols + "个字段!"; + log.debug(message, MODULE); + } + } else if (delCols.size() > 0) { + String errMsg = dropColumn(entity, delCols); + String message; + if (errMsg != null && errMsg.length() > 0) { + message = "清理字段出错,表:\"" + entity.getName() + "\": " + errMsg; + log.error(message, MODULE); + } else { + message = "清理字段成功,表:\"" + entity.getName() + "\""; + log.debug(message, MODULE); + } + } + // -list all fields that do not have a corresponding column + for (String colName : fieldColNames.keySet()) { + ModelField field = fieldColNames.get(colName); + String message = "Field \"" + field.getName() + "\" of entity \"" + entity.getName() + "\" is missing its corresponding column \"" + field.getName() + "\""; + log.debug(message, MODULE); + // add the column + String errMsg = addColumn(entity, field); + if (errMsg != null && errMsg.length() > 0) { + message = "加字段出错,表:\"" + entity.getName() + "\".\"" + field.getName() + "\": " + errMsg; + log.error(message, MODULE); + } else { + message = "加字段成功,表:\"" + entity.getName() + "\".\"" + field.getName() + "\""; + log.debug(message, MODULE); + } + } + //修复主键 + if (StringUtils.isEmpty(table.pk)) { + String errMsg = addPk(entity); + String message; + if (errMsg != null && errMsg.length() > 0) { + message = "修复主键出错,表:\"" + entity.getName() + "\": " + errMsg; + log.error(message, MODULE); + } else { + message = "修复主键成功,表:\"" + entity.getName() + "\""; + log.debug(message, MODULE); + } + } + } + } else { + String message = "数据库没有找到表\"" + entity.getName() + "\""; + log.debug(message, MODULE); + // create the table + String errMsg = createTable(entity); + if (StringUtils.isNotEmpty(errMsg)) { + message = "建表\"" + entity.getName() + "\"出错: " + errMsg; + log.error(message, MODULE); + } else { + entitiesAdded.add(entity); + message = "建表成功\"" + entity.getName() + "\""; + log.debug(message, MODULE); + } + } + } + timer.timerString("After Individual Table/Column Check"); + // -list all tables that do not have a corresponding entity + Iterator tableNamesIter = tableNames.keySet().iterator(); + while (tableNamesIter != null && tableNamesIter.hasNext()) { + String tableName = tableNamesIter.next(); + if (!is_db_clean_table) { + String message = "表\"" + tableName + "\"没有实体定义文件!"; + log.debug(message, MODULE); + } else { + String message, errMsg = dropTable(tableNames.get(tableName).catalog, tableName); + if (StringUtils.isNotEmpty(errMsg)) { + message = "删除表\"" + tableName + "\"出错: " + errMsg; + log.error(message, MODULE); + } else { + message = "删除表成功\"" + tableName + "\""; + log.debug(message, MODULE); + } + } + } + + // for each newly added table, add declared indexes + for (ModelTable curEntity : entitiesAdded) { + String indErrMsg = this.createDeclaredIndices(curEntity); + if (indErrMsg != null && indErrMsg.length() > 0) { + String message = "建索引出错,表\"" + curEntity.getName() + "\": " + indErrMsg; + log.error(message, MODULE); + } else { + String message = "建索引成功,表 \"" + curEntity.getName() + "\""; + log.debug(message, MODULE); + } + } + // 补充索引 get ALL column info, put into hashmap by table name + Map>> tableIndexListMap = this.databaseInfo.getIndexInfo(entitiesExist.keySet(), true); + for (ModelTable entity : entitiesExist.values()) { + // 实体未定义索引. + if (entity.getIndexes().isEmpty()) + continue; + // get existing index map for this table + Map> exists_indexes = tableIndexListMap.get(entity.getName()); + Set setEnabled = new HashSet<>();//有效的索引 + for (ModelIndex mi: entity.getIndexes()) { + if (SwEnum.IndexType.PK.value.equalsIgnoreCase(mi.getType())) continue; + + Set dbfields = null; + String indexName = getDbIndexName(entity, mi); + if (exists_indexes != null) dbfields = exists_indexes.get(indexName); + setEnabled.add(mi.getName()); + if (!hasDiff(mi.getFields(), dbfields)) {//没有变化,不管 + continue; + } + if (dbfields != null) deleteDeclaredIndex(entity.getSchemaTableName(), indexName); + + // 建数据库已经有表的不存在的索引 + String indErrMsg = this.createDeclaredIndex(entity, mi); + if (indErrMsg != null && indErrMsg.length() > 0) { + String message = "建索引出错,表:\"" + entity.getName() + "\".\"" + mi.getName() + "\": " + indErrMsg; + log.error(message, MODULE); + } else { + String message = "Created declared index [" + mi.getName() + "] for entity \"" + entity.getName() + "\""; + log.debug(message, MODULE); + } + } + for (String indexName : exists_indexes.keySet()) { + if (!setEnabled.contains(indexName)) deleteDeclaredIndex(entity.getSchemaTableName(), indexName); + } + } + timer.timerString("数据库结构检测和同步完成!"); + } + + //顺序不一致,也要重建 + private boolean hasDiff(String fields1, Set fields2) { + if (StringUtils.isEmpty(fields1) || fields2 == null) return true; + String[] f1 = fields1.split(","); + if (fields1.length() != fields2.size()) return true; + int n = 0; + for (String s : fields2) { + if (!s.equalsIgnoreCase(f1[n].toLowerCase())) return true; + n++; + } + return false; + } + + /** + * 建表 + * + * @param entity ModelTable + * @return String 错误消息 + */ + public String createTable(ModelTable entity) { + if (entity == null) { + return "ModelTable was null and is required to create a table"; + } + +// entity.setCurCreated(true); + StringBuilder sqlBuf = new StringBuilder("CREATE TABLE "); + sqlBuf.append(entity.getSchemaTableName()); + sqlBuf.append(" ("); + for (ModelField field : entity.getFields()) { + SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType()); + + if (type == null) { + return "Field type [" + field.getDataType() + "] not found for field [" + field.getName() + "] of entity [" + entity.getName() + "], not creating table."; + } + + sqlBuf.append(field.getName()); + sqlBuf.append(" "); + sqlBuf.append(type.getSqlTypeCreate()); + + if (field.getName().equalsIgnoreCase(entity.getIdField())) { + sqlBuf.append(" NOT NULL , "); + } else { + if (!StringUtils.isEmpty(field.getDefaultValue())) { + sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'"); + } + sqlBuf.append(" , "); + } + } + String pkName = "PK_" + entity.getName(); + if (pkName.length() > INDEX_NAME_MAX_LENGTH) { + pkName = pkName.substring(0, INDEX_NAME_MAX_LENGTH); + } + sqlBuf.append("CONSTRAINT "); + sqlBuf.append(pkName); + sqlBuf.append(" PRIMARY KEY ("); + sqlBuf.append(entity.getIdField()); + sqlBuf.append("))"); + + try { + DbEngine.getInstance().update(sqlBuf.toString()); + } catch (Exception e) { + return e.getMessage(); + } + addTableComment(entity); + //加上字段注解: + for (ModelField field : entity.getFields()) { + addColumnComment(entity, field); + } + return null; + } + + public String addColumn(ModelTable entity, ModelField field) { + if (entity == null || field == null) { + return "ModelTable or ModelField where null, cannot add column"; + } + SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType()); + if (type == null) { + return "Field type not found for field [" + field.getName() + "] of entity [" + entity.getName() + "], not adding column."; + } + StringBuilder sqlBuf = new StringBuilder(128); + sqlBuf.append(MessageFormat.format("ALTER TABLE {0} ADD {1} {2}", entity.getSchemaTableName(), field.getName(), type.getSqlTypeCreate())); + if (!StringUtils.isEmpty(field.getDefaultValue())) { + sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'"); + } + log.debug("正在增加字段" + entity.getName() + "." + field.getName()); + try { + DbEngine.getInstance().update(sqlBuf.toString()); + } catch (Exception e) { + sqlBuf.setLength(0); + sqlBuf.append("ALTER TABLE ").append(entity.getSchemaTableName()).append(" ADD COLUMN ").append(field.getName()).append(" ").append(type.getSqlTypeCreate()); + if (StringUtils.isNotEmpty(field.getDefaultValue())) { + sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'"); + } + try { + DbEngine.getInstance().update(sqlBuf.toString()); + } catch (Exception e1) { + return e.getMessage(); + } + } + //加上字段注解: + addColumnComment(entity, field); + return null; + } + + public String addPk(ModelTable entity) { + if (entity == null) { + return "实体为null!"; + } + if (StringUtils.isEmpty(entity.getPkFieldName())) { + return "表" + entity.getName() + "没有定义主键!"; + } + String pkName = "PK_" + entity.getName(); + if (pkName.length() > INDEX_NAME_MAX_LENGTH) { + pkName = pkName.substring(0, INDEX_NAME_MAX_LENGTH); + } + StringBuilder sqlBuf = new StringBuilder(128); + sqlBuf.append("ALTER TABLE ").append(entity.getSchemaTableName()).append(" ADD CONSTRAINT ") + .append(pkName).append(" PRIMARY KEY (").append(entity.getIdField()).append(")"); + try { + DbEngine.getInstance().update(sqlBuf.toString()); + } catch (Exception e) { + return e.getMessage(); + } + return null; + } + + //删除表列 + public String dropColumn(ModelTable entity, List delCols) { + if (delCols.isEmpty()) return null; + StringBuilder sql = new StringBuilder(128); + sql.append("ALTER TABLE " + entity.getSchemaTableName()).append("\nDROP COLUMN("); + for (String col : delCols) { + sql.append(col).append(","); + } + + log.debug("正在删除表字段" + entity.getName()); + try { + DbEngine.getInstance().update(sql.substring(0, sql.length() - 1) + ")"); + } catch (Exception e) { + return e.getMessage(); + } + return null; + } + + //删除表 + public String dropTable(String catalog, String tableName) { + if (StringUtils.isNotEmpty(catalog)) tableName = catalog + "." + tableName; + log.debug("正在删除表" + tableName); + try { + DbEngine.getInstance().update("drop table " + tableName); + } catch (Exception e) { + return e.getMessage(); + } + return null; + } + + private String addTableComment(ModelTable entity) { + log.debug("正在增加表说明" + entity.getName()); + try { + DbEngine.getInstance().update("ALTER TABLE " + entity.getSchemaTableName() + " COMMENT '" + entity.getTitle() + "'"); + } catch (Exception e) { + return e.getMessage(); + } + return null; + } + + private String addColumnComment(ModelTable entity, ModelField field) { + log.debug("正在增加字段说明" + entity.getName() + "." + field.getName()); + // comment on column BASE_ENUM.DESCRIPTION is + SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType()); + if (type == null) return null; + try { + String defValue = StringUtils.isNotEmpty(field.getDefaultValue()) ? "'" + field.getDefaultValue() + "'" : ""; + String dvs = StringUtils.isNotEmpty(field.getDefaultValue()) ? " DEFAULT '" + field.getDefaultValue() + "'" : ""; + String sql = "ALTER TABLE " + entity.getSchemaTableName() + " MODIFY COLUMN " + field.getName() + " " + type.getSqlTypeCreate() + dvs + " COMMENT '" + field.getRemark() + "'"; + DbEngine.getInstance().update(sql); + } catch (Exception e) { + return e.getMessage(); + } + return null; + } + + /** + * 建立索引 + * + * @param entity 实体定义对象; + * @return 错误消息,处理正确会返回null + */ + public String createDeclaredIndices(ModelTable entity) { + if (entity == null) { + return "ModelTable was null and is required to create declared indices for a table"; + } + StringBuilder retMsgsBuffer = new StringBuilder(); + // go through the indexes to see if any need to be added + Iterator indexesIter = entity.getIndexes().iterator(); + for (ModelIndex modelIndex : entity.getIndexes()) { + String retMsg = createDeclaredIndex(entity, modelIndex); + if (retMsg != null && retMsg.length() > 0) { + if (retMsgsBuffer.length() > 0) { + retMsgsBuffer.append("\n"); + } + retMsgsBuffer.append(retMsg); + } + } + if (retMsgsBuffer.length() > 0) { + return retMsgsBuffer.toString(); + } else { + return null; + } + } + + private String createDeclaredIndex(ModelTable entity, ModelIndex modelIndex) { + log.debug("正在创建索引" + entity.getName() + "." + modelIndex.getName() + "....."); + String createIndexSql = makeIndexClause(entity, modelIndex); + if (StringUtils.isEmpty(createIndexSql)) return null; + try { + DbEngine.getInstance().update(createIndexSql); + } catch (Exception sqle) { + return "SQL Exception while executing the following:\n" + createIndexSql + "\nError was: " + sqle.toString(); + } + return null; + } + + /** + * 构造建立索引的脚本 + * + * @param entity 实体 + * @param modelIndex 索引定义; + * @return 脚本; + */ + private String makeIndexClause(ModelTable entity, ModelIndex modelIndex) { + if (SwEnum.IndexType.PK.value.equalsIgnoreCase(modelIndex.getType())) return null; + SwEnum.IndexTypeBean type = SwEnum.IndexType.instance.getByValue(modelIndex.getType()); + return "CREATE " + (SwEnum.IndexType.U.value.equalsIgnoreCase(modelIndex.getType()) ? SwEnum.IndexType.U.fullName : "") + + " INDEX " + getDbIndexName(entity, modelIndex) + + " ON " + entity.getSchemaTableName() + " (" + modelIndex.getFields() + ")"; + } + + /** + * 删除已经实体已经定义的索引 + * + * @param entity 实体 + * @return sql + */ + private String deleteDeclaredIndices(ModelTable entity) { + if (entity == null) { + return "ModelTable was null and is required to delete foreign keys indices for a table"; + } + StringBuilder retMsgsBuffer = new StringBuilder(); + // go through the relationships to see if any foreign keys need to be added + for (ModelIndex modelIndex : entity.getIndexes()) { + String retMsg = deleteDeclaredIndex(entity, modelIndex); + if (retMsg != null && retMsg.length() > 0) { + if (retMsgsBuffer.length() > 0) { + retMsgsBuffer.append("\n"); + } + retMsgsBuffer.append(retMsg); + } + } + if (retMsgsBuffer.length() > 0) { + return retMsgsBuffer.toString(); + } else { + return null; + } + } + + /** + * 删除已经定义的索引 + * + * @param entity 实体 + * @param modelIndex 索引; + * @return sql + */ + private String deleteDeclaredIndex(ModelTable entity, ModelIndex modelIndex) { + String deleteIndexSql = "DROP INDEX " + entity.getSchemaTableName() + "." + getDbIndexName(entity, modelIndex); + try { + DbEngine.getInstance().update(deleteIndexSql); + } catch (Exception sqle) { + return "SQL Exception while executing the following:\n" + deleteIndexSql + "\nError was: " + sqle.toString(); + } + return null; + } + + private String deleteDeclaredIndex(String tableName, String indexName) { + String deleteIndexSql = "DROP INDEX " + indexName + " ON " + tableName; + try { + DbEngine.getInstance().update(deleteIndexSql); + } catch (Exception sqle) { + return "SQL Exception while executing the following:\n" + deleteIndexSql + "\nError was: " + sqle.toString(); + } + return null; + } + + private String getDbIndexName(ModelTable entity, ModelIndex modelIndex) { + return entity.getAbbr() + "_" + modelIndex.getName(); + } +} \ No newline at end of file diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultDatabaseInfoImpl.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultDatabaseInfoImpl.java new file mode 100644 index 0000000..8e98425 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultDatabaseInfoImpl.java @@ -0,0 +1,365 @@ +package cc.smtweb.framework.core.db.impl; + +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.cache.ModelDatabaseCache; +import cc.smtweb.framework.core.db.vo.ModelDatabase; +import cc.smtweb.framework.core.util.SpringUtil; +import com.sun.org.apache.xpath.internal.operations.Mod; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.jdbc.support.JdbcUtils; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.function.Function; + +/** + * Created with IntelliJ IDEA. + * User: AKhh + * Date: 12-12-21 下午10:14 + * 获取连接的数据库相关信息,from ofbiz + */ +@Slf4j +public class DefaultDatabaseInfoImpl implements IDatabaseInfo { + private static final String MODULE = DefaultDatabaseInfoImpl.class.getName(); + private DbEngine dbEngine = SpringUtil.getBean(DbEngine.class); + + @SuppressWarnings("unchecked") + public void printDatabaseInfo() { + dbEngine.doConn(connection -> { + try { + DatabaseMetaData dbData = connection.getMetaData(); + // 数据库信息 + try { + log.debug("Database Product Name is " + dbData.getDatabaseProductName(), MODULE); + log.debug("Database Product Version is " + dbData.getDatabaseProductVersion(), MODULE); + } catch (SQLException sqle) { + log.debug("Unable to get Database name & version information", MODULE); + } + // JDBC Driver Info + try { + log.debug("Database Driver Name is " + dbData.getDriverName(), MODULE); + log.debug("Database Driver Version is " + dbData.getDriverVersion(), MODULE); + } catch (SQLException sqle) { + log.debug("Unable to get Driver name & version information", MODULE); + } + // Db/Driver support settings + try { + log.debug("Database Setting/Support Information (those with a * should be true):", MODULE); + log.debug("- supports transactions [" + dbData.supportsTransactions() + "]*", MODULE); + log.debug("- isolation None [" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE) + "]", MODULE); + log.debug("- isolation ReadCommitted [" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED) + "]", MODULE); + log.debug("- isolation ReadUncommitted[" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED) + "]", MODULE); + log.debug("- isolation RepeatableRead [" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ) + "]", MODULE); + log.debug("- isolation Serializable [" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE) + "]", MODULE); + log.debug("- is case sensitive [" + dbData.supportsMixedCaseIdentifiers() + "]", MODULE); + log.debug("- stores LowerCase [" + dbData.storesLowerCaseIdentifiers() + "]", MODULE); + log.debug("- stores MixedCase [" + dbData.storesMixedCaseIdentifiers() + "]", MODULE); + log.debug("- stores UpperCase [" + dbData.storesUpperCaseIdentifiers() + "]", MODULE); + log.debug("- max table name length [" + dbData.getMaxTableNameLength() + "]", MODULE); + log.debug("- max column name length [" + dbData.getMaxColumnNameLength() + "]", MODULE); + log.debug("- max schema name length [" + dbData.getMaxSchemaNameLength() + "]", MODULE); + log.debug("- concurrent connections [" + dbData.getMaxConnections() + "]", MODULE); + log.debug("- concurrent statements [" + dbData.getMaxStatements() + "]", MODULE); + log.debug("- ANSI SQL92 Entry [" + dbData.supportsANSI92EntryLevelSQL() + "]", MODULE); + log.debug("- ANSI SQL92 Itermediate [" + dbData.supportsANSI92IntermediateSQL() + "]", MODULE); + log.debug("- ANSI SQL92 Full [" + dbData.supportsANSI92FullSQL() + "]", MODULE); + log.debug("- ODBC SQL Grammar Core [" + dbData.supportsCoreSQLGrammar() + "]", MODULE); + log.debug("- ODBC SQL Grammar Extended[" + dbData.supportsExtendedSQLGrammar() + "]", MODULE); + log.debug("- ODBC SQL Grammar Minimum [" + dbData.supportsMinimumSQLGrammar() + "]", MODULE); + log.debug("- outer joins [" + dbData.supportsOuterJoins() + "]*", MODULE); + log.debug("- limited outer joins [" + dbData.supportsLimitedOuterJoins() + "]", MODULE); + log.debug("- full outer joins [" + dbData.supportsFullOuterJoins() + "]", MODULE); + log.debug("- group by [" + dbData.supportsGroupBy() + "]*", MODULE); + log.debug("- group by not in select [" + dbData.supportsGroupByUnrelated() + "]", MODULE); + log.debug("- column aliasing [" + dbData.supportsColumnAliasing() + "]", MODULE); + log.debug("- order by not in select [" + dbData.supportsOrderByUnrelated() + "]", MODULE); + // this doesn't work in HSQLDB, other databases? Debug.logInfo("- named parameters [" + dbData.supportsNamedParameters() + "]", MODULE); + log.debug("- alter table add column [" + dbData.supportsAlterTableWithAddColumn() + "]*", MODULE); + log.debug("- non-nullable column [" + dbData.supportsNonNullableColumns() + "]*", MODULE); + } catch (Exception e) { + log.error("Unable to get misc. support/setting information", e); + } + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + return null; + }); + } + + //需要考虑分库的情况 + @SuppressWarnings("unchecked") + public Map getTables() { + final Map tables = new TreeMap<>(); + dbEngine.doConn(new Function() { + @Override + public Object apply(Connection connection) { + try { + DatabaseMetaData dbData = connection.getMetaData(); + if (dbData == null) { + return null; + } + System.out.println("获取数据库表信息..............................."); + boolean needsUpperCase = false; + try { + needsUpperCase = dbData.storesLowerCaseIdentifiers() || dbData.storesMixedCaseIdentifiers(); + } catch (SQLException sqle) { + String message = "Error getting identifier case information... Error was:" + sqle.toString(); + log.error(message, MODULE); + } + String lookupSchemaName = null; + if (dbData.supportsSchemasInTableDefinitions()) { + lookupSchemaName = dbData.getUserName(); + } + if (dbEngine.isMysql()) {//非oracle才需要 + String dbName = dbEngine.getDbSchema(); + Collection list = ModelDatabaseCache.getInstance().getAll(); + if (list != null && !list.isEmpty()) { + for (ModelDatabase db : list) { + getTableSet(dbData, dbName + "_" + db.getName(), needsUpperCase, lookupSchemaName); + } + } + //当前库都要去读 + getTableSet(dbData, dbName, needsUpperCase, lookupSchemaName); + } else { + //当前库都要去读 + getTableSet(dbData, null, needsUpperCase, lookupSchemaName); + } + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + return null; + } + + private void getTableSet(DatabaseMetaData dbData, String catalog, boolean needsUpperCase, String lookupSchemaName) { + ResultSet tableSet = null; + try { + String[] types = {"TABLE"/*,"VIEW", "ALIAS", "SYNONYM"*/}; + tableSet = dbData.getTables(catalog, lookupSchemaName, null, types); + while (tableSet.next()) { + String tableName = tableSet.getString("TABLE_NAME"); + // for those databases which do not return the schema name with the table name (pgsql 7.3) + //boolean appendSchemaName = false; + if (needsUpperCase && tableName != null) { + tableName = tableName.toUpperCase(); + } + //if (appendSchemaName) { + // tableName = String.format("%s.%s", lookupSchemaName, tableName); + //} + String tableType = tableSet.getString("TABLE_TYPE"); + // only allow certain table types + if (tableType != null && + !"TABLE".equalsIgnoreCase(tableType) && + !"BASE TABLE".equalsIgnoreCase(tableType) && + !"VIEW".equalsIgnoreCase(tableType) && + !"ALIAS".equalsIgnoreCase(tableType) && + !"SYNONYM".equalsIgnoreCase(tableType)) { + continue; + } + try (ResultSet pkSet = dbData.getPrimaryKeys(catalog, lookupSchemaName, tableName)) { + String s = ""; + while (pkSet.next()) { + s += "," + pkSet.getString(4); + } + TableCheckInfo table = new TableCheckInfo(); + table.tableName = tableName; + table.catalog = catalog; + if (StringUtils.isNotEmpty(s)) { + table.pk = s.substring(1); + } + tables.put(tableName, table); + } + } + } catch (SQLException sqle) { + String message = "Error getting next table information... Error was:" + sqle.toString(); + log.error(message, MODULE); + } finally { + JdbcUtils.closeResultSet(tableSet); + } + } + }); + return tables; + } + + @SuppressWarnings("unchecked") + //获取列信息 + public Map> getColumnInfo(final Map dbTables) { + // if there are no tableNames, don't even try to get the columns + final Map> colInfo = new HashMap<>(); + if (dbTables.size() == 0) { + return colInfo; + } + dbEngine.doConn(new Function() { + @Override + public Object apply(Connection connection) { + try { + DatabaseMetaData dbData = connection.getMetaData(); + boolean needsUpperCase = false; + try { + needsUpperCase = dbData.storesLowerCaseIdentifiers() || dbData.storesMixedCaseIdentifiers(); + } catch (SQLException sqle) { + String message = "Error getting identifier case information... Error was:" + sqle.toString(); + log.error(message, MODULE); + } + + String lookupSchemaName = null; + if (dbData.supportsSchemasInTableDefinitions()) { + lookupSchemaName = dbData.getUserName(); + } + + if (dbEngine.isMysql()) {//非oracle才需要 + String dbName = dbEngine.getDbSchema(); + Collection list = ModelDatabaseCache.getInstance().getAll(); + if (list != null && !list.isEmpty()) { + for (ModelDatabase db : list) { + String dn = SwConsts.DEF_DB_NAME.equals(db.getName()) ? "" : ("_" + db.getName()); + getColumnInfo(dbData, dbName + dn, needsUpperCase, lookupSchemaName); + } + } + } + +// getColumnInfo(dbData, null, needsUpperCase, lookupSchemaName); + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + return null; + } + + private void getColumnInfo(DatabaseMetaData dbData, String catalog, boolean needsUpperCase, String lookupSchemaName) { + ResultSet rsCols = null; + try { + rsCols = dbData.getColumns(catalog, lookupSchemaName, null, null); + while (rsCols.next()) { + ColumnCheckInfo ccInfo = new ColumnCheckInfo(); + + ccInfo.tableName = rsCols.getString("TABLE_NAME"); + // for those databases which do not return the schema name with the table name (pgsql 7.3) + //boolean appendSchemaName = false; + // AKzz : 不在表名前加用户名. + //if (ccInfo.tableName != null && lookupSchemaName != null && !ccInfo.tableName.startsWith(lookupSchemaName)) { + // appendSchemaName = true; + //} + if (needsUpperCase && ccInfo.tableName != null) { + ccInfo.tableName = ccInfo.tableName.toUpperCase(); + } + //if (appendSchemaName) { + // ccInfo.tableName = lookupSchemaName + "." + ccInfo.tableName; + //} + // ignore the column info if the table name is not in the list we are concerned with + if (!dbTables.containsKey(ccInfo.tableName)) { + continue; + } + ccInfo.columnName = rsCols.getString("COLUMN_NAME"); + if (needsUpperCase && ccInfo.columnName != null) { + ccInfo.columnName = ccInfo.columnName.toUpperCase(); + } + // NOTE: this may need a toUpperCase in some cases, keep an eye on it + ccInfo.typeName = rsCols.getString("TYPE_NAME"); + ccInfo.columnSize = rsCols.getInt("COLUMN_SIZE"); + ccInfo.decimalDigits = rsCols.getInt("DECIMAL_DIGITS"); + // NOTE: this may need a toUpperCase in some cases, keep an eye on it + ccInfo.isNullable = rsCols.getString("IS_NULLABLE"); + List tableColInfo = colInfo.get(ccInfo.tableName); + if (tableColInfo == null) { + tableColInfo = new ArrayList<>(); + colInfo.put(ccInfo.tableName, tableColInfo); + } + tableColInfo.add(ccInfo); + } + } catch (SQLException sqle) { + String message = "Error getting table fields information... Error was:" + sqle.toString(); + log.error(message, MODULE); + } finally { + JdbcUtils.closeResultSet(rsCols); + } + } + }); + return colInfo; + } + + @SuppressWarnings("unchecked") + //获取索引 + public Map>> getIndexInfo(final Collection tableNames, final boolean include_nounique) { + final Map>> indexInfo = new HashMap<>(); + if (!tableNames.isEmpty()) { + for (TableCheckInfo c : tableNames) { + indexInfo.put(c.tableName, new HashMap<>()); + } + dbEngine.doConn(connection -> { + try { + DatabaseMetaData dbData = connection.getMetaData(); + boolean needsUpperCase = false; + try { + needsUpperCase = dbData.storesLowerCaseIdentifiers() || dbData.storesMixedCaseIdentifiers(); + } catch (SQLException sqle) { + String message = "Error getting identifier case information... Error was:" + sqle.toString(); + log.error(message, MODULE); + } + +// int totalIndices = 0; + String lookupSchemaName = null; + if (dbData.supportsSchemasInTableDefinitions()) { + lookupSchemaName = dbData.getUserName(); + } + + for (TableCheckInfo curTableName : tableNames) { + ResultSet rsCols = null; + try { + // false for unique, we don't really use unique indexes + // true for approximate, don't really care if stats are up-to-date + rsCols = dbData.getIndexInfo(curTableName.catalog, lookupSchemaName, curTableName.tableName, !include_nounique, true); + while (rsCols != null && rsCols.next()) { + // NOTE: The code in this block may look funny, but it is designed so that the wrapping loop can be removed + // skip all index info for statistics + if (rsCols.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic) continue; + //HACK: for now skip all "unique" indexes since our foreign key indices are not unique, but the primary key ones are + //原来的方法: 只取了NON_UNIQUE == true的索引. + //if (!rsCols.getBoolean ("NON_UNIQUE")) continue; + boolean unique = rsCols.getBoolean("NON_UNIQUE"); + + //for (int x = 1; x<=rsCols.getMetaData().getColumnCount();x++){ + // System.out.println(rsCols.getMetaData().getColumnName(x) + " = " + rsCols.getString(x)); + //} + + //System.out.println("INDEX_NAME=" + rsCols.getString("INDEX_NAME") + " --- "+ "COLUMN_NAME=" + rsCols.getString("COLUMN_NAME") ); + + //改动, 可以取所有的索引. + if (include_nounique) { + // 要取nouniqune的 + } else { + // 不取nouniqune的, + if (!unique) continue; + } + String tableName = rsCols.getString("TABLE_NAME"); + if (needsUpperCase && tableName != null) { + tableName = tableName.toUpperCase(); + } + + String indexName = rsCols.getString("INDEX_NAME"); + if (needsUpperCase && indexName != null) { + indexName = indexName.toUpperCase(); + } + Map> tableIndexList = indexInfo.computeIfAbsent(tableName, k -> new HashMap<>()); + Set set = tableIndexList.computeIfAbsent(indexName, k -> new LinkedHashSet<>()); + // totalIndices++; + set.add(rsCols.getString("COLUMN_NAME")); + } + } catch (Exception e) { + log.debug("Error getting index info using lookupSchemaName " + lookupSchemaName, e); + } finally { + JdbcUtils.closeResultSet(rsCols); + } + } + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + return null; + }); + } + return indexInfo; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultEntity.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultEntity.java new file mode 100644 index 0000000..7583b6b --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultEntity.java @@ -0,0 +1,86 @@ +package cc.smtweb.framework.core.db.impl; + +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import cc.smtweb.framework.core.util.DateUtil; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; + +/** + * Created by Akmm at 14-1-2 上午11:19 + * 实体bean抽象类 + */ +public class DefaultEntity extends BaseBean implements Serializable, Cloneable { + //表名 + private final static String tableNameKey = "_def_table_name"; + private final static String statusKey = "_status"; + + public DefaultEntity() {} + + public DefaultEntity(String _def_table_name) { + this.put(tableNameKey,_def_table_name); + } + + public ModelTable getModelTable() { + return ModelTableCache.getInstance().getByName(getTableName()); + } + + public String getTableName() { + return getStr(tableNameKey); + } + public void setTableName(String tableName) { + put(tableNameKey, tableName); + } + + public void setIsNew(boolean isNew) { + put(statusKey, isNew); + } + + public boolean isNew() { + return getBool(statusKey) || getEntityId() <= 0L; + } + + public void removeStatus() { + data.remove(statusKey); + } + + //根据实体定义,设默认值 + public void init() { + ModelTable entity = getModelTable(); + if (entity == null) return; + String pkField = getPkFieldName(); + for (ModelField field : entity.getFields()) { + if (data.containsKey(field.getName())) continue;//有值了,不能动 + if (field.getName().equalsIgnoreCase(pkField)) continue;//是pk,不要初始化 + if (field.getFieldType() == SwEnum.FieldType.CREATE_TIME.value || field.getFieldType() == SwEnum.FieldType.LAST_TIME.value) { + put(field.getName(), DateUtil.nowDateTimeLong()); + } else { + String s = field.getDefaultValue(); + if (StringUtils.isNotEmpty(s)) put(field.getName(), s); + } + } + } + + /** 主键字段 */ + public String getPkFieldName() { + return getModelTable().getIdField(); + } + + public long getEntityId() { + return getLong(getPkFieldName()); + } + + public void setEntityId(long id) { + data.put(getPkFieldName(), id); + } + + @Override + public DefaultEntity clone() throws CloneNotSupportedException { + DefaultEntity bean = (DefaultEntity) super.clone(); + bean.getData().remove(getPkFieldName()); + return bean; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java new file mode 100644 index 0000000..a912e2c --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java @@ -0,0 +1,37 @@ +package cc.smtweb.framework.core.db.impl; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created with IntelliJ IDEA. + * User: AKhh + * Date: 12-12-21 下午10:13 + * To change this template use File | Settings | File Templates. + */ +public interface IDatabaseInfo { + void printDatabaseInfo(); + + Map getTables(); + + Map> getColumnInfo(Map dbTables); + + Map>> getIndexInfo(Collection tableNames, boolean include_nounique); + + class TableCheckInfo { + public String tableName; + public String catalog; + public String pk; + } + + class ColumnCheckInfo { + public String tableName; + public String columnName; + public String typeName; + public int columnSize; + public int decimalDigits; + public String isNullable; // Y|N or "" = ie nobody knows + } +} \ No newline at end of file diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/AbsDbWorker.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/AbsDbWorker.java new file mode 100644 index 0000000..fb87206 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/AbsDbWorker.java @@ -0,0 +1,13 @@ +package cc.smtweb.framework.core.db.jdbc; + +/** + * Created by Akmm at 14-2-15 下午1:51 + * 数据库事务操作方法类 + */ +public abstract class AbsDbWorker implements IDbWorker { + @Override + public void doAfterDbCommit() {} + + @Override + public void doAfterDbRollback(){} +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/IDbWorker.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/IDbWorker.java new file mode 100644 index 0000000..f24c35a --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/IDbWorker.java @@ -0,0 +1,15 @@ +package cc.smtweb.framework.core.db.jdbc; + +/** + * Created by Akmm at 14-2-3 下午4:52 + * 数据库事务操作方法类 + */ +public interface IDbWorker { + public void work(); + + //数据库提交完后的业务或缓存处理 + public void doAfterDbCommit(); + + //数据库回滚后的业务或缓存处理 + public void doAfterDbRollback(); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java new file mode 100644 index 0000000..ec46520 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java @@ -0,0 +1,508 @@ +package cc.smtweb.framework.core.db.jdbc; + +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.impl.BaseBean; +import cc.smtweb.framework.core.exception.DbException; +import cc.smtweb.framework.core.util.JsonUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * JDBC访问类,包装了spring jdbcTemplate对象 + */ +public class JdbcEngine { + private final static String DB_TYPE_MYSQL = "mysql"; + + private Map mapThreadTrans = new ConcurrentHashMap<>(); + private JdbcTemplate jdbcTemplate; + private NamedParameterJdbcTemplate namedJdbcTemplate; + private DataSourceTransactionManager dataSourceTransactionManager; + private IdGenerator idGenerator; + + protected String type; + + public JdbcEngine(NamedParameterJdbcTemplate namedJdbcTemplate, IdGenerator idGenerator, String type) { + this.namedJdbcTemplate = namedJdbcTemplate; + this.jdbcTemplate = namedJdbcTemplate.getJdbcTemplate(); + this.dataSourceTransactionManager = new DataSourceTransactionManager(jdbcTemplate.getDataSource()); + this.idGenerator = idGenerator; + this.type = type; + } + + public boolean isMysql() { + return DB_TYPE_MYSQL.equalsIgnoreCase(type); + } + + /** + * 获取数据库唯一id + * + * @return 返回ID值 + */ + public long nextId() { + return this.idGenerator.nextId(); + } + + /** + * 查询单行数据 + * + * @param sql 查询SQL + * @param rowHandler ResultSet处理器 + * @param 返回得对象类型 + * @return 返回单个对象数据 + */ + public T queryEntity(String sql, final ResultSetExtractor rowHandler) { + return jdbcTemplate.query(sql, rowHandler); + } + + /** + * 查询单行数据 + * + * @param sql 查询SQL + * @param rowHandler ResultSet处理器 + * @param params SQL参数 + * @param 返回得对象类型 + * @return 返回单个对象数据 + */ + public T queryEntity(String sql, final ResultSetExtractor rowHandler, Object... params) { + return jdbcTemplate.query(sql, rowHandler, params); + } + + /** + * 通过回调函数查询SQL,返回列表或者对象数据 + */ + public T query(String sql, ResultSetExtractor rse, Object... params) { + return jdbcTemplate.query(sql, rse, params); + } + + /** + * 查询SQL,返回列表数据 + */ + public List query(String sql, RowMapper rowMapper) { + return jdbcTemplate.query(sql, rowMapper); + } + + /** + * 查询SQL,返回列表数据 + */ + public List query(String sql, RowMapper rowMapper, Object... params) { + return jdbcTemplate.query(sql, rowMapper, params); + } + + /** + * 执行更新SQL + */ + public int update(String sql) { + return jdbcTemplate.update(sql); + } + + /** + * 执行更新SQL + */ + public int update(String sql, Object... params) { + return jdbcTemplate.update(sql, params); + } + + /** + * 查询字符list + * + * @param sql 查询SQL + * @param params 查询SQL参数 + * @return 字符list + */ + public List queryStringList(String sql, Object... params) { + return jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getString(1), params); + } + + /** + * 查询字符set + * + * @param sql 查询SQL + * @param params 查询SQL参数 + * @return 字符set + */ + public Set queryStringSet(String sql, Object... params) { + return jdbcTemplate.query(sql, (resultSet) -> { + Set result = new HashSet<>(); + while (resultSet.next()) { + String value = resultSet.getString(1); + if (value != null) { + result.add(value); + } + } + + return result; + }, params); + } + + /** + * 查询字符 + * + * @param sql 查询SQL + * @param params 查询SQL参数 + * @return 字符 + */ + public String queryString(String sql, Object... params) { + List list = jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getString(1), params); + if (list != null && !list.isEmpty()) { + return list.get(0); + } + + return null; + } + + /** + * 查询值为JSON格式,转换为对象返回 + * + * @param sql 查询SQL + * @param clazz 对象类 + * @param params 查询SQL参数 + * @param 对象类型 + * @return JSON格式,转换为对象返回 + */ + public T queryJson(String sql, Class clazz, Object... params) { + List list = jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getString(1), params); + if (list != null && !list.isEmpty()) { + String s = list.get(0); + if (StringUtils.isNotBlank(s)) { + return JsonUtil.parse(s, clazz); + } else { + try { + return clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new DbException(e); + } + } + } + + return null; + } + + /** + * 查询Long对象 + * + * @param sql 查询SQL + * @param params 查询SQL参数 + * @return Long对象 + */ + public Long queryLong(String sql, Object... params) { + List list = jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getLong(1), params); + if (list != null && !list.isEmpty()) { + return list.get(0); + } + + return null; + } + + /** + * 查询List对象 + * + * @param sql 查询SQL + * @param params 查询SQL参数 + * @return List对象 + */ + public List queryLongList(String sql, Object... params) { + return jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getLong(1), params); + } + + /** + * 查询Set对象 + * + * @param sql 查询SQL + * @param params 查询SQL参数 + * @return Set对象 + */ + public Set queryLongSet(String sql, Object... params) { + return jdbcTemplate.query(sql, (resultSet) -> { + Set result = new HashSet<>(); + while (resultSet.next()) { + long value = resultSet.getLong(1); + if (!resultSet.wasNull()) { + result.add(value); + } + } + + return result; + }, params); + } + + /** + * 查询Integer对象 + * + * @param sql 查询SQL + * @param params 查询SQL参数 + * @return Integer对象 + */ + public Integer queryInt(String sql, Object... params) { + List list = jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getInt(1), params); + if (list != null && !list.isEmpty()) { + return list.get(0); + } + + return null; + } + + /** + * 执行批量更新语句 + * + * @param sql SQL语句 + * @param params 数组参数列表 + * @return 执行结果数组 + */ + public int[] batchUpdate(String sql, List params) { + return jdbcTemplate.batchUpdate(sql, params); + } + + /** + * 启动事务,需要用try(DbTrans dbTrans=dbEngine.openTrans())来处理异常后自动回滚事务,如果手工提交事务DbTaans.commit() + * + * @return 事务对象 + */ + public JdbcTrans openTrans() { + return new JdbcTrans(this.dataSourceTransactionManager); + } + + /** + * 在回调函数中执行事务,返回的true就提交事务,否则回滚事务 + * + * @param extractor 回调方法 + * @return 事务是否成功,如果异常会也会事务回滚后再抛出异常 + */ + public boolean doTrans(Supplier extractor) { + try (JdbcTrans jdbcTrans = openTrans()) { + boolean result = extractor.get(); + if (result) { + jdbcTrans.commit(); + return true; + } + } + + return false; + } + + public void beginTrans() { + Thread t = Thread.currentThread(); + JdbcTrans jdbcTrans = mapThreadTrans.get(t); + if (jdbcTrans != null) { + jdbcTrans.inc(); + return; + } + mapThreadTrans.put(t, openTrans()); + } + + public void commit() throws SwException { + Thread t = Thread.currentThread(); + JdbcTrans tm = this.mapThreadTrans.get(t); + if (tm == null) throw new SwException("当前没有开启事务。"); + if (tm.canCommit()) { + tm.doEnd("commit"); + tm.commit(); + this.mapThreadTrans.remove(t); + } + } + + public void recTransLog() { + for (JdbcTrans tm: mapThreadTrans.values()) { + tm.doEnd("process"); + } + } + + public void rollback(Exception e) throws SwException { + Thread t = Thread.currentThread(); + JdbcTrans tm = mapThreadTrans.get(t); + if (tm == null) throw new SwException("当前没有开启事务。"); + if (tm.canCommit()) { + tm.doEnd("rollback"); + mapThreadTrans.remove(t); + tm.rollback(); + } + if (e != null) throw new SwException(e); + } + + public void doTrans(IDbWorker dbWorker) throws SwException { + beginTrans(); + try { + dbWorker.work(); + commit(); + } catch (Exception e) { + rollback(e); + dbWorker.doAfterDbRollback(); + throw new SwException(e); + } + dbWorker.doAfterDbCommit(); + } + + //独立事务 + public void doTransSingle(IDbWorker worker) throws Exception { + JdbcTrans jdbcTrans = openTrans(); + try { + worker.work(); + jdbcTrans.commit(); + } catch (Exception e) { + jdbcTrans.rollback(); + worker.doAfterDbRollback(); + throw e; + } + worker.doAfterDbCommit(); + } + + + /** + * 获取原始数据库连接执行命令 + * + * @return 数据库连接 + */ + public T doConn(Function extractor) { + DataSource ds = Objects.requireNonNull(this.jdbcTemplate.getDataSource()); + + try (Connection conn = ds.getConnection()) { + return extractor.apply(conn); + } catch (SQLException e) { + throw new DbException(e); + } + } + + /** + * 查询单行数据,返回bean + */ + public T queryEntity(String sql, Class type) { + List list = jdbcTemplate.query(sql, createRowMapper(type)); + + if (list != null && !list.isEmpty()) { + return list.get(0); + } + + return null; + } + + /** + * 查询单行数据,返回bean + */ + public T queryEntity(String sql, Class type, Object... params) { + List list = query(sql, createRowMapper(type), params); + + if (list != null && !list.isEmpty()) { + return list.get(0); + } + + return null; + } + + /** + * 通过回调函数查询SQL,返回列表或者对象数据 + */ + public T query(String sql, ResultSetExtractor rse) { + return jdbcTemplate.query(sql, rse); + } + + /** + * 查询SQL,返回列表数据 + */ + public List query(String sql, Class type) { + return jdbcTemplate.query(sql, createRowMapper(type)); + } + + /** + * 查询SQL,返回列表数据 + */ + public List query(String sql, Class type, Object... params) { + return jdbcTemplate.query(sql, createRowMapper(type), params); + } + + + /*================以下为具名参数方法================================================*/ + public int queryIntN(String sql, Map params) { + List list = namedJdbcTemplate.query(sql, params, (resultSet, i) -> resultSet.getInt(1)); + if (list != null && !list.isEmpty()) { + return list.get(0); + } + + return 0; + } + + public T queryEntityN(String sql, Map params, Class type) { + List list = queryN(sql, params, type); + + if (list != null && !list.isEmpty()) { + if (list.size() > 1) throw new SwException("您调用的查询单个对象的方法,结果却查出了多条!"); + return list.get(0); + } + + return null; + } + + public List queryN(String sql, Map params, Class type) { + return namedJdbcTemplate.query(sql, params, createRowMapper(type)); + } + + /** + * 执行更新SQL + */ + public int updateN(String sql, Map params) { + return namedJdbcTemplate.update(sql, params); + } + + public int[] batchUpdateN(String sql, List> params) { + return namedJdbcTemplate.batchUpdate(sql, (Map[])params.toArray()); + } + + /** + * 翻页查询 + */ + public List pagedQueryN(String sql, Class type, int start, int limit, Map params) { + return queryN(sql + " LIMIT " + start + "," + limit, params, type); + } + /*=================以上为具名参数方法==================================================*/ + public boolean isExists(String sql, Object... params) { + try { + Object v = jdbcTemplate.queryForObject(sql + " LIMIT 0, 1", Object.class, params); + return (v != null); + } catch (EmptyResultDataAccessException e) { + return false; + } + } + + private RowMapper createRowMapper(Class type) { + RowMapper rowMapper; + if (BaseBean.class.isAssignableFrom(type)) { + rowMapper = new BaseBeanPropertyRowMapper<>(type); + } else if (java.util.Map.class.isAssignableFrom(type)) { + if (SwMap.class.equals(type)) { + rowMapper = new SwMapPropertyRowMapper<>(type); + } else { + rowMapper = new MapPropertyRowMapper<>(type); + } + } else { + rowMapper = new BeanPropertyRowMapper<>(type); + } + return rowMapper; + } + + /** + * 翻页查询 + */ + public List pagedQuery(String sql, Class type, int start, int limit, Object... params) { + return jdbcTemplate.query(sql + " LIMIT " + start + "," + limit, createRowMapper(type), params); + } + + /** + * 翻页查询 + */ + public List pagedQuery(String sql, RowMapper rowMapper, int start, int limit, Object... params) { + return jdbcTemplate.query(sql + " LIMIT " + start + "," + limit, rowMapper, params); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/MapPropertyRowMapper.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/MapPropertyRowMapper.java new file mode 100644 index 0000000..c8ebc51 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/MapPropertyRowMapper.java @@ -0,0 +1,39 @@ +package cc.smtweb.framework.core.db.jdbc; + +import org.springframework.beans.BeanUtils; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * ORM映射处理器,实现spring jdbcTemplate的行集映射器 + * @author xkliu + */ +public class MapPropertyRowMapper implements RowMapper { + private Class mappedClass; + + public MapPropertyRowMapper(Class mappedClass) { + this.mappedClass = mappedClass; + } + + @Override + public T mapRow(ResultSet resultSet, int i) throws SQLException { + T mappedObject = BeanUtils.instantiateClass(this.mappedClass); + java.util.Map map = (java.util.Map)mappedObject; + + ResultSetMetaData rsmd = resultSet.getMetaData(); + int columnCount = rsmd.getColumnCount(); + + for(int index = 1; index <= columnCount; ++index) { + Object value = resultSet.getObject(index); + + if (value != null) { + map.put(rsmd.getColumnLabel(index), value); + } + } + + return mappedObject; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/SwMapPropertyRowMapper.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/SwMapPropertyRowMapper.java new file mode 100644 index 0000000..a5aad19 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/jdbc/SwMapPropertyRowMapper.java @@ -0,0 +1,59 @@ +package cc.smtweb.framework.core.db.jdbc; + +import cc.smtweb.framework.core.common.SwMap; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * ORM映射处理器,实现spring jdbcTemplate的行集映射器,对下划线进行小驼峰命名转化 + * @author xkliu + */ +public class SwMapPropertyRowMapper implements RowMapper { + public SwMapPropertyRowMapper(Class mappedClass) { + } + + @Override + public T mapRow(ResultSet resultSet, int i) throws SQLException { + SwMap map = new SwMap(); + + ResultSetMetaData rsmd = resultSet.getMetaData(); + int columnCount = rsmd.getColumnCount(); + + for(int index = 1; index <= columnCount; ++index) { + Object value = resultSet.getObject(index); + + if (value != null) { + String columnLabel = rsmd.getColumnLabel(index); + map.put(columnLabel, value); //toCamelCase(columnLabel) + } + } + + return (T)map; + } + + private String toCamelCase(String columnLabel) { + int len = columnLabel.length(); + StringBuilder sb = new StringBuilder(len); + int lowCase = 1; + for (int i = 0; i < len; i++) { + char ch = columnLabel.charAt(i); + if (ch == '_') { + lowCase = 2; + } else { + if (lowCase == 1) { + ch = Character.toLowerCase(ch); + lowCase = 0; + } else if (lowCase == 2) { + ch = Character.toUpperCase(ch); + lowCase = 0; + } + sb.append(ch); + } + } + + return sb.toString(); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractSelectSqlBuilder.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractSelectSqlBuilder.java new file mode 100644 index 0000000..9006790 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractSelectSqlBuilder.java @@ -0,0 +1,129 @@ +package cc.smtweb.framework.core.db.sqlbuilder; + +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.jdbc.JdbcEngine; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; + +public class AbstractSelectSqlBuilder extends SqlBuilder { + private List orderBy; + + protected void makeFields(StringBuilder sb) { + } + + protected Object[] makeParams(StringBuilder sb) { + makeFields(sb); + + if (wheres != null) { + List params = new ArrayList<>(wheres.size()); + + if (wheres.size() > 0) { + String logicOp = " AND "; + boolean addLoginOp = false; + + for (int i = 0; i < wheres.size(); i++) { + SqlWhereValue whereValue = wheres.get(i); + + if (i == 0) { + sb.append(" WHERE "); + } + + if (whereValue.getName() == null) { + Object value = whereValue.getValue(); + + if ("(".equals(value)) { + if (i > 0) { + sb.append(logicOp); + } + addLoginOp = false; + } + + sb.append(value); + logicOp = whereValue.getOp(); + } else { + if (addLoginOp) { + sb.append(logicOp); + } else { + addLoginOp = true; + } + + sb.append(whereValue.getName()).append(whereValue.getOp()).append('?'); + params.add(whereValue.getValue()); + } + } + } + + if (orderBy != null) { + for (int i = 0; i < orderBy.size(); i++) { + if (i == 0) { + sb.append(" ORDER BY "); + } else { + sb.append(","); + } + + sb.append(orderBy.get(i)); + } + } + + return params.toArray(new Object[params.size()]); + } + + return null; + } + + @Override + public AbstractSelectSqlBuilder addOrderBy(String orderByField) { + if (this.orderBy == null) { + this.orderBy = new ArrayList<>(); + } + + this.orderBy.add(orderByField); + + return this; + } + + public List query(DbEngine dbEngine, Class clazz) { + return exec((sql, params) -> dbEngine.query(sql, clazz, params)); + } + + public T queryEntity(DbEngine dbEngine, Class clazz) { + return exec((sql, params) -> dbEngine.queryEntity(sql, clazz, params)); + +// StringBuilder sb = new StringBuilder("select "); +// +// Object[] params = makeParams(sb); +// +// return dbEngine.queryEntity(sb.toString(), clazz, params); + } + + public T exec(BiFunction execute) { + StringBuilder sb = new StringBuilder("select "); + + Object[] params = makeParams(sb); + + return execute.apply(sb.toString(), params); + } + + public List pagedQuery(DbEngine dbEngine, Class clazz, int start, int limit) { + return exec((sql, params) -> dbEngine.pagedQuery(sql, clazz, start, limit, params)); +// StringBuilder sb = new StringBuilder("select "); +// +// Object[] params = makeParams(sb); +// +// return dbEngine.pagedQuery(sb.toString(), clazz, start, limit, params); + } + + public int queryInt(JdbcEngine dbEngine) { + return exec(dbEngine::queryInt); + } + + public SqlJoinTable addJoinTable(String dbName, String tableName, String tableAlias) { + return null; + } + + public SqlJoinTable findJoinTable(String dbName, String tableName) { + return null; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractUpdateSqlBuilder.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractUpdateSqlBuilder.java new file mode 100644 index 0000000..ebb4e53 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractUpdateSqlBuilder.java @@ -0,0 +1,20 @@ +package cc.smtweb.framework.core.db.sqlbuilder; + +import cc.smtweb.framework.core.db.jdbc.JdbcEngine; + +public abstract class AbstractUpdateSqlBuilder extends SqlBuilder { + // 无效的更新值,用以占位表示不组装值到params对象里面 + public static final Object VALUE_INVALID = new SqlFieldValue("", ""); + + public boolean isEmpty() { + return fields.isEmpty(); + } + + public abstract int update(JdbcEngine dbEngine); + + public void updateMap(java.util.Map map) { + for (SqlFieldValue field: fields) { + map.put(field.getName(), field.getValue()); + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/InsertSqlBuilder.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/InsertSqlBuilder.java new file mode 100644 index 0000000..dfc1e3c --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/InsertSqlBuilder.java @@ -0,0 +1,38 @@ +package cc.smtweb.framework.core.db.sqlbuilder; + +import cc.smtweb.framework.core.db.jdbc.JdbcEngine; + +public class InsertSqlBuilder extends AbstractUpdateSqlBuilder { + private String tableName; + + InsertSqlBuilder(String tableName) { + this.tableName = tableName; + } + + @Override + public int update(JdbcEngine dbEngine) { + int fieldSize = fields.size(); + Object[] params = new Object[fieldSize]; + + StringBuilder sb = new StringBuilder("insert into "); + sb.append(tableName).append('('); + + for (int i = 0; i < fieldSize; i++) { + SqlFieldValue field = fields.get(i); + sb.append(field.getName()).append(','); + params[i] = field.getValue(); + } + + sb.setCharAt(sb.length() - 1, ')'); + + sb.append(" values("); + + for (int i = 0; i < fieldSize; i++) { + sb.append("?,"); + } + + sb.setCharAt(sb.length() - 1, ')'); + + return dbEngine.update(sb.toString(), params); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SelectSqlBuilder.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SelectSqlBuilder.java new file mode 100644 index 0000000..2a83149 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SelectSqlBuilder.java @@ -0,0 +1,95 @@ +package cc.smtweb.framework.core.db.sqlbuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; + +public class SelectSqlBuilder extends AbstractSelectSqlBuilder { + private String tableName; + private List joinTables; + + SelectSqlBuilder(String tableName) { + this.tableName = tableName; + } + +// @Override +// public List query(DbEngine dbEngine, Class clazz) { +// StringBuilder sb = new StringBuilder("select "); +// +// Object[] params = makeParams(sb); +// +// if (params != null) { +// return dbEngine.query(sb.toString(), clazz, params); +// } else { +// return dbEngine.query(sb.toString(), clazz); +// } +// } + + @Override + protected void makeFields(StringBuilder sb) { + for (SqlFieldValue field: fields) { + sb.append(field.getName()).append(","); + } + + sb.setCharAt(sb.length() - 1, ' '); + sb.append("FROM ").append(tableName); + + if (joinTables != null) { + for (SqlJoinTable joinTable: joinTables) { + sb.append(joinTable.joinSql()).append(joinTable.getDbName()).append('.').append(joinTable.getTableName()) + .append(' ').append(joinTable.getTableAlias()).append(" ON("); + + boolean first = true; + for (SqlJoinField joinField: joinTable.getFields()) { + if (first) { + first = false; + } else { + sb.append(" AND "); + } + + sb.append(joinField.getKeyField()).append("=").append(joinField.getValueField()); + } + + sb.append(')'); + } + } + } + + @Override + public T exec(BiFunction execute) { + StringBuilder sb = new StringBuilder("select "); + + Object[] params = makeParams(sb); + + return execute.apply(sb.toString(), params); + } + + @Override + public SqlJoinTable addJoinTable(String dbName, String tableName, String tableAlias) { + if (joinTables == null) { + joinTables = new ArrayList<>(); + } + + SqlJoinTable joinTable = new SqlJoinTable(); + joinTable.setDbName(dbName); + joinTable.setTableName(tableName); + joinTable.setTableAlias(tableAlias); + + joinTables.add(joinTable); + + return joinTable; + } + + @Override + public SqlJoinTable findJoinTable(String dbName, String tableName) { + if (joinTables != null) { + for (SqlJoinTable table: joinTables) { + if (dbName.equals(table.getDbName()) && tableName.equals(table.getTableName())) { + return table; + } + } + } + + return null; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlFieldValue.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlFieldValue.java new file mode 100644 index 0000000..50ee584 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlFieldValue.java @@ -0,0 +1,14 @@ +package cc.smtweb.framework.core.db.sqlbuilder; + +import lombok.Getter; + +@Getter +class SqlFieldValue { + private final String name; + private final Object value; + + public SqlFieldValue(String name, Object value) { + this.name = name; + this.value = value; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinField.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinField.java new file mode 100644 index 0000000..e9ecfce --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinField.java @@ -0,0 +1,14 @@ +package cc.smtweb.framework.core.db.sqlbuilder; + +import lombok.Getter; + +@Getter +public class SqlJoinField { + private String keyField; + private String valueField; + + public SqlJoinField(String keyField, String valueField) { + this.keyField = keyField; + this.valueField = valueField; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinTable.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinTable.java new file mode 100644 index 0000000..a5bc154 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinTable.java @@ -0,0 +1,39 @@ +package cc.smtweb.framework.core.db.sqlbuilder; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * SelectSqlBuilder使用的查询关联表 + * @author xkliu + */ +@Data +public class SqlJoinTable { + public static final int LEFT_JOIN = 1; + public static final int RIGHT_JOIN = 2; + public static final int INNER_JOIN = 3; + public static final int FULL_JOIN = 4; + + private int joinType = LEFT_JOIN; + private String dbName; + private String tableName; + private String tableAlias; + + private List fields = new ArrayList<>(); + + public void add(String keyField, String valueField) { + fields.add(new SqlJoinField(keyField, valueField)); + } + + public String joinSql() { + switch (joinType) { + default: + case LEFT_JOIN: return " LEFT JOIN "; + case RIGHT_JOIN: return " RIGHT JOIN "; + case INNER_JOIN: return " INNER JOIN "; + case FULL_JOIN: return " FULL JOIN "; + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlWhereValue.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlWhereValue.java new file mode 100644 index 0000000..d3a9360 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlWhereValue.java @@ -0,0 +1,13 @@ +package cc.smtweb.framework.core.db.sqlbuilder; + +import lombok.Getter; + +class SqlWhereValue extends SqlFieldValue { + @Getter + private String op; + + public SqlWhereValue(String name, Object value, String op) { + super(name, value); + this.op = op; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelDatabase.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelDatabase.java new file mode 100644 index 0000000..112588d --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelDatabase.java @@ -0,0 +1,95 @@ +package cc.smtweb.framework.core.db.vo; + +import cc.smtweb.framework.core.annotation.SwTable; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import lombok.Data; + +@Data +@SwTable(value = "ASP_MODEL_DATABASE") +public class ModelDatabase extends DefaultEntity { + public final static String ENTITY_NAME = "ASP_MODEL_DATABASE"; + + public ModelDatabase() { + super(ENTITY_NAME); + } + + public long getId() { + return getLong("db_id"); + } + + public void setId(long dbId) { + put("db_id", dbId); + } + + public long getPrjId() { + return getLong("db_prj_id"); + } + + public void setPrjId(long dbPrjId) { + put("db_prj_id", dbPrjId); + } + + public String getName() { + return getStr("db_name"); + } + + public void setName(String dbName) { + put("db_name", dbName); + } + + public String getTitle() { + return getStr("db_title"); + } + + public void setTitle(String dbTitle) { + put("db_title", dbTitle); + } + + public int getStatus() { + return getInt("db_status"); + } + + public void setStatus(int dbStatus) { + put("db_status", dbStatus); + } + + public int getVersion() { + return getInt("db_version"); + } + + public void setVersion(int dbVersion) { + put("db_version", dbVersion); + } + + public long getCreateUid() { + return getLong("db_create_uid"); + } + + public void setCreateUid(long dbCreateUid) { + put("db_create_uid", dbCreateUid); + } + + public long getUpdateUid() { + return getLong("db_update_uid"); + } + + public void setUpdateUid(long dbUpdateUid) { + put("db_update_uid", dbUpdateUid); + } + + public long getCreateAt() { + return getLong("db_create_at"); + } + + public void setCreateAt(long dbCreateAt) { + put("db_create_at", dbCreateAt); + } + + public long getUpdateAt() { + return getLong("db_update_at"); + } + + public void setUpdateAt(long dbUpdateAt) { + put("db_update_at", dbUpdateAt); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelIndex.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelIndex.java new file mode 100644 index 0000000..534b04c --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelIndex.java @@ -0,0 +1,25 @@ +package cc.smtweb.framework.core.db.vo; + +import lombok.Data; +import org.apache.commons.codec.digest.DigestUtils; + +/** + * 索引定义 {name:"索引名称,如idx_t1", fields:"字段,如f1,f2", type="索引类别:P-主键 I-一般索引 U-唯一索引"} + */ +@Data +public class ModelIndex { + public static final String TYPE_PRIMARY = "P"; + public static final String TYPE_INDEX = "I"; + public static final String TYPE_UNIQUE = "U"; + + private String type; + private String fields; + + public boolean isUnique() { + return TYPE_UNIQUE.equals(type); + } + + public String getName() { + return DigestUtils.md5Hex(fields).substring(0, 16); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelLinkName.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelLinkName.java new file mode 100644 index 0000000..f55d0d9 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/vo/ModelLinkName.java @@ -0,0 +1,20 @@ +package cc.smtweb.framework.core.db.vo; + +import lombok.Data; + +/** + * Created by Akmm at 2022/3/15 10:19 + * 表关联信息,关联表名称字段信息 + */ +@Data +public class ModelLinkName { + private String fieldName; + private ModelTable linkTable; + private String linkNameField; + + public ModelLinkName(String fieldName, ModelTable linkTable, String linkNameField) { + this.fieldName = fieldName; + this.linkTable = linkTable; + this.linkNameField = linkNameField; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/BindParamException.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/BindParamException.java new file mode 100644 index 0000000..678c044 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/BindParamException.java @@ -0,0 +1,32 @@ +package cc.smtweb.framework.core.exception; + +import java.text.ParseException; + +public class BindParamException extends SwException { + /** + * + */ + private static final long serialVersionUID = 1L; + private String paramName; + + public String getParamName() { + return paramName; + } + + public BindParamException(String message, String paramName) { + this(message, null, paramName); + } + + public BindParamException(Exception e, String paramName) { + this(e.getMessage(), e, paramName); + } + + public BindParamException(String message, Exception e, String paramName) { + super("[" + paramName + "]" + message, e); + this.paramName = paramName; + } + + public BindParamException(ParseException e) { + super(e); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/BizException.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/BizException.java new file mode 100644 index 0000000..0fbb71a --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/BizException.java @@ -0,0 +1,29 @@ +package cc.smtweb.framework.core.exception; + +/** + * 业务异常 + * @author kevin + * + */ +public class BizException extends RuntimeException { + /** + * + */ + private static final long serialVersionUID = 1L; + + public BizException() { + super(); + } + + public BizException(String message, Throwable cause) { + super(message, cause); + } + + public BizException(String message) { + super(message); + } + + public BizException(Throwable cause) { + super(cause.getMessage(), cause); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/ExceptionMessage.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/ExceptionMessage.java new file mode 100644 index 0000000..39ea4ec --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/ExceptionMessage.java @@ -0,0 +1,102 @@ +package cc.smtweb.framework.core.exception; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * 错误码 JDK version used: + * + * @author kevin + * @version v1.0 + */ +@Setter +@Getter +@ToString +public class ExceptionMessage { + private int code; + + private String msg; + + private ExceptionMessage(int code, String msg) { + this.code = code; + this.msg = msg; + } + + // 401 + public static ExceptionMessage NO_AUTH_ERROR = new ExceptionMessage(401, "登录失效!"); + + // 403 + public static ExceptionMessage FORBIDDEN_ERROR = new ExceptionMessage(403, "没有访问权限!"); + + // 404 + public static ExceptionMessage NOT_FOUND_ERROR = new ExceptionMessage(404, "没有找到需要资源!"); + + // 通用异常 + public static ExceptionMessage INNER_ERROR = new ExceptionMessage(100100, "内部服务错误,请稍后再试!"); + + // 参数错误 + public static ExceptionMessage PARAM_ERROR = new ExceptionMessage(100101, "参数校验失败!"); + + // 数据库访问异常 + public static ExceptionMessage DB_ERROR = new ExceptionMessage(100102, "数据库访问失败!"); + + // 外部网络访问异常 + public static ExceptionMessage NETWORK_ERROR = new ExceptionMessage(100103, "外部网络访问失败!"); + + // 字符转换异常 + public static ExceptionMessage UNSUPPORTED_ENCODING_ERROR = new ExceptionMessage(100104, "字符编码失败!"); + + // 没有登录 + public static ExceptionMessage NO_LOGIN_ERROR = new ExceptionMessage(100105, "用户没有登录!"); + + // 没有登录 + public static ExceptionMessage CAPTCHA_ERROR = new ExceptionMessage(100106, "验证码错误!"); + + // 用户不存在 + public static ExceptionMessage USER_ERROR = new ExceptionMessage(100107, "手机号或密码错误,请重新输入!"); + + // 用户被禁 + public static ExceptionMessage USER_FORBIDED = new ExceptionMessage(100108, "用户被禁!"); + + // 密码错误 + public static ExceptionMessage PASSWORD_ERROR = new ExceptionMessage(100109, "密码错误,请重新输入!"); + + // 文件上传失败 + public static ExceptionMessage FILE_UPLOAD_ERROR = new ExceptionMessage(100110, "文件上传失败!"); + + // 文件不存在 + public static ExceptionMessage FILE_NOT_EXIST = new ExceptionMessage(100111, "文件不存在!"); + + // 树形层级只有6级 + public static ExceptionMessage TREE_HIERARCHY_ERROR = new ExceptionMessage(100112, "树形层级过多!"); + + // 手机号被使用了 + public static ExceptionMessage PHONE_ERROR = new ExceptionMessage(100113, "手机号被使用了!"); + + // 手机号不存在 + public static ExceptionMessage PHONE_EXISTS_ERROR = new ExceptionMessage(100114, "手机号不存在!"); + + // 消息发送要延迟 + public static ExceptionMessage SM_SEND_NEED_DELAY = new ExceptionMessage(100115, "验证码有效时间"); + + // 身份不能确认 + public static ExceptionMessage IDENTITY_ERROR = new ExceptionMessage(100116, "请选择登录身份!"); + + // 身份不能确认 + public static ExceptionMessage USER_PERMISSION_CHANGE = new ExceptionMessage(100117, "权限变更,请选择退出重新登录!"); + + // 数据发生变更 + public static ExceptionMessage DATA_CHANGE_ERROR = new ExceptionMessage(100118, "数据发生变更,请刷新后重试!"); + + // 数据发生变更 + public static ExceptionMessage SM_SEND_ERROR = new ExceptionMessage(100119, "验证码发生失败!"); + + // 敏感词 + public static ExceptionMessage XSS_ERROR = new ExceptionMessage(100120, "含有敏感词,请检查。"); + + // 树形层级数量太多 + public static ExceptionMessage TREE_NUMBER_ERROR = new ExceptionMessage(100121, "树形该层节点过多!"); + + public static ExceptionMessage APP_ID_NOT_EXISTS = new ExceptionMessage(100122, "不存在的应用ID"); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/SwException.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/SwException.java new file mode 100644 index 0000000..50306a5 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/exception/SwException.java @@ -0,0 +1,53 @@ +package cc.smtweb.framework.core.exception; + +import cc.smtweb.framework.core.exception.ExceptionMessage; + +/** + * 〈全局异常〉 + * + * @author kevin + * @since 1.0.0 + */ +public class SwException extends RuntimeException { + + private static final long serialVersionUID = 8096609992852791423L; + +// private ExceptionMessage cm; + + public SwException() { + } + + public SwException(String msg) { + super(msg); + } + + public SwException(int code, String msg) { + super(msg); + } + + public SwException(String msg, Throwable e) { + super(msg, e); + } + + public SwException(Throwable e) { + super(e.getMessage(), e); + } + + public SwException(ExceptionMessage cm) { + super(cm.getMsg()); + } + + public SwException(ExceptionMessage cm, Throwable e) { + super(cm.getMsg(), e); + } + + public SwException(ExceptionMessage cm, String msg) { + super(msg); + } + + +// public ExceptionMessage getCm() { +// return cm; +// } + +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/ISchedulerWakeup.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/ISchedulerWakeup.java new file mode 100644 index 0000000..0cfd153 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/ISchedulerWakeup.java @@ -0,0 +1,15 @@ +package cc.smtweb.framework.core.mvc; + +/** + * 定时任务唤醒服务接口 + * @author xkliu + */ +public interface ISchedulerWakeup { + /** + * 唤醒定时任务立即执行 + * @param clazz 包含定时任务方法的类名 + * @param methodName 有定时任务注解的方法名 + * @return 是否唤醒请求成功 + */ + boolean wakeup(Class clazz, String methodName); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/GlobalExceptionHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/GlobalExceptionHandler.java new file mode 100644 index 0000000..6737ab9 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/GlobalExceptionHandler.java @@ -0,0 +1,88 @@ +package cc.smtweb.framework.core.mvc.config; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.mvc.realm.exception.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.validation.ObjectError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 〈异常处理〉 + * + * @author kevin + * @since 1.0.0 + */ +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { +// private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class); +// +// /** +// * 〈校验的异常处理〉 +// */ +// @ExceptionHandler(value = {BindException.class}) +// @ResponseBody +// public Result handleBindException(BindException be) { +// return super.handleException(be); +// } +// + + @ExceptionHandler(AuthenticationException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public R handleAuthenticationException(AuthenticationException e) { + return R.error("认证失败", e); + } + + @ExceptionHandler(UnauthenticatedException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public R handleUnauthenticatedException(UnauthenticatedException e) { + return R.error("认证失败", e); + } + + @ExceptionHandler(UnknownAccountException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public R handleUnknownAccountException(UnknownAccountException e) { + return R.error("用户名或密码错误", e); + } + + @ExceptionHandler(AuthorizationException.class) + @ResponseStatus(HttpStatus.FORBIDDEN) + public R handleAuthorizationException(AuthorizationException e) { + log.error("No permissions:" + e.getMessage()); + return R.error("没有权限", e); + } + + @ExceptionHandler(ForbiddenException.class) + @ResponseStatus(HttpStatus.FORBIDDEN) + public R handleAuthorizationException(ForbiddenException e) { + log.error("No permissions:" + e.getMessage()); + return R.error("没有权限", e); + } + + @ExceptionHandler(value = {Exception.class}) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public R handleException(Exception ex) { + Throwable e = ex; + if (ex instanceof java.lang.reflect.InvocationTargetException) { + e = ex.getCause(); + } + + log.error(e.getMessage(), e); + return R.error(e.getMessage(), e); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public R handleException(MethodArgumentNotValidException ex) { + List errors = ex.getBindingResult().getAllErrors(); + List validationMsg = errors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList()); + // 不满足需求 一个一个提示 + return R.error(validationMsg.get(0)); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java new file mode 100644 index 0000000..11369d7 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java @@ -0,0 +1,132 @@ +package cc.smtweb.framework.core.mvc.config; + +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.db.jdbc.IdGenerator; +import cc.smtweb.framework.core.mvc.controller.ApiConfigBean; +import cc.smtweb.framework.core.mvc.controller.MethodAccessManager; +import cc.smtweb.framework.core.session.SessionManager; +import cc.smtweb.framework.core.session.UserSessionArgumentResolver; +import cc.smtweb.framework.core.util.JsonUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +/** + * @author kevin + */ +@Configuration +@Slf4j +public class WebMvcConfig implements WebMvcConfigurer { + private static final String PATTERN_FILES = "/files/**"; + private static final String PATTERN_STATIC = "/static/**"; + + @Value("${smtweb.file.local-path}") + private String fileLocalPath; + + @Value("${smtweb.static.local-path:}") + private String staticLocalPath; + +// @Value("${smtweb.api.json-full:}") +// private String apiJsonFull; + + @Autowired + private ApiConfigBean apiConfigBean; + + private static final String TRUE_VALUE = "true"; + + @Autowired + private RedisManager redisManager; + + @Bean + public SessionManager sessionManager(RedisManager redisManager, IdGenerator idGenerator) { + return new SessionManager(redisManager, idGenerator); + } + + @Bean + public CacheManager cacheManager() { + return new CacheManager(); + } + + @Bean + public MethodAccessManager methodAccessManager(CacheManager cacheManager) { + return new MethodAccessManager(redisManager, cacheManager); + } + + @Override + public void addCorsMappings(CorsRegistry registry) { + // 2.4 以前使用 .allowedOrigins("*") + registry.addMapping("/**") + .allowedOriginPatterns("*") + .allowedMethods("*") + .maxAge(3600) + .allowCredentials(true); + } + + @Bean + @Primary + public HttpMessageConverters customConverters() { + MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); + if (apiConfigBean.isJsonFull()) { + // 输出所有空属性 + messageConverter.setObjectMapper(JsonUtil.API_OBJECT_MAPPER); + } else { + messageConverter.setObjectMapper(JsonUtil.OBJECT_MAPPER); + } + + // 将转换器添加到converters中 + return new HttpMessageConverters(messageConverter); + } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(new UserSessionArgumentResolver()); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + // 静态资源文件 + if (!registry.hasMappingForPattern(PATTERN_STATIC)) { + if (StringUtils.isBlank(staticLocalPath)) { + registry.addResourceHandler(PATTERN_STATIC).addResourceLocations("classpath:/static/"); + } else if (staticLocalPath.endsWith("/")) { + // staticLocalPath 必须 / 结束 + registry.addResourceHandler(PATTERN_STATIC).addResourceLocations("classpath:/static/", + "file:" + staticLocalPath); + log.info("'/static/**' => file:" + staticLocalPath); + } else { + log.error("'smtweb.static.local-path' 必须用'/'结尾: " + staticLocalPath); + } + } else { + log.error("'/static/**' 已经被注册"); + } + + // 动态用户文件 + if (!registry.hasMappingForPattern(PATTERN_FILES)) { + registry.addResourceHandler(PATTERN_FILES).addResourceLocations("file:" + fileLocalPath); + log.info("'/files/**' => file:" + fileLocalPath); + } else { + log.error("'/files/**' 已经被注册"); + } + } + + // 所有返回接口Content-Type默认都返回application/json + @Override + public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { + configurer.defaultContentType(MediaType.APPLICATION_JSON); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiConfigBean.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiConfigBean.java new file mode 100644 index 0000000..2d69275 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiConfigBean.java @@ -0,0 +1,21 @@ +package cc.smtweb.framework.core.mvc.controller; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * API相关配置参数 + * @author xkliu + */ +@Component +@ConfigurationProperties(prefix = "smtweb.api") +@Data +public class ApiConfigBean { + // JSON是否输出非空字段 + private boolean jsonFull; + // 是否支持大驼峰url匹配规则 + private boolean lowerCaseUrl; + // 是否支持大驼峰url匹配规则,默认都支持 little camel-case + private boolean bigCameCaseUrl; +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/DefaultPageController.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/DefaultPageController.java new file mode 100644 index 0000000..1f2fa7d --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/DefaultPageController.java @@ -0,0 +1,29 @@ +package cc.smtweb.framework.core.mvc.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * 默认静态页面处理 + * @author xkliu + */ +@Controller +public class DefaultPageController { + /** + * 重定向默认静态页面 + * @return 静态页面重定向路径 + */ + @GetMapping("/") + public String index() { + return "forward:/static/index.html"; + } + + /** + * 重定向默认网站图标 + * @return 网站图标重定向路径 + */ + @GetMapping(value = "/favicon.ico") + public String favicon() { + return "forward:/static/favicon.ico"; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/ControllerAccess.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/ControllerAccess.java new file mode 100644 index 0000000..dc61fff --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/ControllerAccess.java @@ -0,0 +1,69 @@ +package cc.smtweb.framework.core.mvc.controller.access; + +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.Map; + +/** 控制器访问类 */ +@Slf4j +public class ControllerAccess implements IBeanAccess { + private final Class clazz; + private final List fieldList; + @Getter + private final boolean singleton; + @Getter + private Object singletonInstance; + + public ControllerAccess(Class clazz, List fieldList, boolean singleton) { + this.clazz = clazz; + this.fieldList = fieldList; + this.singleton = singleton; + } + + public String getFullName() { + return clazz.getName(); + } + + public Object getOrNewInstance(IBeanContext context, Map params) throws IllegalAccessException, InstantiationException { + if (singletonInstance != null) { + return singletonInstance; + } else { + Object result = clazz.newInstance(); + + writeBeanFields(result, context, params); + + return result; + } + } + + private void writeBeanFields(Object bean, IBeanContext context, Map params) { + for (FieldAccess fieldAccess: fieldList) { + boolean ret = fieldAccess.writeValue(bean, context, params); + if (!ret) { + log.error("write bean " + fieldAccess.getFullName(bean) + + " failure."); + } + } + } + + public Object initSingletonFields(IBeanContext context, Map params) { + if (singletonInstance != null) { + writeBeanFields(singletonInstance, context, params); + } + + return singletonInstance; + } + + public Class getBeanType() { + return clazz; + } + + public void newSingletonInstance() throws IllegalAccessException, InstantiationException { + if (isSingleton()) { + this.singletonInstance = clazz.newInstance(); + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IMethodAccess.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IMethodAccess.java new file mode 100644 index 0000000..b070db5 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IMethodAccess.java @@ -0,0 +1,50 @@ +package cc.smtweb.framework.core.mvc.controller.access; + +import cc.smtweb.framework.core.mvc.controller.IBeanContext; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * API方法访问接口 + * @author xkliu + */ +public interface IMethodAccess { + // 方法返回值Java类型 + Class getReturnType(); + + // @SwBody 注解Java类型 + Class getBodyType(); + + // @SwAttr 注解Java类型 + Class getAttrType(String paramName); + + /** + * 执行反射的API函数,一般时定时器等无参数环境调用 + * @param context 对象上下文 + * @return API函数返回值 + */ + Object invoke(IBeanContext context); + + /** + * 执行类方法,实现API调用 + * @param context 上下文对象,包括springboot服务类,@SwBean类 + * @param params url请求参数map + * @param body post请求的内容 + * @param request HTTP请求对象 + * @return 应答对象,一般是返回R转换为json返回 + */ + Object invoke(IBeanContext context, Map params, String body, HttpServletRequest request); + + /** + * 输出错误信息用,方法全名 + * @return 方法全名 + */ + String fullName(); + + /** + * API权限 + * @return 权限串 + */ + String getPerm(); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodAccess.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodAccess.java new file mode 100644 index 0000000..3ec44b1 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodAccess.java @@ -0,0 +1,117 @@ +package cc.smtweb.framework.core.mvc.controller.access; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.exception.BindBeanException; +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import cc.smtweb.framework.core.mvc.controller.binder.ParamEditor; +import lombok.Getter; +import org.apache.commons.lang3.ObjectUtils; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + +/** + * API方法执行 + * + * @author xkliu + */ +public class MethodAccess implements IMethodAccess { + private final ControllerAccess controllerAccess; + private final Method method; + @Getter + private final String perm; + private final MethodParamAccess[] paramBinds; + + public MethodAccess(ControllerAccess controllerAccess, Method method, String perm, MethodParamAccess[] paramBinds) { + this.controllerAccess = controllerAccess; + this.method = method; + this.perm = perm; + this.paramBinds = paramBinds; + } + + @Override + public Class getReturnType() { + return this.method.getReturnType(); + } + + @Override + public Class getBodyType() { + for (MethodParamAccess methodParamAccess : paramBinds) { + if (methodParamAccess.getBindType() == ParamEditor.TYPE_BODY) { + return methodParamAccess.getParamType(); + } + } + + return null; + } + + @Override + public Class getAttrType(String paramName) { + for (MethodParamAccess methodParamAccess : paramBinds) { + if (methodParamAccess.getBindType() == ParamEditor.TYPE_ATTR && paramName.equals(methodParamAccess.getParamName())) { + return methodParamAccess.getParamType(); + } + } + + return null; + } + + @Override + public Object invoke(IBeanContext context) { + return invoke(context, null, null, null); + } + + @Override + public Object invoke(IBeanContext context, Map params, String body, HttpServletRequest request) { + // 通过请求数据转换函数参数值 + Object[] args = null; + + if (!ObjectUtils.isEmpty(paramBinds)) { + args = new Object[paramBinds.length]; + for (int i = 0; i < paramBinds.length; i++) { + MethodParamAccess param = paramBinds[i]; + try { + args[i] = param.getParamValue(context, params, body, request); + } catch (Exception e) { + throw new BindBeanException(String.format("%s error value: %s", param.getParamName(), param.toString()), e); + } + } + } + + // 获取服务实例,然后执行方法 + try { + Object instance = controllerAccess.getOrNewInstance(context, params); + return method.invoke(instance, args); + } catch (IllegalAccessException | InstantiationException e) { + throw new SwException(e); + } catch (InvocationTargetException e) { + throw new SwException(e.getCause()); + } catch (BizException e) { + return R.error(e.getMessage()); + } + } + + @Override + public String fullName() { + return controllerAccess.getFullName() + "." + method.getName(); + } + + public Class findParam(Class clazz) { + for (MethodParamAccess param : paramBinds) { + Class paramType = param.getParamType(); + if (clazz.equals(paramType)) { + return paramType; + } + } + + return null; + } + + public String controllerFullName() { + return this.controllerAccess.getFullName(); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/BeanContext.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/BeanContext.java new file mode 100644 index 0000000..7510494 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/BeanContext.java @@ -0,0 +1,47 @@ +package cc.smtweb.framework.core.mvc.controller.binder; + +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; + +import java.util.Map; + +public class BeanContext implements IBeanContext { + private final Map, Object> beanMap; + private final BeanFactory applicationContext; + + public BeanContext(Map, Object> beanMap, BeanFactory applicationContext) { + this.beanMap = beanMap; + this.applicationContext = applicationContext; + } + + @Override + public T getBean(String name, Class type) throws BeansException { + Object controllerAccess = beanMap.get(type); + + if (controllerAccess == null) { + return applicationContext.getBean(name, type); + } else { + return (T)controllerAccess; + } + } + + @Override + public T getBean(Class type) throws BeansException { + Object controllerAccess = beanMap.get(type); + + if (controllerAccess != null) { + return (T) controllerAccess; + } + + controllerAccess = applicationContext.getBean(type); + if (controllerAccess != null) { + return (T) controllerAccess; + } + + return null; + } + + public void init() { + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/ParamEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/ParamEditor.java new file mode 100644 index 0000000..fcd56e3 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/ParamEditor.java @@ -0,0 +1,40 @@ +package cc.smtweb.framework.core.mvc.controller.binder; + +import cc.smtweb.framework.core.mvc.controller.IEditor; +import lombok.Setter; + +import java.util.HashMap; +import java.util.Map; + +public class ParamEditor { + public static final int TYPE_UNKNOWN = 0; + public static final int TYPE_FIELD = 1; + public static final int TYPE_PARAM = 2; + public static final int TYPE_BODY = 3; + public static final int TYPE_PATH = 4; + public static final int TYPE_HEADER = 5; + public static final int TYPE_COOKIE = 6; + public static final int TYPE_ATTR = 7; + + private final Map, IEditor> editors = new HashMap<>(); + + @Setter + private IEditor defaultEditor; + + ParamEditor(IEditor defaultEditor) { + this.defaultEditor = defaultEditor; + } + + public void add(Class clazz, IEditor editor) { + editors.put(clazz, editor); + } + + public IEditor find(Class paramType) { + IEditor result = editors.get(paramType); + if (result == null) { + result = defaultEditor; + } + + return result; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/AbstractContextEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/AbstractContextEditor.java new file mode 100644 index 0000000..1187721 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/AbstractContextEditor.java @@ -0,0 +1,16 @@ +package cc.smtweb.framework.core.mvc.controller.binder.bean; + +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import cc.smtweb.framework.core.mvc.controller.IEditor; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public abstract class AbstractContextEditor implements IEditor { + @Override + public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { + return getValue(paramName, paramType, context); + } + + protected abstract Object getValue(String paramName, Class paramType, IBeanContext context); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/BeanEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/BeanEditor.java new file mode 100644 index 0000000..399673a --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/BeanEditor.java @@ -0,0 +1,15 @@ +package cc.smtweb.framework.core.mvc.controller.binder.bean; + +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import org.apache.commons.lang3.StringUtils; + +public class BeanEditor extends AbstractContextEditor { + @Override + public Object getValue(String paramName, Class paramType, IBeanContext context) { + if (StringUtils.isBlank(paramName)) { + return context.getBean(paramType); + } else { + return context.getBean(paramName, paramType); + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/HttpServletRequestEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/HttpServletRequestEditor.java new file mode 100644 index 0000000..3cdbfa2 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/HttpServletRequestEditor.java @@ -0,0 +1,12 @@ +package cc.smtweb.framework.core.mvc.controller.binder.bean; + +import cc.smtweb.framework.core.mvc.controller.binder.param.AbstractRequestEditor; + +import javax.servlet.http.HttpServletRequest; + +public class HttpServletRequestEditor extends AbstractRequestEditor { + @Override + public Object getValue(HttpServletRequest request) { + return request; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/NullEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/NullEditor.java new file mode 100644 index 0000000..c791f97 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/NullEditor.java @@ -0,0 +1,14 @@ +package cc.smtweb.framework.core.mvc.controller.binder.bean; + +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import cc.smtweb.framework.core.mvc.controller.IEditor; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public class NullEditor implements IEditor { + @Override + public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { + return null; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/SwIpAddrEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/SwIpAddrEditor.java new file mode 100644 index 0000000..8329f39 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/SwIpAddrEditor.java @@ -0,0 +1,34 @@ +package cc.smtweb.framework.core.mvc.controller.binder.bean; + +import cc.smtweb.framework.core.mvc.controller.binder.param.AbstractRequestEditor; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +/*** + * 获取客户端IP地址;这里通过了Nginx获取;X-Real-IP + */ +public class SwIpAddrEditor extends AbstractRequestEditor { + @Override + public Object getValue(HttpServletRequest request) { + String ip = request.getHeader("X-Real-IP"); + + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Forwarded-For"); + } + + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + + return ip; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java new file mode 100644 index 0000000..ca550c6 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java @@ -0,0 +1,69 @@ +package cc.smtweb.framework.core.mvc.controller.binder.body; + +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.exception.BindBeanException; +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import cc.smtweb.framework.core.mvc.controller.IEditor; +import cc.smtweb.framework.core.util.JsonUtil; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * API函数@SwBody参数的转换处理,POST请求直接转换Json内容为Bean对象,GET请求转换Map请求参数为Bean对 + * @author xkliu + */ +public class SwMapBodyEditor implements IEditor { + @Override + public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { + Object map = request.getAttribute(BODY_MAP); + if (map != null) { + return getFieldValue((SwMap)map, paramName); + } + + if (body != null) { + return getPostValue(paramName, paramType, body, request); + } else { + return getGetValue(paramName, paramType, params, request); + } + } + + private Object getGetValue(String paramName, Class paramType, Map params, HttpServletRequest request) { + SwMap result = JsonUtil.parse(params, SwMap.class); + request.setAttribute(BODY_MAP, result); + return getFieldValue(result, paramName); + } + + private Object getPostValue(String paramName, Class paramType, String body, HttpServletRequest request) { + if (body == null || StringUtils.isBlank(body)) { + return null; + } + + SwMap result = JsonUtil.parse(body, SwMap.class); + request.setAttribute(BODY_MAP, result); + return getFieldValue(result, paramName); + } + + private Object getFieldValue(SwMap result, String paramName) { + if (paramName != null) { + Object value = result.get(paramName); + if (value == null) { + return null; + } + + if (value instanceof Map) { + SwMap map = new SwMap(); + ((Map) value).forEach((k, v) -> { + map.put(k.toString(), v); + }); + return map; + } + + throw new BindBeanException("传入的 @SwBody(" + paramName + ") 值非MAP类型! " + value.getClass().getName()); + } + + return result; + } + +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractNumberEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractNumberEditor.java new file mode 100644 index 0000000..24d2feb --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractNumberEditor.java @@ -0,0 +1,46 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + +import org.apache.commons.lang3.StringUtils; + + +/** + * 字符串到Number类型的转换 + * + * @author kevin + * + */ +public abstract class AbstractNumberEditor extends AbstractParameterEditor { + protected boolean automicType; + + public AbstractNumberEditor(int paramEditType, boolean automicType) { + super(paramEditType); + this.automicType = automicType; + } + + @Override + protected Object parseText(Object value) { + Object result = null; + + if (value == null) { + return automicType ? defaultValue() : null; + } + + if (value instanceof Number) { + return convert((Number)value); + } + + String text = value.toString(); + + if (StringUtils.isNotBlank(text)) { + result = getValue(text); + } else { + result = automicType ? defaultValue() : null; + } + + return result; + } + + protected abstract Object convert(Number value); + protected abstract Object getValue(String text); + protected abstract Object defaultValue(); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractParameterEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractParameterEditor.java new file mode 100644 index 0000000..db51dba --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractParameterEditor.java @@ -0,0 +1,109 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import cc.smtweb.framework.core.mvc.controller.IEditor; +import cc.smtweb.framework.core.mvc.controller.binder.ParamEditor; +import cc.smtweb.framework.core.util.JsonUtil; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +/** + * 字符串参数到对象的转换; + * @author xkliu + */ +public abstract class AbstractParameterEditor implements IEditor { + private static final IEditorValue paramValue = (paramName, params, body, request) -> params.get(paramName); + private static final IEditorValue headerValue = (paramName, params, body, request) -> request.getHeader(paramName); + private static final IEditorValue bodyValue = (paramName, params, body, request) -> { + if (body == null) { + if (paramName != null) { + return params.get(paramName); + } + } else { + SwMap map = (SwMap) request.getAttribute(BODY_MAP); + if (map != null) { + return map.get(paramName); + } + + map = JsonUtil.parse(body, SwMap.class); + if (map != null) { + request.setAttribute(BODY_MAP, map); + return map.get(paramName); + } + } + + return null; + }; + + private final IEditorValue editorValue; + +// AbstractParameterEditor() { +// editorValue = paramValue; +// } + + AbstractParameterEditor(int paramEditorType) { + switch (paramEditorType) { + case ParamEditor.TYPE_HEADER: + editorValue = headerValue; + break; + case ParamEditor.TYPE_PARAM: + editorValue = paramValue; + break; + case ParamEditor.TYPE_BODY: + editorValue = bodyValue; + break; + default: + throw new UnsupportedOperationException("not implement type: " + paramEditorType); + } + } + + protected static Date parseDateTime(String text) throws ParseException { + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + df.setLenient(false); + + return df.parse(text); + } + + protected static Date parseShortDateTime(String text) throws ParseException { + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + df.setLenient(false); + + return df.parse(text); + } + + protected static Date parseDate(String text) throws ParseException { + DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + df.setLenient(false); + + return df.parse(text); + } + + @Override + public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { + if (StringUtils.isBlank(paramName)) { + return null; + } + + return parseText(editorValue.getValue(paramName, params, body, request)); + } + + protected abstract Object parseText(Object text); +} + +interface IEditorValue { + /** + * 获取参数值 + * @param paramName 参数名 + * @param params HTTP请求参数集合 + * @param request HTTP请求对象 + * @return 参数值 + */ + Object getValue(String paramName, Map params, String body, HttpServletRequest request); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractRequestEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractRequestEditor.java new file mode 100644 index 0000000..eb17731 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractRequestEditor.java @@ -0,0 +1,16 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import cc.smtweb.framework.core.mvc.controller.IEditor; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public abstract class AbstractRequestEditor implements IEditor { + @Override + public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { + return getValue(request); + } + + protected abstract Object getValue(HttpServletRequest request); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BooleanEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BooleanEditor.java new file mode 100644 index 0000000..30572c0 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BooleanEditor.java @@ -0,0 +1,30 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + +import org.apache.commons.lang3.StringUtils; + +public class BooleanEditor extends AbstractParameterEditor { + private final boolean automicType; + + public BooleanEditor(int header, boolean automicType) { + super(header); + this.automicType = automicType; + } + + @Override + public Object parseText(Object text) { + if (text == null) { + return automicType ? Boolean.FALSE : null; + } + + if (text instanceof Boolean) { + return text; + } + + String s = text.toString(); + if (StringUtils.isBlank(s)) { + return automicType ? Boolean.FALSE : null; + } + + return Boolean.valueOf(s); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ByteEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ByteEditor.java new file mode 100644 index 0000000..fd3a27e --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ByteEditor.java @@ -0,0 +1,24 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + +public class ByteEditor extends AbstractNumberEditor { + private static final Byte BYTE_ZERO = 0; + + public ByteEditor(int header, boolean automicType) { + super(header, automicType); + } + + @Override + protected Object convert(Number value) { + return value.byteValue(); + } + + @Override + protected Object getValue(String text) { + return Byte.valueOf(text); + } + + @Override + protected Object defaultValue() { + return BYTE_ZERO; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/CharEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/CharEditor.java new file mode 100644 index 0000000..a723b20 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/CharEditor.java @@ -0,0 +1,29 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + +import org.apache.commons.lang3.StringUtils; + + +public class CharEditor extends AbstractParameterEditor { + private static final char CHAR_ZERO = '\u0000'; + private final boolean automicType; + + public CharEditor(int header, boolean automicType) { + super(header); + this.automicType = automicType; + } + + @Override + protected Object parseText(Object value) { + if (value == null) { + return automicType ? CHAR_ZERO : null; + } + + String text = value.toString(); + + if(StringUtils.isBlank(text)){ + return automicType ? CHAR_ZERO : null; + } + + return text.charAt(0); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DoubleEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DoubleEditor.java new file mode 100644 index 0000000..8b8d7d9 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DoubleEditor.java @@ -0,0 +1,25 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + + +public class DoubleEditor extends AbstractNumberEditor { + private static final Double DOUBLE_ZERO = 0.0d; + + public DoubleEditor(int header, boolean automicType) { + super(header, automicType); + } + + @Override + protected Object convert(Number value) { + return value.doubleValue(); + } + + @Override + protected Object getValue(String text) { + return Double.valueOf(text); + } + + @Override + protected Object defaultValue() { + return DOUBLE_ZERO; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/LongEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/LongEditor.java new file mode 100644 index 0000000..359cc0b --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/LongEditor.java @@ -0,0 +1,25 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + + +public class LongEditor extends AbstractNumberEditor { + private static final Long LONG_ZERO = 0L; + + public LongEditor(int header, boolean automicType) { + super(header, automicType); + } + + @Override + protected Object convert(Number value) { + return value.longValue(); + } + + @Override + protected Object getValue(String text) { + return Long.valueOf(text); + } + + @Override + protected Object defaultValue() { + return LONG_ZERO; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimeEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimeEditor.java new file mode 100644 index 0000000..5377898 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimeEditor.java @@ -0,0 +1,35 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + +import cc.smtweb.framework.core.exception.BindParamException; +import org.apache.commons.lang3.StringUtils; + +import java.text.ParseException; +import java.util.Date; + +public class TimeEditor extends AbstractParameterEditor { + public TimeEditor(int header) { + super(header); + } + + @Override + public Object parseText(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Date) { + return new java.sql.Time(((Date) value).getTime()); + } + + String text = value.toString(); + if (StringUtils.isBlank(text)) { + return null; + } + + try { + return new java.sql.Time(parseDateTime(text).getTime()); + } catch (ParseException e) { + throw new BindParamException(e); + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimestampEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimestampEditor.java new file mode 100644 index 0000000..44141bf --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimestampEditor.java @@ -0,0 +1,57 @@ +package cc.smtweb.framework.core.mvc.controller.binder.param; + +import cc.smtweb.framework.core.exception.BindParamException; +import org.apache.commons.lang3.StringUtils; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.util.Date; + +public class TimestampEditor extends AbstractParameterEditor { + public TimestampEditor(int header) { + super(header); + } + + @Override + public Object parseText(Object value) throws IllegalArgumentException { + if (value == null) { + return null; + } + + if (value instanceof Date) { + return new Timestamp(((Date) value).getTime()); + } + + String text = value.toString(); + if (StringUtils.isBlank(text)) { + return null; + } + + text = text.trim(); + + if ("null".equals(text)) { + return null; + } + + Timestamp result = null; + + try { + int pos = text.indexOf(':'); + if (pos < 0 && text.indexOf("-") < 0) { + result = new Timestamp(Long.parseLong(text)); + } else if (text.length() > 10) { + if (text.indexOf(':', pos + 1) > pos) { + result = new Timestamp(parseDateTime(text).getTime()); + } else { + result = new Timestamp(parseDateTime(text).getTime()); + } + } else { + result = new Timestamp(parseDateTime(text).getTime()); + } + } catch (ParseException ex) { + throw new BindParamException(ex); + } + + return result; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/path/PathParamEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/path/PathParamEditor.java new file mode 100644 index 0000000..cb42ef7 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/path/PathParamEditor.java @@ -0,0 +1,14 @@ +package cc.smtweb.framework.core.mvc.controller.binder.path; + +import cc.smtweb.framework.core.mvc.controller.binder.param.AbstractRequestEditor; + +import javax.servlet.http.HttpServletRequest; + +public class PathParamEditor extends AbstractRequestEditor { + public final static String ATTR_KEY = "SMTWEB_PATH"; + + @Override + public Object getValue(HttpServletRequest request) { + return request.getAttribute(ATTR_KEY); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/BeanManager.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/BeanManager.java new file mode 100644 index 0000000..20adc64 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/BeanManager.java @@ -0,0 +1,161 @@ +package cc.smtweb.framework.core.mvc.controller.scan; + +import cc.smtweb.framework.core.mvc.controller.IActionManager; +import cc.smtweb.framework.core.mvc.controller.access.ControllerAccess; +import cc.smtweb.framework.core.mvc.controller.access.IMethodAccess; +import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; +import cc.smtweb.framework.core.mvc.controller.access.SchedulerMethodAccess; +import cc.smtweb.framework.core.mvc.controller.binder.BeanContext; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +public class BeanManager implements IActionManager { + private ApplicationContext applicationContext; + private List beans = new ArrayList<>(); + private Map, Object> beanMap = new HashMap<>(); + private List singletonServices = new ArrayList<>(); + @Getter + private Map controllers = new HashMap<>(); + @Getter + private BeanContext beanContext; + @Getter + private List tasks = new ArrayList<>(); + + private List constructMethods = new ArrayList<>(); + private List destroyMethods = new ArrayList<>(); + private List beanMethods = new ArrayList<>(); + + private Map> mapTableClass = new HashMap<>(); + + private static BeanManager instance = null; + static { + instance = new BeanManager(); + } + + public static BeanManager getInstance() { + return instance; + } + + private BeanManager() { + } + + public void install(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + beanContext = new BeanContext(beanMap, applicationContext); + } + + public void init() throws Exception { + // 读取DbEngine,用以初始化 EntityDao + beanContext.init(); + + // 自动设置@SwBean注解对象的@SwParam注解属性 + for (ControllerAccess controllerAccess: beans) { + Object bean = controllerAccess.getSingletonInstance(); + addBeanMap(controllerAccess.getBeanType(), bean); + } + + // 映射单例Bean字段值 + for (ControllerAccess controllerAccess: beans) { + controllerAccess.initSingletonFields(beanContext, null); + } + + for (IMethodAccess methodAccess: beanMethods) { + Object bean = methodAccess.invoke(beanContext); + addBeanMap(methodAccess.getReturnType(), bean); + log.debug("[smt]init bean:" + methodAccess.getReturnType() + " by " + methodAccess.fullName()); + } + + // 映射单例控制器字段值 + for (ControllerAccess controllerAccess: singletonServices) { + controllerAccess.initSingletonFields(beanContext, null); + } + + // 执行初始化方法 + constructMethods.sort((a, b) -> a.order - b.order); + + for (OrderMethodAccess orderMethodAccess: constructMethods) { + IMethodAccess methodAccess = orderMethodAccess.methodAccess; + methodAccess.invoke(beanContext); + } + } + + private void addBeanMap(Class beanType, Object bean) { + if (bean != null) { + beanMap.put(beanType, bean); + } + } + + IMethodAccess putIfAbsent(String url, IMethodAccess methodAccess) { + return controllers.putIfAbsent(url, methodAccess); + } + + void addBean(ControllerAccess controllerAccess) { + this.beans.add(controllerAccess); + } + + void addSingletonController(ControllerAccess controllerAccess) { + this.singletonServices.add(controllerAccess); + } + + void addTask(SchedulerMethodAccess schedulerMethodAccess) { + this.tasks.add(schedulerMethodAccess); + } + + void addConstruct(int order, MethodAccess methodAccess) { + constructMethods.add(new OrderMethodAccess(order, methodAccess)); + } + + void addDestroy(int order, MethodAccess methodAccess) { + destroyMethods.add(new OrderMethodAccess(order, methodAccess)); + } + + public MethodAccess[] loadDestroyMethods() { + if (destroyMethods.isEmpty()) { + return null; + } + + destroyMethods.sort((a, b) -> b.order - a.order); + + int size = destroyMethods.size(); + MethodAccess[] result = new MethodAccess[size]; + for (int i = 0; i < size; i++) { + result[i] = destroyMethods.get(i).methodAccess; + } + + return result; + } + + void addBeanMethod(IMethodAccess methodAccess) { + this.beanMethods.add(methodAccess); + } + + @Override + public boolean api(String url, IMethodAccess methodAccess) { + return this.putIfAbsent(url, methodAccess) == null; + } + + public void addTableClass(String tableName, Class clzz) { + mapTableClass.put(tableName, clzz); + } + + public Class getTableClass(String tableName) { + return mapTableClass.get(tableName); + } + + private static class OrderMethodAccess { + private final int order; + private final MethodAccess methodAccess; + + OrderMethodAccess(int order, MethodAccess methodAccess) { + this.order = order; + this.methodAccess = methodAccess; + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ClassParser.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ClassParser.java new file mode 100644 index 0000000..84db2a4 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ClassParser.java @@ -0,0 +1,173 @@ +package cc.smtweb.framework.core.mvc.controller.scan; + +import cc.smtweb.framework.core.annotation.*; +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.mvc.controller.IEditor; +import cc.smtweb.framework.core.mvc.controller.access.BindFieldAccess; +import cc.smtweb.framework.core.mvc.controller.access.ControllerAccess; +import cc.smtweb.framework.core.mvc.controller.access.FieldAccess; +import cc.smtweb.framework.core.mvc.controller.access.SingletonFieldAccess; +import cc.smtweb.framework.core.mvc.controller.binder.ParamEditor; +import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.collection.SynchronizedCollection; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +@Slf4j +public class ClassParser { + private BeanManager beanManager; + private UrlMaker urlMaker; + private WebDataBinder webDataBinder; + private ScanContext scanContext; + private Field singletonField; + private boolean singleton; + // private List cacheList; + private MethodParser methodParser; + private List> threadSafeTypes = new ArrayList<>(); + private DbEngine dbEngine; + + public ClassParser(UrlMaker urlMaker, ScanContext scanContext) { + this.urlMaker = urlMaker; + this.scanContext = scanContext; + this.beanManager = scanContext.getBeanManager(); +// this.cacheList = cacheList; + this.webDataBinder = scanContext.getWebDataBinder(); + this.methodParser = new MethodParser(urlMaker, scanContext); + this.dbEngine = beanManager.getBeanContext().getBean(DbEngine.class); + + threadSafeTypes.add(AtomicBoolean.class); + threadSafeTypes.add(AtomicInteger.class); + threadSafeTypes.add(AtomicLong.class); + threadSafeTypes.add(SynchronizedCollection.class); + threadSafeTypes.add(ConcurrentMap.class); + } + + public void parse(String dirName, Class clazz) throws InstantiationException, IllegalAccessException, ParseException { + SwBean swBean = clazz.getAnnotation(SwBean.class); + + // TODO ISwCache.class.isAssignableFrom(clazz) + if (swBean != null) { + ControllerAccess controllerAccess = buildControllerAccess(clazz, swBean.alwaysCreate()); + if (controllerAccess.isSingleton()) { + controllerAccess.newSingletonInstance(); + log.debug("[smt]init bean: " + clazz.getName()); + beanManager.addBean(controllerAccess); + + methodParser.parse(clazz, controllerAccess, false); + } else { + log.error(clazz.getName() + " must be singleton, can not use field: " + singletonField.getName()); + } + return; + } + + SwService swService = clazz.getAnnotation(SwService.class); + if (swService != null) { + urlMaker.setServiceUrl(swService.value()); + log.debug("[smt]init service: " + clazz.getName()); + //Service类,非单例,以免多线程并发相互干扰 + ControllerAccess controllerAccess = buildControllerAccess(clazz, false); + if (controllerAccess.isSingleton()) { + controllerAccess.newSingletonInstance(); + beanManager.addSingletonController(controllerAccess); + } + + // 处理url路径 + methodParser.parse(clazz, controllerAccess, true); + return; + } + + SwCache swCache = clazz.getAnnotation(SwCache.class); + if (swCache != null) { + CacheManager cacheManager = CacheManager.getIntance(); + cacheManager.install((AbstractCache) clazz.newInstance()); + return; + } + + SwTable swTable = clazz.getAnnotation(SwTable.class); + if (swTable != null) { + beanManager.addTableClass(swTable.value(), clazz); + } + } + + private ControllerAccess buildControllerAccess(Class clazz, boolean alwaysCreate) { + List fieldList = new ArrayList<>(); + singleton = true; + singletonField = null; + // 扫描本类和父类的 field + Class parentClazz = clazz; + + // !parentClazz.equals(stopClazz) + while (parentClazz != null && !parentClazz.isInterface()) { + parseFields(parentClazz, fieldList); + parentClazz = parentClazz.getSuperclass(); + } + + return new ControllerAccess(clazz, fieldList, alwaysCreate || singleton); + } + + private void parseFields(Class clazz, List fieldList) { + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + FieldAccess fieldAccess = parseField(field); + + if (fieldAccess != null) { + fieldList.add(fieldAccess); + } + } + } + + private FieldAccess parseField(Field field) { + // 得到属性上的注解 + SwParam swParam = field.getAnnotation(SwParam.class); + + if (swParam != null) { + if (Object.class.equals(swParam.type())) { + IEditor editor = webDataBinder.findEditor(field.getType(), ParamEditor.TYPE_FIELD); + return new BindFieldAccess(editor, field, swParam.value()); + } else { + EntityDao entityDao = dbEngine.findDao(swParam.type()); + return new SingletonFieldAccess(entityDao, field); + } + } else { + if (singleton) { + if (!isConstance(field) && !isThreadSafe(field)) { + // 记录首个发现的线程不安全字段 + singletonField = field; + singleton = false; + } + } + } + + return null; + } + + private static boolean isConstance(Field field) { + int fieldModifiers = field.getModifiers(); + return Modifier.isStatic(fieldModifiers) && Modifier.isFinal(fieldModifiers); + } + + private boolean isThreadSafe(Field field) { + Class fieldType = field.getDeclaringClass(); + for (Class type : threadSafeTypes) { + if (type.isAssignableFrom(fieldType)) { + return true; + } + } + + return false; + } + +} + diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanAction.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanAction.java new file mode 100644 index 0000000..798fc2e --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanAction.java @@ -0,0 +1,18 @@ +package cc.smtweb.framework.core.mvc.controller.scan; + +import cc.smtweb.framework.core.mvc.controller.IActionManager; +import cc.smtweb.framework.core.mvc.controller.access.IMethodAccess; + +/** + * 实现自定义@SwAction的拦截器,需要配合@SwAction继承注解配置到函数上使用 + * @author kevin + */ +public interface IScanAction { + Class actionType(); + /** + * 一种@SwAction子类型只能声明一个SwActionPointcut + * @param module 模块名称 + * @param actionManager action管理器,用以注册API服务 + */ + void load(IActionManager actionManager, String module, T anno, IMethodAccess methodAccess); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanActionBuilder.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanActionBuilder.java new file mode 100644 index 0000000..dcb9529 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanActionBuilder.java @@ -0,0 +1,12 @@ +package cc.smtweb.framework.core.mvc.controller.scan; + +import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * 实现自定义@SwAction的拦截器,需要配合@SwAction继承注解配置到函数上使用 + * @author kevin + */ +public interface IScanActionBuilder { + IScanAction build(ConfigurableApplicationContext applicationContext, WebDataBinder webDataBinder); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/MethodParser.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/MethodParser.java new file mode 100644 index 0000000..37664f2 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/MethodParser.java @@ -0,0 +1,159 @@ +package cc.smtweb.framework.core.mvc.controller.scan; + +import cc.smtweb.framework.core.annotation.*; +import cc.smtweb.framework.core.mvc.controller.IEditor; +import cc.smtweb.framework.core.mvc.controller.access.ControllerAccess; +import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; +import cc.smtweb.framework.core.mvc.controller.access.MethodParamAccess; +import cc.smtweb.framework.core.mvc.controller.binder.ParamEditor; +import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.ResolvableType; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.text.ParseException; +import java.util.List; + +@Slf4j +public class MethodParser { + private final UrlMaker urlMaker; + private final BeanManager controllers; + private final WebDataBinder webDataBinder; + private ScanContext scanContext; +// private ControllerAccess controllerAccess; + + public MethodParser(UrlMaker urlMaker, ScanContext scanContext) { + this.urlMaker = urlMaker; + this.controllers = scanContext.getBeanManager(); + this.webDataBinder = scanContext.getWebDataBinder(); + this.scanContext = scanContext; + } + + public void parse(Class clazz, ControllerAccess controllerAccess, boolean isApi) throws ParseException { +// this.controllerAccess = controllerAccess; + // 服务的默认权限 + String classPerm = ""; + SwPerm swPerm = clazz.getAnnotation(SwPerm.class); + if (swPerm != null) { + classPerm = swPerm.value(); + } + + // 扫描方法注解 + for (Method m : clazz.getMethods()) { + int modifier = m.getModifiers(); + + // && (R.class.isAssignableFrom(m.getReturnType())) + if (Modifier.isPublic(modifier) && !Modifier.isStatic(modifier) && !Object.class.equals(m.getDeclaringClass())) { + MethodAccess methodAccess = parseMethod(controllerAccess, m, classPerm); + + if (scanContext.dealMethod(m, methodAccess)) { + if (isApi) { + urlMaker.addApi(clazz, m, methodAccess, controllers); + } + } + +// SwScheduling scheduling = m.getAnnotation(SwScheduling.class); +// SwConstruct construct = m.getAnnotation(SwConstruct.class); +// SwDestroy destroy = m.getAnnotation(SwDestroy.class); +// SwBean bean = m.getAnnotation(SwBean.class); +// SwAction action = m.getAnnotation(SwAction.class); +// +// if (scheduling != null) { +// // 定时任务用seed值限定 +// log.debug(" add timer task: " + clazz.getSimpleName() + "." + m.getName()); +// controllers.addTask(new SchedulerMethodAccess(methodAccess, scheduling)); +// } else if(construct != null) { +// controllers.addConstruct(construct.order(), methodAccess); +// } else if(destroy != null) { +// controllers.addDestroy(destroy.order(), methodAccess); +// } else if(bean != null) { +// controllers.addBeanMethod(methodAccess); +// } else if(action != null) { +// controllers.addAction(action, methodAccess); +// } else if (isApi) { +// urlMaker.addApi(clazz, m, methodAccess, controllers); +// } + } + } + } + + private MethodAccess parseMethod(ControllerAccess controllerAccess, Method method, String defaultPerm) { + Class[] paramTypes = method.getParameterTypes(); + Annotation[][] paramAnnotations = method.getParameterAnnotations(); + + MethodParamAccess[] paramBinds = new MethodParamAccess[paramTypes.length]; + + for (int i = 0; i < paramTypes.length; i++) { + Class paramType = paramTypes[i]; + String paramName = null; + int bindType = ParamEditor.TYPE_UNKNOWN; + if (!ObjectUtils.isEmpty(paramAnnotations[i])) { + for (Annotation annotation: paramAnnotations[i]) { + // isAssignableFrom + Class annotationType = annotation.annotationType(); + if (SwParam.class.equals(annotationType)) { + bindType = ParamEditor.TYPE_PARAM; + String value = ((SwParam) annotation).value(); + if (StringUtils.isNotBlank(value)) { + paramName = value; + } + break; + } else if (SwPathParam.class.equals(annotationType)) { + bindType = ParamEditor.TYPE_PATH; + break; + } else if (SwHeaderParam.class.equals(annotationType)) { + bindType = ParamEditor.TYPE_HEADER; + String value = ((SwHeaderParam) annotation).value(); + if (StringUtils.isNotBlank(value)) { + paramName = value; + } + break; + } else if (SwBody.class.equals(annotationType)) { + bindType = ParamEditor.TYPE_BODY; + String value = ((SwBody) annotation).value(); + if (StringUtils.isNotBlank(value)) { + paramName = value; + } + break; + } else if (SwAttr.class.equals(annotationType)) { + bindType = ParamEditor.TYPE_ATTR; + String value = ((SwAttr) annotation).value(); + if (StringUtils.isNotBlank(value)) { + paramName = value; + } + break; + } + } + } + + IEditor editor = webDataBinder.findEditor(paramType, bindType); + + if (List.class.isAssignableFrom(paramType)) { + // List bind类型使用泛型声明的对象 + ResolvableType resolvableType = ResolvableType.forMethodParameter(method, i); + paramType = resolvableType.getGeneric(0).getRawClass(); + paramBinds[i] = new MethodParamAccess(editor, paramName, resolvableType.getGeneric(0).getRawClass(), bindType, paramType); + } else { + paramBinds[i] = new MethodParamAccess(editor, paramName, paramType, bindType, null); + } + + if (editor == null) { + log.error("not bind type:" + controllerAccess.getFullName() + "." + method.getName()); + } + } + + // 得到权限注解 + String perm = defaultPerm; + SwPerm swPerm = method.getAnnotation(SwPerm.class); + if (swPerm != null) { + perm = swPerm.value(); + } + + return new MethodAccess(controllerAccess, method, perm, paramBinds); + } + +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/PackageScanner.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/PackageScanner.java new file mode 100644 index 0000000..d0bfe8b --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/PackageScanner.java @@ -0,0 +1,180 @@ +package cc.smtweb.framework.core.mvc.controller.scan; + +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLDecoder; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +@Slf4j +public class PackageScanner { + private ClassParser classParser; + + public PackageScanner(ClassParser classParser) { + this.classParser = classParser; + } + + /** + * 1. 遍历所有目录 2. 处理注解类,进行适配类匹配 3. 放入路径映射map + * + * @throws IOException + */ + public void scan(String packagePath) throws IOException { +// log.info("[smt]start scan " + packagePath); + directorize(packagePath, true); +// log.info("[smt]end scan " + packagePath); + } + + /** + * 扫描目录下的注解类 + * + * @param packageName 目录对象 + * @param recursive 是否递归扫描包 + */ + private void directorize(String packageName, boolean recursive) + throws IOException { + String packageDirName = packageName.replace('.', '/'); + + Enumeration dirs = Thread.currentThread().getContextClassLoader() + .getResources(packageDirName); + + // 循环迭代下去 + while (dirs.hasMoreElements()) { + // 获取下一个元素 + URL url = dirs.nextElement(); + // 得到协议的名称 + String protocol = url.getProtocol(); + // 如果是以文件的形式保存在服务器上 + if ("file".equals(protocol)) { +// log.debug("scan action in file"); + // 获取包的物理路径 + String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); + // 以文件的方式扫描整个包下的文件 并添加到集合中 + findAndAddClassesInPackageByFile(packageName, "", filePath, + recursive); + // 执行属性设置 +// for (FieldAutowriter field : fieldList) { +// boolean ret = field.writeValue(this.context); +// if (ret) { +// log.debug("write bean " + field.getName() +// + " success."); +// } else { +// log.error("write bean " + field.getName() +// + " failure."); +// } +// } + } else if ("jar".equals(protocol)) { + // 如果是jar包文件 + // 定义一个JarFile + try { + // 获取jar + JarFile jar = ((JarURLConnection) url.openConnection()) + .getJarFile(); + // 从此jar包 得到一个枚举类 + Enumeration entries = jar.entries(); + // 同样的进行循环迭代 + while (entries.hasMoreElements()) { + // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件 + JarEntry entry = entries.nextElement(); + String name = entry.getName(); + // 如果是以/开头的 + if (name.charAt(0) == '/') { + // 获取后面的字符串 + name = name.substring(1); + } + // 如果前半部分和定义的包名相同 + if (name.startsWith(packageDirName)) { + int idx = name.lastIndexOf('/'); + // 如果以"/"结尾 是一个包 + if (idx != -1) { + // 获取包名 把"/"替换成"." + packageName = name.substring(0, idx).replace( + '/', '.'); + } + // 如果可以迭代下去 并且是一个包 + if ((idx != -1) || recursive) { + // 如果是一个.class文件 而且不是目录 + if (!entry.isDirectory()) { + parseFile( + packageName, "", + name.substring(packageName.length() + 1)); + } + } + } + } + } catch (IOException e) { + log.error("scan jar error", e); + // log.error("在扫描用户定义视图时从jar包获取文件出错"); + // e.printStackTrace(); + } + } + } + } + + /** + * 以文件的形式来获取包下的所有Class + * + * @param packageName + * @param packagePath + * @param recursive + */ + public void findAndAddClassesInPackageByFile(String packageName, String dirName, + String packagePath, final boolean recursive) { + // 获取此包的目录 建立一个File + File dir = new File(packagePath); + // 如果不存在或者 也不是目录就直接返回 + if (!dir.exists() || !dir.isDirectory()) { + // log.warn("用户定义包名 " + packageName + " 下没有任何文件"); + return; + } + + // 如果存在 就获取包下的所有文件 包括目录 + // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件) + File[] dirFiles = dir.listFiles(file -> { + String fileName = file.getName(); + return (recursive && file.isDirectory()) + || fileName.endsWith(".class"); + }); + + // 循环所有文件 + if (dirFiles != null) { + for (File file : dirFiles) { + // 如果是目录 则继续扫描 + if (file.isDirectory()) { + findAndAddClassesInPackageByFile(packageName + "." + file.getName(), + file.getName(), file.getAbsolutePath(), recursive); + } else { + parseFile(packageName, dirName, file.getName()); + } + } + } + } + + private void parseFile(String packageName, String dirName, String fileName) { + if (fileName.endsWith(".class")) { + // 去掉后面的".class" 获取真正的类名 + String className = fileName.substring(0, fileName.length() - 6); + + className = packageName + '.' + className; + + try { + Class clazz = Class.forName(className); + + int modifiers = clazz.getModifiers(); + + if (Modifier.isPublic(modifiers) && !Modifier.isAbstract(modifiers)) { + classParser.parse(dirName, clazz); + } + } catch (Exception e) { + log.error("init class error " + className, e); + throw new RuntimeException(e); + } + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ScanContext.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ScanContext.java new file mode 100644 index 0000000..b20338c --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ScanContext.java @@ -0,0 +1,115 @@ +package cc.smtweb.framework.core.mvc.controller.scan; + +import cc.smtweb.framework.core.annotation.SwBean; +import cc.smtweb.framework.core.annotation.SwConstruct; +import cc.smtweb.framework.core.annotation.SwDestroy; +import cc.smtweb.framework.core.annotation.SwScheduling; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; +import cc.smtweb.framework.core.mvc.controller.access.SchedulerMethodAccess; +import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiFunction; + +@Getter +@Slf4j +public class ScanContext { + private final BeanManager beanManager; + private final WebDataBinder webDataBinder; +// private Map, List> actions = new HashMap<>(); + private Map, BiFunction> dealMethodAnnotation = new HashMap<>(); + @Setter + private String module; + + public ScanContext(BeanManager beanManager, WebDataBinder webDataBinder) { + this.beanManager = beanManager; + this.webDataBinder = webDataBinder; +// if (scheduling != null) { +// // 定时任务用seed值限定 +// log.debug(" add timer task: " + clazz.getSimpleName() + "." + m.getName()); +// controllers.addTask(new SchedulerMethodAccess(methodAccess, scheduling)); +// } else if(construct != null) { +// controllers.addConstruct(construct.order(), methodAccess); +// } else if(destroy != null) { +// controllers.addDestroy(destroy.order(), methodAccess); +// } else if(bean != null) { +// controllers.addBeanMethod(methodAccess); +// } else if(action != null) { +// controllers.addAction(action, methodAccess); +// } else if (isApi) { +// urlMaker.addApi(clazz, m, methodAccess, controllers); +// } + dealMethodAnnotation.put(SwScheduling.class, (a, methodAccess) -> { + try { + // 定时任务用seed值限定 + beanManager.addTask(new SchedulerMethodAccess(methodAccess, ((SwScheduling)a))); + log.debug(" add timer task: " + methodAccess.fullName()); + } catch (ParseException e) { + throw new SwException(e); + } + + return false; + }); + + dealMethodAnnotation.put(SwConstruct.class, (a, methodAccess) -> { + beanManager.addConstruct(((SwConstruct)a).order(), methodAccess); + return false; + }); + + dealMethodAnnotation.put(SwDestroy.class, (a, methodAccess) -> { + beanManager.addDestroy(((SwDestroy)a).order(), methodAccess); + return false; + }); + + dealMethodAnnotation.put(SwBean.class, (a, methodAccess) -> { + beanManager.addBeanMethod(methodAccess); + return false; + }); +// +// dealMethodAnnotation.put(SwAction.class, (a, methodAccess) -> { +// return true; +// }); +// +// dealMethodAnnotation.put(SwPerm.class, (a, methodAccess) -> { +// return true; +// }); + } + + public void addScanAction(IScanAction apiLoader) { + Object old = dealMethodAnnotation.putIfAbsent(apiLoader.actionType(), (a, methodAccess) -> { + apiLoader.load(beanManager, module, a, methodAccess); + return false; + }); + + if (old != null) { + log.error("已经存在动作解析器:" + apiLoader.actionType()); + } + } + + public boolean dealMethod(Method m, MethodAccess methodAccess) { + boolean result = true; + Annotation[] annos = m.getDeclaredAnnotations(); + if (annos != null) { + for (Annotation anno: annos) { + BiFunction func = dealMethodAnnotation.get(anno.annotationType()); + if (func != null) { + boolean ret = func.apply(anno, methodAccess); + if (!ret) { + result = false; + break; + } + } + } + } + + return result; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/IRealmLoader.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/IRealmLoader.java new file mode 100644 index 0000000..5d5a490 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/IRealmLoader.java @@ -0,0 +1,18 @@ +package cc.smtweb.framework.core.mvc.realm; + +import cc.smtweb.framework.core.session.UserSession; + +import java.util.Set; + +/** + * @author kevin + * 用户权限加载器 + */ +public interface IRealmLoader { + /** + * 读取用户权限集合 + * @param userSession 用户会话 + * @return 权限集合 + */ + Set getPermits(UserSession userSession); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthenticationException.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthenticationException.java new file mode 100644 index 0000000..3a65419 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthenticationException.java @@ -0,0 +1,7 @@ +package cc.smtweb.framework.core.mvc.realm.exception; + +public class AuthenticationException extends AuthorizationException { + public AuthenticationException(String s) { + super(s); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthorizationException.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthorizationException.java new file mode 100644 index 0000000..423cbbd --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthorizationException.java @@ -0,0 +1,9 @@ +package cc.smtweb.framework.core.mvc.realm.exception; + +import cc.smtweb.framework.core.exception.SwException; + +public class AuthorizationException extends SwException { + public AuthorizationException(String s) { + super(s); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnauthenticatedException.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnauthenticatedException.java new file mode 100644 index 0000000..52ea554 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnauthenticatedException.java @@ -0,0 +1,7 @@ +package cc.smtweb.framework.core.mvc.realm.exception; + +public class UnauthenticatedException extends AuthorizationException { + public UnauthenticatedException(String s) { + super(s); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AbstractPermInterceptor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AbstractPermInterceptor.java new file mode 100644 index 0000000..73e4c3c --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AbstractPermInterceptor.java @@ -0,0 +1,109 @@ +package cc.smtweb.framework.core.mvc.realm.interceptor; + +import cc.smtweb.framework.core.annotation.SwPerm; +import cc.smtweb.framework.core.cache.ISwCache; +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.mvc.controller.IEditor; +import cc.smtweb.framework.core.mvc.realm.exception.ForbiddenException; +import cc.smtweb.framework.core.mvc.realm.exception.UnauthenticatedException; +import cc.smtweb.framework.core.mvc.realm.service.PermCheckItem; +import cc.smtweb.framework.core.mvc.realm.service.PermChecker; +import cc.smtweb.framework.core.session.SessionUtil; +import cc.smtweb.framework.core.session.UserSession; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +public class AbstractPermInterceptor { + private final RedisManager redisManager; + private ISwCache cacheService; + + public AbstractPermInterceptor(RedisManager redisManager) { + this.redisManager = redisManager; + } + + public void setCache(ISwCache cacheService) { + this.cacheService = cacheService; + } + + protected boolean handle(HttpServletRequest request, String permissionValue) { + // 如果注解为null, 说明不需要拦截, 直接放过 + if (StringUtils.isEmpty(permissionValue) || SwPerm.NONE.equals(permissionValue)) { + return true; + } + + // redis读取session,判断是否登录 + String token = SessionUtil.readToken(request); + if (StringUtils.isBlank(token)) { + throw new UnauthenticatedException("not find Auth-Token in header"); + } + + UserSession us = redisManager.get(token, UserSession.class); + if (us == null) { + throw new UnauthenticatedException("not find UserSession by token: " + token); + } + + request.setAttribute(IEditor.USER_TOKEN, token); + request.setAttribute(IEditor.USER_SESSION, us); + + // 如果标记了权限注解,则判断权限 + if (checkPermission(permissionValue, us)) { + // 更新Token redis TTL + redisManager.expire(token, RedisManager.SESSION_EXPIRE_SEC); + return true; + } else { + throw new ForbiddenException("user not permission: " + permissionValue); + } + } + + /** + * 权限检查 + */ + private boolean checkPermission(String permissionValue, UserSession us) { + if (StringUtils.isBlank(permissionValue)) { + return true; + } + + // 从本地缓存或数据库中获取该用户的权限信息 + PermChecker permissionSet = cacheService.get(us.getUserId()); + +// if (MapUtils.isEmpty(permissionSet)) { +// throw new ForbiddenException("empty permission"); +// } + + PermCheckItem permChecker = permissionSet.get(permissionValue); + + if (permChecker != null) { + return true; + } + + while (true) { + permissionValue = getParentPermValue(permissionValue); + + if (permissionValue != null) { + permChecker = permissionSet.get(permissionValue); + if (permChecker != null && permChecker.isPerfixMath()) { + return true; + } + } else { + break; + } + } + + return false; + } + + private static String getParentPermValue(String permissionValue) { + if (permissionValue.length() > 0) { + + int pos = permissionValue.lastIndexOf(':'); + if (pos > 0) { + return permissionValue.substring(0, pos); + } + + return ""; + } + + return null; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AuthorizationInterceptor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AuthorizationInterceptor.java new file mode 100644 index 0000000..47a24d5 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AuthorizationInterceptor.java @@ -0,0 +1,42 @@ +package cc.smtweb.framework.core.mvc.realm.interceptor; + +import cc.smtweb.framework.core.annotation.SwPerm; +import cc.smtweb.framework.core.cache.redis.RedisManager; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 暂时未使用,spring的拦截器方式判断权限 + */ +public class AuthorizationInterceptor extends AbstractPermInterceptor implements HandlerInterceptor { + + public AuthorizationInterceptor(RedisManager redisManager) { + super(redisManager); + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + if (handler instanceof HandlerMethod) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + // 获取方法上的注解 + SwPerm requiredSwPerm = handlerMethod.getMethod().getAnnotation(SwPerm.class); + // 如果方法上的注解为空 则获取类的注解 + if (requiredSwPerm == null) { + requiredSwPerm = handlerMethod.getMethod().getDeclaringClass().getAnnotation(SwPerm.class); + } + + String requiredValue = null; + if (requiredSwPerm != null) { + requiredValue = requiredSwPerm.value(); + } + + return super.handle(request, requiredValue); + } + + return true; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermCheckItem.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermCheckItem.java new file mode 100644 index 0000000..2cecf28 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermCheckItem.java @@ -0,0 +1,21 @@ +package cc.smtweb.framework.core.mvc.realm.service; + +public class PermCheckItem { + // 全匹配 + private static final int TYPE_ALL_MATCH = 0; + // 前缀匹配 + private static final int TYPE_PREFIX_MATCH = 1; + + private int type; + + public static final PermCheckItem allMatch = new PermCheckItem(TYPE_ALL_MATCH); + public static final PermCheckItem prefixMatch = new PermCheckItem(TYPE_PREFIX_MATCH); + + private PermCheckItem(int type) { + this.type = type; + } + + public boolean isPerfixMath() { + return this.type == TYPE_PREFIX_MATCH; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermChecker.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermChecker.java new file mode 100644 index 0000000..8bb2cc5 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermChecker.java @@ -0,0 +1,35 @@ +package cc.smtweb.framework.core.mvc.realm.service; + +import java.util.HashMap; +import java.util.Set; + +public class PermChecker extends HashMap { + private static final PermChecker CHECKER_ZERO = new PermChecker(); + + private PermChecker(){ + super(); + } + + private PermChecker(int size){ + super(size); + } + + public static PermChecker build(Set permits) { + if (permits != null) { + PermChecker result = new PermChecker(permits.size()); + + for (String perm: permits) { + if (perm.endsWith(":*")) { + perm = perm.substring(0, perm.length() - 2); + result.put(perm, PermCheckItem.prefixMatch); + } else { + result.putIfAbsent(perm, PermCheckItem.allMatch); + } + } + + return result; + } + + return CHECKER_ZERO; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJob.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJob.java new file mode 100644 index 0000000..d3d8030 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJob.java @@ -0,0 +1,59 @@ +package cc.smtweb.framework.core.mvc.scheduler; + +import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractJob { + final MethodAccess method; + @Getter + private String key; + boolean hasPointParam; +// @Getter @Setter +// private AbstractJobQueue jobQueue; + + public AbstractJob(MethodAccess methodAccess) { + this.method = methodAccess; + this.hasPointParam = methodAccess.findParam(SchedulerPoint.class) != null; + } + + protected void initKey(String key) { + this.key = key; + } + +// public void invoke(Map params) { +// try { +// // 组织断点对象参数 +// Map params = null; +// SchedulerPoint schedulerPoint = null; +// if (hasPointParam) { +// schedulerPoint = jobManager.loadBreakPoint(this); +// if (schedulerPoint != null) { +// params = new HashMap<>(1); +// params.put(SchedulerPoint.class.getName(), schedulerPoint); +// } +// } +// +// method.invoke(beanContext, params, null, null, null); +// +// if (hasPointParam) { +// jobManager.saveBreakPoint(this, schedulerPoint); +// } +// } catch (InvocationTargetException e) { +// if (e.getCause() != null) { +// log.error(e.getCause().getMessage(), e.getCause()); +// } else { +// log.error(e.getMessage(), e); +// } +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// } + + public abstract AbstractJobQueue createJobQueue(AbstractJobExecutor jobManager); + + public String getName() { + return this.method.fullName(); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobQueue.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobQueue.java new file mode 100644 index 0000000..1f5993f --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobQueue.java @@ -0,0 +1,72 @@ +package cc.smtweb.framework.core.mvc.scheduler; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Job执行队列 + * @author xkliu + */ +@Slf4j +public abstract class AbstractJobQueue { + private AtomicLong lastTime = new AtomicLong(); + private ReentrantLock lock = new ReentrantLock(); + @Getter + private AbstractJobExecutor jobExecutor; + + public AbstractJobQueue(AbstractJobExecutor jobExecutor) { + this.jobExecutor = jobExecutor; + } + + public void execute(AbstractJob job) { + try { + // 组织断点对象参数 + Map params = null; + SchedulerPoint schedulerPoint = null; + if (job.hasPointParam) { + schedulerPoint = jobExecutor.loadBreakPoint(job); + if (schedulerPoint != null) { + params = new HashMap<>(1); + params.put(SchedulerPoint.class.getName(), schedulerPoint); + } + } + + job.method.invoke(jobExecutor.getBeanContext(), params, null, null); + + if (job.hasPointParam) { + jobExecutor.saveBreakPoint(job, schedulerPoint); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + } + + public long getLastTime() { + return lastTime.get(); + } + + protected boolean tryLock() { + boolean result = lock.tryLock(); + + if (result) { + lastTime.set(System.currentTimeMillis()); + } + + return result; + } + + protected void unlock() { + lastTime.set(0); + lock.unlock(); + } + + public void updateLastTime() { + lastTime.set(System.currentTimeMillis()); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/FixedTimerTask.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/FixedTimerTask.java new file mode 100644 index 0000000..7f33937 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/FixedTimerTask.java @@ -0,0 +1,19 @@ +package cc.smtweb.framework.core.mvc.scheduler; + +import com.serotonin.timer.FixedRateTrigger; +import com.serotonin.timer.TimerTask; + +public class FixedTimerTask extends TimerTask { + private final Runnable job; + + // new TimerTask(new FixedRateTrigger(30, 60)), result.redisJobManager + public FixedTimerTask(int delay, int period, Runnable job) { + super(new FixedRateTrigger(delay, period)); + this.job = job; + } + + @Override + public void run(long runtime) { + job.run(); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerPoint.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerPoint.java new file mode 100644 index 0000000..b2bf66c --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerPoint.java @@ -0,0 +1,40 @@ +package cc.smtweb.framework.core.mvc.scheduler; + +import cc.smtweb.framework.core.common.SwMap; + +/** + * 定时器断点数据 + * @author xkliu + */ +public class SchedulerPoint { + SwMap value; + boolean changed; + boolean insert; + + public SchedulerPoint() { + insert = true; + value = new SwMap(); + } + + public SchedulerPoint(SwMap value) { + this.value = value; + } + + public Object get(String key) { + return value.get(key); + } + + public Long readLong(String key) { + return value.readLong(key); + } + public Long readLong(String key, Long defaultValue) { + return value.readLong(key, defaultValue); + } + + public SchedulerPoint put(String key, Object value) { + this.value.put(key, value); + this.changed = true; + + return this; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerTaskManager.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerTaskManager.java new file mode 100644 index 0000000..7fe5a7d --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerTaskManager.java @@ -0,0 +1,97 @@ +package cc.smtweb.framework.core.mvc.scheduler; + +import cc.smtweb.framework.core.annotation.SwScheduling; +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.mvc.ISchedulerWakeup; +import cc.smtweb.framework.core.mvc.controller.IBeanContext; +import cc.smtweb.framework.core.mvc.controller.access.SchedulerMethodAccess; +import cc.smtweb.framework.core.mvc.scheduler.job.GroupJob; +import cc.smtweb.framework.core.mvc.scheduler.job.LocalJobExecutor; +import cc.smtweb.framework.core.mvc.scheduler.job.RedisJobExecutor; +import cc.smtweb.framework.core.mvc.scheduler.job.SimpleJob; +import com.serotonin.timer.RealTimeTimer; +import com.serotonin.timer.TimerTask; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class SchedulerTaskManager implements ISchedulerWakeup { + private final ExecutorService executor; + private final RealTimeTimer timer; + private final Map timerTaskMap = new HashMap<>(); + + private SchedulerTaskManager() { + int poolSize = Runtime.getRuntime().availableProcessors(); + this.executor = new ThreadPoolExecutor(2, poolSize * 2 + 2, 5, TimeUnit.MINUTES, + new SynchronousQueue<>(), + new BasicThreadFactory.Builder().namingPattern("sw-scheduler-").build()); + + // 保证2个线程就够了,1个触发定时器,1个定时同步redis状态 + this.timer = new RealTimeTimer(); + this.timer.init(1, 4); + } + + public static SchedulerTaskManager build(IBeanContext beanContext, List tasks) { + if (!tasks.isEmpty()) { + SchedulerTaskManager result = new SchedulerTaskManager(); + + DbEngine dbEngine = beanContext.getBean(DbEngine.class); + RedisManager redisManager = beanContext.getBean(RedisManager.class); + Long redisLockValue = dbEngine.nextId(); + + LocalJobExecutor localJobExecutor = new LocalJobExecutor(beanContext, result.executor, redisLockValue, dbEngine); + RedisJobExecutor redisJobExecutor = new RedisJobExecutor(beanContext, result.executor, redisLockValue, dbEngine, redisManager); + + for (SchedulerMethodAccess schedulerMethodAccess: tasks) { + SwScheduling swScheduling = schedulerMethodAccess.getSwScheduling(); + + AbstractJob job; + String group = swScheduling.group(); + AbstractJobExecutor jobManager = swScheduling.multiServer() ? localJobExecutor : redisJobExecutor; + + if (StringUtils.isNotBlank(group)) { + job = new GroupJob(group, schedulerMethodAccess.getMethodAccess()); + } else { + job = new SimpleJob(schedulerMethodAccess.getMethodAccess()); + } + + AbstractJobQueue jobQueue = jobManager.initJobQueue(job); + CronTimerTask task = new CronTimerTask(schedulerMethodAccess.getTimerTrigger(), jobQueue, job); + + result.timer.schedule(task); + result.timerTaskMap.put(job.getName(), task); + } + + int time = RedisJobExecutor.TIME_CHECK_SEC * 1000; + result.timer.schedule(new FixedTimerTask(time, time, redisJobExecutor)); + + return result; + } + + return null; + } + + public void shutdown() { + this.timer.cancel(); + this.executor.shutdown(); + } + + @Override + public boolean wakeup(Class clazz, String methodName) { + TimerTask task = timerTaskMap.get(clazz.getName() + "." + methodName); + if (task != null) { + task.run(System.currentTimeMillis()); + return true; + } + + return false; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJobQueue.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJobQueue.java new file mode 100644 index 0000000..2fd9a56 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJobQueue.java @@ -0,0 +1,82 @@ +package cc.smtweb.framework.core.mvc.scheduler.job; + +import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; +import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; +import cc.smtweb.framework.core.mvc.scheduler.AbstractJobQueue; + +import java.util.Deque; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +public class GroupJobQueue extends AbstractJobQueue { + private Deque queue; + private Set keySet; + private String currentJobName; + + public GroupJobQueue(AbstractJobExecutor jobManager) {super(jobManager);} + + private synchronized void setCurrent(AbstractJob job) { + currentJobName = job.getName(); + } + + private synchronized AbstractJob pull() { + AbstractJob result = null; + + if (queue != null) { + result = queue.pop(); + + if (result != null) { + keySet.remove(result.getName()); + } + } + + if (result != null) { + this.currentJobName = result.getName(); + } else { + this.currentJobName = null; + } + + return result; + } + + private synchronized boolean push(AbstractJob job) { + String jobName = job.getName(); + + if (jobName.equals(currentJobName)) { + return false; + } + + if (keySet == null) { + keySet = new HashSet<>(); + } else if (keySet.contains(jobName)) { + // 避免重复加入 + return false; + } + + keySet.add(jobName); + + if (queue == null) { + queue = new LinkedList<>(); + } + + queue.push(job); + return true; + } + + @Override + public void execute(AbstractJob job) { + if (tryLock()) { + try { + setCurrent(job); + do { + super.execute(job); + } while((job = pull()) != null); + } finally { + unlock(); + } + } else { + push(job); + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJob.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJob.java new file mode 100644 index 0000000..19b2720 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJob.java @@ -0,0 +1,19 @@ +package cc.smtweb.framework.core.mvc.scheduler.job; + +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; +import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; +import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; +import cc.smtweb.framework.core.mvc.scheduler.AbstractJobQueue; + +public class SimpleJob extends AbstractJob { + public SimpleJob(MethodAccess methodAccess) { + super(methodAccess); + initKey(RedisManager.PREFIX_TIMER + methodAccess.fullName()); + } + + @Override + public AbstractJobQueue createJobQueue(AbstractJobExecutor jobManager) { + return new SimpleJobQueue(jobManager); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJobQueue.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJobQueue.java new file mode 100644 index 0000000..e0de2d1 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJobQueue.java @@ -0,0 +1,22 @@ +package cc.smtweb.framework.core.mvc.scheduler.job; + +import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; +import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; +import cc.smtweb.framework.core.mvc.scheduler.AbstractJobQueue; + +public class SimpleJobQueue extends AbstractJobQueue { + public SimpleJobQueue(AbstractJobExecutor jobManager) { + super(jobManager); + } + + @Override + public void execute(AbstractJob job) { + if (tryLock()) { + try { + super.execute(job); + } finally { + unlock(); + } + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompProvider.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompProvider.java new file mode 100644 index 0000000..472a9a3 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompProvider.java @@ -0,0 +1,21 @@ +package cc.smtweb.framework.core.mvc.service; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Akmm at 2022/3/3 11:13 + * 数据提供者,线程级缓存 + */ +public class AbstractCompProvider { + //临时缓存 + private Map cacheData = new HashMap<>(); + + protected T doGetData(String key, IDataProvider loader) { + cacheData.computeIfAbsent(key, s -> loader.load()); + if (!cacheData.containsKey(key)) { + cacheData.put(key, loader.load()); + } + return (T) cacheData.get(key); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractDelHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractDelHandler.java new file mode 100644 index 0000000..cdbaaf8 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractDelHandler.java @@ -0,0 +1,53 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; +import lombok.extern.slf4j.Slf4j; + +/** + * Created by Akmm at 2022/3/2 19:44 + * 保存 + */ +@Slf4j +public abstract class AbstractDelHandler extends AbstractHandler{ + protected long id; + + public R del() { + id = readId(); + + checkValid(); + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + delDb(); + } + + @Override + public void doAfterDbCommit() { + super.doAfterDbCommit(); + saveSuccess(); + } + + @Override + public void doAfterDbRollback() { + super.doAfterDbRollback(); + saveFailed(); + } + }); + return R.success(); + } + + /** + * 读取页面传回来的id + * @return + */ + protected long readId() { + return params.readLong("id", 0L); + } + + protected abstract void checkValid(); + protected abstract void delDb(); + protected void saveSuccess() {} + protected void saveFailed() {} +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractHandler.java new file mode 100644 index 0000000..90c16e0 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractHandler.java @@ -0,0 +1,17 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.session.UserSession; + +/** + * Created by Akmm at 2022/3/2 19:44 + */ +public abstract class AbstractHandler { + protected SwMap params; + protected UserSession us; + + public void init(SwMap params, UserSession us) { + this.params = params; + this.us = us; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractListHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractListHandler.java new file mode 100644 index 0000000..e8b3376 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractListHandler.java @@ -0,0 +1,235 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.cache.SessionCache; +import cc.smtweb.framework.core.cache.SessionCacheFactory; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.mvc.service.list.FooterField; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY; + +/** + * Created by Akmm at 2022/3/2 19:44 + * 列表服务 + */ +@Slf4j +public abstract class AbstractListHandler extends AbstractHandler { + protected static String KEY_SQLPARA = "query-sqlPara"; + protected static String KEY_SQLPARA_SUM = "query-sqlPara-sum"; + protected static String KEY_PARAMS = "query-params"; + + private SessionCache sessionCache; + + protected String getCompId() { + return this.getClass().getSimpleName(); + } + + protected T getCache(String key) { + if (sessionCache == null) + sessionCache = SessionCacheFactory.getInstance().getUserCache(us.getUserId()); + return sessionCache.get(getCompId() + "." + key); + } + + protected void setCache(String key, Object v) { + if (sessionCache == null) + sessionCache = SessionCacheFactory.getInstance().getUserCache(us.getUserId()); + sessionCache.put(getCompId() + "." + key, v); + } + + protected void removeCache(String key) { + if (sessionCache == null) + sessionCache = SessionCacheFactory.getInstance().getUserCache(us.getUserId()); + sessionCache.remove(getCompId() + "." + key); + } + + public R data() { + return R.success(buildListData()); + } + + public SwListData buildListData() { + List listData; + SqlPara sqlPara = buildDataSql(); + + + String sort = params.readString("sort"); + String order = params.readString("order"); + String sql; + if (StringUtils.isEmpty(sort)) sql = sqlPara.sql; + else { + sql = "select ar.* from (" + sqlPara.sql + ") ar order by ar." + sort + " " + order; + if (StringUtils.isNotEmpty(getPkFieldName())) { + sql += "," + getPkFieldName(); + } + } + + listData = queryData(sql, sqlPara); + + afterQuery(listData); + return SwListData.create(listData, sqlPara.rows); + } + + protected List queryData(String sql, SqlPara sqlPara) { + sqlPara.rows = params.readInt("rows", 0); + sqlPara.page = params.readInt("page", 1); + + + if (sqlPara.rows == 0) { + return DbEngine.getInstance().query(sql, SwMap.class, sqlPara.paras); + } else { + //查分页数据 + return DbEngine.getInstance().pagedQuery(sql, SwMap.class, (sqlPara.page - 1) * sqlPara.rows, sqlPara.rows, sqlPara.paras); + } + } + + protected SqlPara buildSumSqlPara() { + SqlPara sqlPara = getCache(KEY_SQLPARA); + if (sqlPara == null) return null; + + List footerFields = getFooterFields(); + StringBuilder sql = new StringBuilder(128); + sql.append("select count(1) " + TOTAL_KEY); + for (FooterField cn : footerFields) { + if (!FooterField.STATIC_TEXT.equals(cn.type)) { + if (FooterField.SUM_TYPE_COUNT_ALL.equals(cn.type)) { + sql.append(",COUNT("); + } else if (FooterField.SUM_TYPE_SUM_NUM.equals(cn.type)) { + sql.append(",SUM("); + } else { + sql.append(",").append(cn.type).append("("); + } + if (FooterField.SUM_TYPE_COUNT.equals(cn.type)) + sql.append("distinct "); + sql.append(cn.field).append(") ").append(cn.field); + } + } + sql.append(" from (").append(sqlPara.getSqlNoOrderBy()).append(") xxxxxz"); + + return new SqlPara(sql.toString(), sqlPara.paras); + } + + public R getTotal() { + try { + SqlPara sqlParaSum = getCache(KEY_SQLPARA_SUM); + if (sqlParaSum == null) { + Map map = getCache(KEY_PARAMS); + if (map != null) params.putAll(map); + sqlParaSum = buildSumSqlPara(); + } + if (sqlParaSum == null) return R.success(); + setCache(KEY_SQLPARA_SUM, sqlParaSum); + + SwMap mapFooter = DbEngine.getInstance().queryEntity(sqlParaSum.sql, SwMap.class, sqlParaSum.paras); + + SwMap r = new SwMap(); + r.put("total", mapFooter.get(TOTAL_KEY)); + r.put("footer", mapFooter); + return R.success(r); + } catch (Exception e) { + return R.error("计算合计失败!", e); + } + } + + protected SqlPara buildDataSql() { + //从缓存里看看有没有保存的sql缓存; + SqlPara sqlParaInCache = getCache(KEY_SQLPARA); //缓存里面的对象; + boolean query = sqlParaInCache == null || params.readBool("query"); + if (!query) { + Map map = getCache(KEY_PARAMS); + if (map == null) query = true; + else { + Map params = getCachedParams(); + if (params.size() > map.size()) query = true;//本次参数更多 + else { + for (String key : params.keySet()) { + Object v = map.get(key); + String cv = v != null && StringUtils.isNotEmpty(v.toString()) ? v.toString() : ""; + v = params.get(key); + String rv = v != null && StringUtils.isNotEmpty(v.toString()) ? v.toString() : ""; + if (!cv.equals(rv)) { + query = true; + break; + } + } + } + } + } + SqlPara sqlPara = null; + if (query) {//新查询 + //缓存里面没有对象,重新构建查询条件,重新计算汇总数; + buildParam();//构造过滤条件,设默认值 + sqlPara = buildSqlPara(); //重新构建查询对象; + removeCache(KEY_SQLPARA_SUM); + + setCache(KEY_SQLPARA, sqlPara); + setCache(KEY_PARAMS, getCachedParams());//不缓存页码之类的东东,避免下次请求时,页码又回去了 + } else { + sqlPara = sqlParaInCache; + + Map map = getCache(KEY_PARAMS); + if (map != null) params.putAll(map); + } + return sqlPara; + } + + /** + * 构造过滤条件,设默认值 + * + * @throws Exception + */ + protected void buildParam() { + + } + + /** + * sql主键字段,用于点击表头排序时保证排序记录唯一性 + * + * @return + */ + protected String getPkFieldName() { + return null; + } + + protected void afterQuery(List listData) { + } + + protected abstract SqlPara buildSqlPara(); + + //构建合计字段 + private List getFooterFields() { + List footerFields = new ArrayList<>(); + buildFooterFields(footerFields); + return footerFields; + } + + protected void buildFooterFields(List footer) { + } + + protected Map getCachedParams() { + Map map = new HashMap<>(); + map.putAll(params); + map.remove("page"); + map.remove("rows"); + map.remove("sort"); + map.remove("order"); + map.remove("tokenkey"); + map.remove("tokenval"); + map.remove("_v"); + map.remove("_dn"); + map.remove("_sk"); + map.remove("_skw"); + map.remove("_tk"); + map.remove("_sb"); + map.remove("__exp_model"); + map.remove("model"); + map.remove("data"); + return map; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractLoadHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractLoadHandler.java new file mode 100644 index 0000000..8f36e81 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractLoadHandler.java @@ -0,0 +1,32 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.common.R; + +/** + * Created by Akmm at 2022/3/2 19:44 + */ +public abstract class AbstractLoadHandler extends AbstractHandler { + + public R load() { + long id = readId(); + T bean; + if (id <= 0L) { + bean = createComp(); + } else { + bean = loadComp(id); + } + return R.success(bean); + } + + /** + * 读取页面传回来的id + * @return + */ + protected long readId() { + return params.readLong("id", 0L); + } + + protected abstract T createComp(); + + protected abstract T loadComp(long id); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultComboHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultComboHandler.java new file mode 100644 index 0000000..296a35d --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultComboHandler.java @@ -0,0 +1,84 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by Akmm at 2022/3/2 19:52 + * 默认实体实现 + */ +public class DefaultComboHandler extends DefaultListHandler { + + public DefaultComboHandler(String tableName) { + super(tableName); + } + + public R filter() { + return R.success(filterData()); + } + + protected SwListData filterData() { + String text = params.readString("text"); + if (StringUtils.isEmpty(text)) throw new BizException("没有搜素内容!"); + + SqlPara sqlPara = buildDataSql(); + String sort = params.readString("sort"); + String order = params.readString("order"); + + StringBuilder sqlFilter = new StringBuilder(); + List args = new ArrayList<>(sqlPara.paras.length); + Collections.addAll(args, sqlPara.paras); + + buildFilterCondition(text, sqlFilter, args); + if (sqlFilter.length() == 0) throw new BizException("没有待搜索的字段!"); + + String sql = "select ar.* from (" + sqlPara.sql + ") ar where " + sqlFilter.substring(4); + if (StringUtils.isNotEmpty(sort)) { + sql += " order by ar." + sort + " " + order; + if (StringUtils.isNotEmpty(getPkFieldName())) { + sql += "," + getPkFieldName(); + } + } + + List listData = DbEngine.getInstance().pagedQuery(sql, SwMap.class, 0, 10, args.toArray()); + afterQuery(listData); + return SwListData.create(listData, 0); + } + + //搜索条件 + protected void buildFilterCondition(String text, StringBuilder sqlFilter, List args) { + List fields = new ArrayList<>(); + getFilterFields(fields); + if (fields.isEmpty()) return; + + text = text + "%";//combo不支持全模糊 + for (String field: fields) { + sqlFilter.append(" or " + field + " like ?"); + args.add(text); + } + + } + + //构建参与搜索的字段,默认为code和name字段 + protected void getFilterFields(List fields) { + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + ModelField field = table.findFieldByType(SwEnum.FieldType.CODE.value); + if (field != null) fields.add(field.getName()); + + field = table.findFieldByType(SwEnum.FieldType.NAME.value); + if (field != null) fields.add(field.getName()); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultListHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultListHandler.java new file mode 100644 index 0000000..791756b --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultListHandler.java @@ -0,0 +1,73 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.EntityHelper; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Akmm at 2022/3/2 19:52 + * 默认实体实现 + */ +public class DefaultListHandler extends AbstractListHandler { + protected String tableName; + + public DefaultListHandler(String tableName) { + this.tableName = tableName; + } + + @Override + protected SqlPara buildSqlPara() { + EntityDao dao = DbEngine.getInstance().findDao(tableName); + StringBuilder sql = new StringBuilder(512); + List args = new ArrayList<>(); + dao.handleSelect(sql, null); + + StringBuilder sqlCondition = new StringBuilder(128); + buildCondition(sqlCondition, args); + String filter = sqlCondition.toString().trim(); + if (StringUtils.isNotEmpty(filter)) { + if (filter.startsWith("or ")) { + sql.append("\nwhere ").append(filter.substring(3)); + } else if (filter.startsWith("and ")) { + sql.append("\nwhere ").append(filter.substring(4)); + } else if (!filter.startsWith("where ")) { + sql.append("\nwhere ").append(filter); + } else { + sql.append(filter); + } + } + + buildOrder(sql); + + return new SqlPara(sql.toString(), args.toArray()); + } + + protected void buildCondition(StringBuilder sql, List args) { + } + + protected void buildOrder(StringBuilder sql) { + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + if (table == null) return; + sql.append(" order by "); + + ModelField field = table.findFieldByType(SwEnum.FieldType.CODE.value); + if (field != null) sql.append(field.getName()).append(","); + sql.append(table.getIdField()); + } + + @Override + protected void afterQuery(List listData) { + super.afterQuery(listData); + EntityHelper.loadBeanLink(tableName, listData, null); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultLoadHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultLoadHandler.java new file mode 100644 index 0000000..a42639f --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultLoadHandler.java @@ -0,0 +1,36 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; + +/** + * Created by Akmm at 2022/3/2 19:52 + * 默认实体实现 + */ +public class DefaultLoadHandler extends AbstractLoadHandler { + protected String tableName; + + public DefaultLoadHandler(String tableName) { + this.tableName = tableName; + } + + @Override + protected T createComp() { + final EntityDao dao = DbEngine.getInstance().findDao(tableName); + T bean = dao.createBean(); + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + ModelField field = table.findFieldByType(SwEnum.FieldType.CREATE_USER.value); + if (field != null) bean.put(field.getName(), us.getUserId()); + return bean; + } + + @Override + protected T loadComp(long id) { + return new DefaultProvider(tableName).getBean(id); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultSaveHandler.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultSaveHandler.java new file mode 100644 index 0000000..0a0defa --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultSaveHandler.java @@ -0,0 +1,176 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.common.R; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelIndex; +import cc.smtweb.framework.core.db.vo.ModelTable; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +/** + * Created by Akmm at 2022/3/2 19:52 + * 默认实体实现 + */ +public class DefaultSaveHandler extends AbstractSaveHandler { + protected String tableName; + + private List listTreeBean = null; + + public DefaultSaveHandler(String tableName) { + this.tableName = tableName; + } + + @Override + protected T createComp() { + final EntityDao dao = DbEngine.getInstance().findDao(tableName); + T bean = dao.createBean(); + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + ModelField field = table.findFieldByType(SwEnum.FieldType.CREATE_USER.value); + if (field != null) bean.put(field.getName(), us.getUserId()); + field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); + if (field != null) bean.put(field.getName(), us.getUserId()); + return bean; + } + + @Override + protected long readId() { + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + return params.readLong(table.getIdField()); + } + + @Override + protected void setNewId() { + bean.setEntityId(DbEngine.getInstance().nextId()); + } + + @Override + protected T loadComp(long id) { + return new DefaultProvider(tableName).getBean(id); + } + + @Override + protected void readFromPage() { + bean.readFromMap(params); + } + + @Override + protected void checkValid() { + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + for (ModelField field : table.getFields()) { + if (field.isNotNull() && StringUtils.isEmpty(bean.getStr(field.getName()))) { + throw new BizException(field.getTitle() + "不能为空!"); + } + if (field.getFieldType() == SwEnum.FieldType.PARENT_ID.value) { + TreeHelper.getTreeHelper(tableName).checkParent(bean); + } + } + + EntityDao dao = DbEngine.getInstance().findDao(tableName); + for (ModelIndex mi : table.getIndexes()) { + if (mi.isUnique()) { + dao.checkUnique(bean, mi.getFields().split(",")); + } + } + } + + @Override + protected void saveDb() { + EntityDao dao = DbEngine.getInstance().findDao(tableName); + if (isNew) { + dao.insertEntity(bean); + } else { + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); + if (field != null) bean.put(field.getName(), us.getUserId()); + + updateBean(dao); + if (table.getType() == SwEnum.TableType.TYPE_TREE.value) { + listTreeBean = TreeHelper.getTreeHelper(tableName).resetTreeLevel(bean); + } + } + } + + //更新入库 + protected void updateBean(EntityDao dao) { + dao.updateEntity(bean); + } + + + @Override + protected void saveSuccess() { + super.saveSuccess(); + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + if (table.isNeedCache()) { + AbstractCache cache = CacheManager.getIntance().getCache(tableName); + //树型表,父亲改变了,要多处理下缓存;还有个东东:级次码 + if (listTreeBean != null && !listTreeBean.isEmpty()) { + for (T b : listTreeBean) { + cache.put(b); + } + } else { + cache.put(bean); + } + } + } + + @Override + protected void saveFailed() { + super.saveFailed(); + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + if (table.isNeedCache()) { + AbstractCache cache = CacheManager.getIntance().getCache(tableName); + cache.reset(bean); + } + } + + //树,改变父亲 + public R changeParent(){ + ModelTable table = ModelTableCache.getInstance().getByName(tableName); + if (table.getType() != SwEnum.TableType.TYPE_TREE.value) throw new BizException("非树型表,不支持更改父节点"); + + long id = params.readLong("id"); + long parentId = params.readLong("parent_id"); + + AbstractCache cache = CacheManager.getIntance().getCache(tableName); + if (table.isNeedCache()) { + bean = cache.get(id); + } else { + bean = loadComp(id); + } + TreeHelper.getTreeHelper(tableName).checkParent(bean); + //不考虑没有级次码等情况,这个在表设计时校验 + ModelField fieldParentId = table.findFieldByType(SwEnum.FieldType.PARENT_ID.value); + + bean.put(fieldParentId.getName(), parentId); + DbEngine.getInstance().doTrans(new AbsDbWorker() { + @Override + public void work() { + EntityDao dao = DbEngine.getInstance().findDao(tableName); + listTreeBean = TreeHelper.getTreeHelper(tableName).resetTreeLevel(bean); + dao.updateEntity(bean, fieldParentId.getName()); + } + + @Override + public void doAfterDbCommit(){ + saveSuccess(); + } + + @Override + public void doAfterDbRollback() { + saveFailed(); + } + }); + return R.success(); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/IDataProvider.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/IDataProvider.java new file mode 100644 index 0000000..84f130e --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/IDataProvider.java @@ -0,0 +1,8 @@ +package cc.smtweb.framework.core.mvc.service; + +/** + * Created by Akmm at 2022/3/3 12:10 + */ +public interface IDataProvider { + T load(); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/IWorker.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/IWorker.java new file mode 100644 index 0000000..a37939e --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/IWorker.java @@ -0,0 +1,11 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.common.R; + +/** + * Created by Akmm at 2022/3/2 19:01 + * 所有handler的接口 + */ +public interface IWorker { + R doWork(AbstractHandler handler); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlNamedPara.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlNamedPara.java new file mode 100644 index 0000000..9c6177e --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlNamedPara.java @@ -0,0 +1,30 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.common.SwMap; + +import java.util.HashMap; +import java.util.Map; + +//一个sql及其参数,具名参数 +public class SqlNamedPara extends SqlPara { + public SwMap mapParas = new SwMap(); + //字段别名 + public Map mapFieldAlias = new HashMap<>(); + + public SqlNamedPara(String sql) { + this.sql = sql; + } + + public SqlNamedPara(String sql, SwMap paras) { + this.sql = sql; + this.mapParas = paras; + } + + public void addParas(String name, Object value) { + mapParas.put(name, value); + } + + public void addFieldAlias(String fieldName, String alias) { + mapFieldAlias.put(fieldName, alias); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlPara.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlPara.java new file mode 100644 index 0000000..2c07fe0 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlPara.java @@ -0,0 +1,36 @@ +package cc.smtweb.framework.core.mvc.service; + +//一个sql及其参数 +public class SqlPara { + public String sql; + public Object[] paras; + public int rows; + public int page; + + public SqlPara() { + } + + public SqlPara(String sql, Object... paras) { + this.sql = sql; + this.paras = paras; + } + + //获取不带order by 的sql语句 + public String getSqlNoOrderBy() { + String sSql = sql.toUpperCase(); + int n = sSql.lastIndexOf("ORDER BY ");//截取最后一个 order by + if (n < 0) return sql; + String retSql = sql.substring(0, n); + String s = sSql.substring(n); + if (s.contains("SELECT")) return sql; //最后一个order by之后,有子查询的不算 + if (!s.contains(")")) return retSql; //校验order by之后带括号的情况,一般是表达式 + n = 0; + for (int i = 0, len = s.length(); i < len; i++) { + final char c = s.charAt(i); + if (c == '(') n++; + else if (c == ')') n--; + if (n < 0) return sql; + } + return retSql; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SwListData.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SwListData.java new file mode 100644 index 0000000..d2299d2 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/SwListData.java @@ -0,0 +1,36 @@ +package cc.smtweb.framework.core.mvc.service; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public class SwListData { + public static final SwListData EMPTY = new SwListData(new ArrayList<>(), 0); + + private final List rows; + // 总数, -1 表示需要异步获取数量, >=0 表示总数 + private int total = 0; + + private SwListData(List rows, int total) { + this.rows = rows; + this.total = total; + } + + public static SwListData create(List list, int rows) { + if (list == null) { + return SwListData.EMPTY; + } + + if (rows > 0 && list.size() >= rows) { + return new SwListData(list, -1); + } else { + return new SwListData(list, list.size()); + } + } + + public boolean isEmpty() { + return this.rows == null || this.rows.isEmpty(); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java new file mode 100644 index 0000000..413bb37 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java @@ -0,0 +1,132 @@ +package cc.smtweb.framework.core.mvc.service; + +import cc.smtweb.framework.core.cache.AbstractCache; +import cc.smtweb.framework.core.cache.CacheManager; +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.common.SwEnum; +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.cache.ModelTableCache; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.db.vo.ModelField; +import cc.smtweb.framework.core.db.vo.ModelTable; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by Akmm at 2022/3/17 19:56 + */ +public class TreeHelper { + private static Map mapInstance; + static { + mapInstance = new ConcurrentHashMap<>(); + } + private String tableName; + + private ModelTable table; + protected AbstractCache cache; + private EntityDao dao; + + private String fieldParent; + private String fieldLevelCode; + + + public static TreeHelper getTreeHelper(String tableName) { + return mapInstance.computeIfAbsent(tableName, k-> new TreeHelper(tableName)); + } + + public static TreeHelper getTreeHelper(String tableName, Class clazz) { + TreeHelper helper = mapInstance.get(tableName); + if (helper == null) { + try { + helper = clazz.newInstance(); + mapInstance.put(tableName, helper); + } catch (Exception e) { + throw new SwException(e); + } + } + return helper; + } + + //先禁止外部创建 + protected TreeHelper(String tableName) { + this.tableName = tableName; + table = ModelTableCache.getInstance().getByName(tableName); + cache = CacheManager.getIntance().getCache(tableName); + dao = DbEngine.getInstance().findDao(tableName); + + ModelField field = table.findFieldByType(SwEnum.FieldType.PARENT_ID.value); + fieldParent = field.getName(); + field = table.findFieldByType(SwEnum.FieldType.LEVEL_CODE.value); + fieldLevelCode = field.getName(); + } + + public long getParentId(T bean) { + return bean.getLong(fieldParent); + } + + public String getLevelCode(T bean) { + return bean.getStr(fieldLevelCode); + } + + public Collection getChildren(T bean) { + return getChildren(bean.getEntityId()); + } + + public Collection getChildren(long id) { + return cache.getListByKey(SwConsts.KEY_PARENT_ID, String.valueOf(id)); + } + + public List getChildren(long id, Comparator comparator) { + Collection set = cache.getListByKey(SwConsts.KEY_PARENT_ID, String.valueOf(id)); + + List list = set == null ? new ArrayList<>(): new ArrayList<>(set); + if (comparator != null) + list.sort(comparator); + return list; + } + + public void checkParent(T bean) { + if (table.getType() != SwEnum.TableType.TYPE_TREE.value) return; + if (!table.isNeedCache()) throw new BizException("请将树型表定义为需要缓存!"); + long pId = getParentId(bean); + if (bean.getEntityId() == pId) throw new BizException("上级节点不能为自己!"); + if (pId <= 0) return; + T parent = cache.get(pId); + if (parent == null) return; + String plevelcode = SwConsts.SPLIT_CHAR + parent.getStr(fieldLevelCode) + SwConsts.SPLIT_CHAR; + if (plevelcode.contains(SwConsts.SPLIT_CHAR + bean.getEntityId() + SwConsts.SPLIT_CHAR)) { + throw new BizException("上级节点不能为自己的下级!"); + } + } + + public List resetTreeLevel(T bean) { + List list = new ArrayList<>(); + if (table.getType() != SwEnum.TableType.TYPE_TREE.value) return list; + if (!table.isNeedCache()) throw new BizException("请定义为需要缓存!"); + + T oldBean = cache.get(bean.getEntityId()); + if (bean.getLong(fieldParent) != oldBean.getLong(fieldParent)) { + resetParentChildren(bean, list); + } + return list; + } + + private void resetParentChildren(T bean, List list) { + T parent = cache.get(getParentId(bean)); + if (parent != null) { + bean.put(fieldLevelCode, getLevelCode(parent) + SwConsts.SPLIT_CHAR + parent.getEntityId()); + dao.updateEntity(bean, fieldLevelCode); + list.add(bean); + } + Collection children = getChildren(bean); + if (children != null && !children.isEmpty()) { + for (T child : children) { + resetParentChildren(child, list); + } + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/list/FooterField.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/list/FooterField.java new file mode 100644 index 0000000..2da36c6 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/list/FooterField.java @@ -0,0 +1,57 @@ +package cc.smtweb.framework.core.mvc.service.list; + +/** + * Created by Akmm at 13-4-16 上午10:51 + * 合计行列定义 + */ +public class FooterField { + //计数 不同值计数 + public static final String SUM_TYPE_COUNT = "COUNT"; + //计数 记录数 + public static final String SUM_TYPE_COUNT_ALL = "COUNT_A"; + //求和 + public static final String SUM_TYPE_SUM = "SUM"; + //整数求和 + public static final String SUM_TYPE_SUM_NUM = "SUM_NUM"; + //平均数 + public static final String SUM_TYPE_AVG = "AVG"; + //最大值 + public static final String SUM_TYPE_MAX = "MAX"; + //最小值 + public static final String SUM_TYPE_MIN = "MIN"; + //静态文本 + public static final String STATIC_TEXT = "TEXT"; + + public String field; + public String type; + public String text; + + public FooterField() { + } + + public FooterField(String field, String type, String text) { + this.field = field; + this.type = type; + this.text = text; + } + + public String toString() { + return "field=" + field + ";type=" + type + ";text=" + text; + } + + public static FooterField newSumField(String field) { + return new FooterField(field, SUM_TYPE_SUM, null); + } + + public static FooterField newCountField(String field) { + return new FooterField(field, SUM_TYPE_COUNT, null); + } + + public static FooterField newTextField(String field, String text) { + return new FooterField(field, STATIC_TEXT, text); + } + + public static FooterField newSumField(String field, String type) { + return new FooterField(field, type, null); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/ICalcVar.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/ICalcVar.java new file mode 100644 index 0000000..4a85ec9 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/ICalcVar.java @@ -0,0 +1,18 @@ +package cc.smtweb.framework.core.mvc.variable; + +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.session.UserSession; + +/** + * Created by Akmm at 2022/5/12 9:07 + * 计算并返回变量值 + */ +public interface ICalcVar { + /** + * 计算并返回变量值 + * @param params 参数 + * @param us 用户会话信息 + * @return + */ + Object calcVar(SwMap params, UserSession us); +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariable.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariable.java new file mode 100644 index 0000000..a952274 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariable.java @@ -0,0 +1,26 @@ +package cc.smtweb.framework.core.mvc.variable; + +import lombok.Data; + +/** + * Created by Akmm at 2022/5/12 9:11 + * 变量定义信息 + */ +@Data +public class SwVariable { + //变量名 + private String name; + //中文标题 + private String label; + //描述 + private String remark; + //计算值的方法 + private ICalcVar calcVar; + + public SwVariable(String name, String label, String remark, ICalcVar calcVar) { + this.name = name; + this.label = label; + this.remark = remark; + this.calcVar = calcVar; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariableFactory.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariableFactory.java new file mode 100644 index 0000000..dfbb34e --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariableFactory.java @@ -0,0 +1,45 @@ +package cc.smtweb.framework.core.mvc.variable; + +import cc.smtweb.framework.core.exception.BizException; +import cc.smtweb.framework.core.exception.SwException; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.framework.core.util.DateUtil; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Akmm at 2022/5/11 19:07 + * 变量工厂,变量的注册及计算 + */ +public class SwVariableFactory { + private static SwVariableFactory instance; + static { + instance = new SwVariableFactory(); + } + + public static SwVariableFactory getInstance() { + return instance; + } + + //记录变量信息 + private Map map = new HashMap<>(); + private SwVariableFactory() { + regVariable("SYS_DATE", "当前日期", "YYYYMMDD格式", (params, us) -> DateUtil.nowDateLong()); + regVariable("CUR_USER_ID", "当前操作员id", "当前操作员主键", (params, us) -> us.getUserId()); + } + + //注册变量 + public void regVariable(String name, String label, String remark, ICalcVar calcVar) { + if (map.containsKey(name)) throw new BizException("变量重复定义:name=" + name); + map.put(name, new SwVariable(name, label, remark, calcVar)); + } + + //计算变量值 + public Object calcVar(String name, SwMap params, UserSession us) { + SwVariable var = map.get(name); + if (var == null) throw new BizException("没有定义此变量:" + name); + return var.getCalcVar().calcVar(params, us); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionManager.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionManager.java new file mode 100644 index 0000000..b03e1c4 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionManager.java @@ -0,0 +1,73 @@ +package cc.smtweb.framework.core.session; + +import cc.smtweb.framework.core.cache.redis.RedisBroadcastEvent; +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.db.jdbc.IdGenerator; +import cc.smtweb.framework.core.mvc.controller.IEditor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +import java.util.Random; + +public class SessionManager { + private final RedisManager redisManager; + private final IdGenerator idGenerator; + + public SessionManager(RedisManager redisManager, IdGenerator idGenerator) { + this.redisManager = redisManager; + this.idGenerator = idGenerator; + } + + // 登录,产生session + public String login(UserSession userSession) { + if (userSession != null) { + String sid = RedisManager.PREFIX_SESSION + Long.toHexString(idGenerator.nextId()) + "_" + Integer.toHexString(new Random().nextInt()); + + redisManager.set(sid, userSession, RedisManager.SESSION_EXPIRE_SEC); + + return sid; + } + + return null; + } + + public void logout() { + String sid = (String)RequestContextHolder.currentRequestAttributes().getAttribute(IEditor.USER_TOKEN, RequestAttributes.SCOPE_REQUEST); + if (StringUtils.isNoneBlank(sid)) { + redisManager.del(sid); + } + } + + // token延时 + public boolean flush(String token) { + if (token != null) { + // 更新Token redis TTL + return redisManager.expire(token, RedisManager.SESSION_EXPIRE_SEC); + } + + return false; + } + + /** + * 清除指定用户权限本地缓存 + * @param userId 用户ID + */ + public void removePermits(long userId) { + RedisBroadcastEvent event = new RedisBroadcastEvent(); + event.setAction(RedisBroadcastEvent.CODE_REMOVE); + event.setIdent("ReamlCache"); + event.setKey(userId + ""); + redisManager.publish(event); + } + + /** + * 清除所有用户权限本地缓存 + */ + public void clearPermits() { + RedisBroadcastEvent event = new RedisBroadcastEvent(); + event.setAction(RedisBroadcastEvent.CODE_CLEAR); + event.setKey("ReamlCache"); + redisManager.publish(event); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java new file mode 100644 index 0000000..09e63a6 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java @@ -0,0 +1,109 @@ +package cc.smtweb.framework.core.session; + +import cc.smtweb.framework.core.cache.redis.RedisManager; +import cc.smtweb.framework.core.mvc.controller.IEditor; +import cc.smtweb.framework.core.mvc.realm.exception.UnauthenticatedException; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; + +import javax.servlet.http.HttpServletRequest; + +/** + * 〈session工具类〉 + * + * @author kevin + * @since 1.0.0 + */ +public class SessionUtil { + private SessionUtil() { + } + + public static Object getSession() { + return RequestContextHolder.currentRequestAttributes().getAttribute(IEditor.USER_SESSION, 0); + } + + public static String readToken(HttpServletRequest request) { + String token = request.getHeader("Auth-Token"); + + if (token == null) { + token = request.getParameter("auth_token"); + } + return token; + } + + public static UserSession checkSession(HttpServletRequest request, RedisManager redisManager) { + String token = readToken(request); + + if (StringUtils.isBlank(token)) { + throw new UnauthenticatedException("not find Auth-Token in header"); + } + + UserSession us = redisManager.get(token, UserSession.class); + if (us == null) { + throw new UnauthenticatedException("not find UserSession by token: " + token); + } + + return us; + } + + + public static UserSession checkSession(String accessToken, RedisManager redisManager) { + if (StringUtils.isBlank(accessToken)) { + throw new UnauthenticatedException("not find Auth-Token in header"); + } + + UserSession us = redisManager.get(accessToken, UserSession.class); + if (us == null) { + throw new UnauthenticatedException("not find UserSession by token: " + accessToken); + } + + return us; + } + +// private static Session getShiroSession() { +// Session session = SecurityUtils.getSubject().getSession(); +// if (session == null) { +// throw new SmartException(ExceptionMessage.NO_LOGIN_ERROR); +// } +// return session; +// } + +// public static String getSid() { +// return getShiroSession().getId().toString(); +// } + +// public static UserSession getSession() { +// Object session = getShiroSession().getAttribute(USER_SESSION); +// if (session == null) { +// throw new SmartException(ExceptionMessage.NO_LOGIN_ERROR); +// } +// UserSession userSession = (UserSession) session; +// if (userSession.isChange()) { +// throw new SmartException(ExceptionMessage.USER_PERMISSION_CHANGE); +// } +// return userSession; +// } +// +// public static void updateSession(UserSession userSession) { +// getShiroSession().setAttribute(USER_SESSION, userSession); +// } + +// public static String login(String userName, UserSession userSession) { +// // 通过 shiro 登录验证 +// Subject subject = SecurityUtils.getSubject(); +// try { +// // 统一默认密码登录 +// subject.login(new UsernamePasswordToken(userName, CommonUtil.INIT_PASSWORD)); +// } catch (ShiroException ex) { +// throw new SmartException(ExceptionMessage.USER_ERROR); +// } +// +// Session session = subject.getSession(); +// if (session == null) { +// throw new SmartException(ExceptionMessage.NO_LOGIN_ERROR); +// } +// +// session.setAttribute(USER_SESSION, userSession); +// return session.getId().toString(); +// } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/UserSessionArgumentResolver.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/UserSessionArgumentResolver.java new file mode 100644 index 0000000..fc9e21c --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/UserSessionArgumentResolver.java @@ -0,0 +1,26 @@ +package cc.smtweb.framework.core.session; + +import cc.smtweb.framework.core.mvc.controller.IEditor; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +/** + * spring 参数拦截器,提供UserSession在@Service的函数参数中@Param使用 + * @author kevin + */ +public class UserSessionArgumentResolver implements HandlerMethodArgumentResolver { + @Override + public boolean supportsParameter(MethodParameter methodParameter) { + return methodParameter.getParameterType().isAssignableFrom(UserSession.class); + } + + @Override + public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { + return nativeWebRequest.getAttribute(IEditor.USER_SESSION, RequestAttributes.SCOPE_REQUEST); +// return SessionUtil.getSession(); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysTaskManager.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysTaskManager.java new file mode 100644 index 0000000..2a5a5c1 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysTaskManager.java @@ -0,0 +1,40 @@ +package cc.smtweb.framework.core.systask; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class SysTaskManager { + @Autowired + private ApplicationContext applicationContext; + + private List tasks = new ArrayList<>(); + + public void add(ISysTask task) { + tasks.add(task); + } + + @EventListener + public void onTaskStartEvent(TaskStartEvent event) { + runAll(); + } + + // 每隔60秒定时执行 +// @Scheduled(fixedRate = 60000) +// public void fixedRateJob() { +// System.out.println("fixedRate 每隔60秒" + new java.util.Date()); +// +// runAll(); +// } + + private void runAll() { + for (ISysTask task : tasks) { + task.run(); + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/WebStartedEvent.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/WebStartedEvent.java new file mode 100644 index 0000000..cd8bba0 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/WebStartedEvent.java @@ -0,0 +1,4 @@ +package cc.smtweb.framework.core.systask; + +public class WebStartedEvent { +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/CommUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/CommUtil.java new file mode 100644 index 0000000..f616640 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/CommUtil.java @@ -0,0 +1,140 @@ +package cc.smtweb.framework.core.util; + +import cc.smtweb.framework.core.db.impl.BaseBean; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.util.kryo.KryoTool; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; +import java.text.Collator; +import java.util.Collection; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +/** + * Created by Akmm at 2022/1/5 9:10 + * 通用工具类 + */ +@Slf4j +public class CommUtil { + private static Collator chineseCollator = Collator.getInstance(Locale.CHINA); + + /** + * 找指定类的泛型类 + * @param cls + * @param + * @return + */ + public static Class getParameterizedType(Class cls) { + while (cls != null) { //找到泛型类 + Type pt = cls.getGenericSuperclass(); + if (pt instanceof ParameterizedType) { + return (Class) ((ParameterizedType) pt).getActualTypeArguments()[0]; + } + cls = (Class) pt; + } + return null; + } + + /** + * 序列化对象 + * @param obj + * @param + * @return + */ + public static byte[] writeObject(T obj) { + return KryoTool.getINST().writeObject(obj); + } + + /** + * 反序列化 + * @param data + * @param clazz + * @param + * @return + */ + public static T readObject(byte[] data, Class clazz) { + return KryoTool.getINST().readObject(data, clazz); + } + + public static T cloneObj(T obj, Class cls) { + byte[] data = writeObject(obj); + return readObject(data, cls); + } + + public static boolean isEmpty(Collection c) { + return c == null || c.isEmpty(); + } + + /** + * 从DefaultEntity实体转成自己的对象类 + * @param bean + * @param clazz + * @param + * @return + */ + public static T castEntity(DefaultEntity bean, Class clazz) { + try { + T ret = clazz.newInstance(); + ret.getData().putAll(bean.getData()); + return ret; + } catch (Exception e) { + log.error("转换bean失败:", e); + return null; + } + } + + /*public static String getSqlInIds(Collection ids) { + if (null == ids || ids.isEmpty()) return ""; + StringBuilder s = new StringBuilder(128); + Set set = new HashSet<>(); + for (String id : ids) { + if (set.contains(id)) continue; + set.add(id); + if (StringUtils.isEmpty(id)) continue; + s.append(id).append(","); + } + if (s.length() == 0) return ""; + return s.substring(0, s.length() - 1); + }*/ + + public static String getSqlInIds(Collection ids) { + if (null == ids || ids.isEmpty()) return ""; + StringBuilder s = new StringBuilder(128); + Set set = new HashSet<>(); + for (Long id : ids) { + if (set.contains(id)) continue; + set.add(id); + if (id <= 0) continue; + s.append(id).append(","); + } + if (s.length() == 0) return ""; + return s.substring(0, s.length() - 1); + } + + //中文字符串比较 + public static int chineseCompare(String s1, String s2) { + return chineseCollator.compare(s1, s2); + } + public static int compareStr(String s1, String s2) { + if (StringUtils.isEmpty(s1) && StringUtils.isEmpty(s2)) return 0; + if (StringUtils.isEmpty(s1)) return -1; + if (StringUtils.isEmpty(s2)) return 1; + return chineseCollator.compare(s1, s2); + } + + public static boolean isStrEquals(String s1, String s2) { + return compareStr(s1, s2) == 0; + } + + //获取字段字符串长度 + public static int getStrLenB(String s) { + if (StringUtils.isEmpty(s)) return 0; + return s.getBytes(StandardCharsets.UTF_8).length; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/IpAddrUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/IpAddrUtil.java new file mode 100644 index 0000000..9ba2642 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/IpAddrUtil.java @@ -0,0 +1,101 @@ +package cc.smtweb.framework.core.util; + +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 〈IP〉工具类 + * + * @author kevin + * @since 1.0.0 + */ +public class IpAddrUtil { + + private IpAddrUtil() { + } + + //指定字符串是否工具类 + public static boolean isIpAddress(String ipAddr) { + if (StringUtils.isEmpty(ipAddr)) { + return false; + } else { + String regTxt = + "\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b"; + return regMatch(ipAddr, regTxt); + } + } + + //正则匹配校验 + private static boolean regMatch(String source, String regTxt) { + Pattern pattern = Pattern.compile(regTxt); + Matcher matcher = pattern.matcher(source); + return matcher.matches(); + } + + //ip转long + public static long ip2Long(String ipAddr) { + long[] ip = new long[4]; + int position1 = ipAddr.indexOf("."); + int position2 = ipAddr.indexOf(".", position1 + 1); + int position3 = ipAddr.indexOf(".", position2 + 1); + ip[0] = Long.parseLong(ipAddr.substring(0, position1)); + ip[1] = Long.parseLong(ipAddr.substring(position1 + 1, position2)); + ip[2] = Long.parseLong(ipAddr.substring(position2 + 1, position3)); + ip[3] = Long.parseLong(ipAddr.substring(position3 + 1)); + return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]; + } + + //long转ip格式 + public static String long2IP(long ipAddr) { + return (ipAddr >>> 24) + + "." + + ((ipAddr & 16777215L) >>> 16) + + "." + + ((ipAddr & 65535L) >>> 8) + + "." + + (ipAddr & 255L); + } + + //获取当前请求ip,返回long格式 + public static long getLongIp(HttpServletRequest request) { + try { + String ipAddr = getIpAddr(request); + return StringUtils.isBlank(ipAddr) ? 0L : ip2Long(ipAddr); + } catch (Exception var2) { + return 0L; + } + } + + //获取当前请求的ip,返回ip格式 + public static String getIpAddr(HttpServletRequest request) { + if (request == null) { + return ""; + } else { + String ip = request.getHeader("X-Forwarded-For"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + + return ip; + } + } +} \ No newline at end of file diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/JsonUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/JsonUtil.java new file mode 100644 index 0000000..d049d96 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/JsonUtil.java @@ -0,0 +1,296 @@ +package cc.smtweb.framework.core.util; + +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.exception.JsonParseException; +import cc.smtweb.framework.core.util.jackson.*; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.ser.FilterProvider; +import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; +import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; + +import java.beans.PropertyDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.sql.Timestamp; +import java.util.*; + +import static org.springframework.beans.BeanUtils.getPropertyDescriptors; + +/** + * json工具类 + */ +@Slf4j +public class JsonUtil { + public final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + public final static ObjectMapper API_OBJECT_MAPPER = new ObjectMapper(); + + static { + init(OBJECT_MAPPER); + // 不序列化空值 + OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); +// OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); +// OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); +// // 设置将MAP转换为JSON时候只转换值不等于NULL的 +// objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); + + init(API_OBJECT_MAPPER); + API_OBJECT_MAPPER.getSerializerProvider().setNullValueSerializer(new NullSerializer()); + + FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.serializeAllExcept(new HashSet<>())); + } + + private static void init(ObjectMapper mapper) { + // JSON转化为对象时忽略未对应的属性 + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + SimpleModule module = new SimpleModule(); + LongSerializer longSerializer = new LongSerializer(); + module.addSerializer(Long.class, longSerializer); + module.addSerializer(Long.TYPE, longSerializer); + + DateSerializer dateSerializer = new DateSerializer(); + module.addSerializer(java.sql.Date.class, dateSerializer); + TimeSerializer timeSerializer = new TimeSerializer(); + module.addSerializer(java.sql.Time.class, timeSerializer); +// module.addSerializer(BaseBean.class, new BaseBeanSerializer()); + + module.addDeserializer(Timestamp.class, new TimestampDeserializer()); + module.addDeserializer(java.util.Date.class, new DateDeserializer()); + + mapper.registerModule(module); + mapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); + } + + public static JsonNode readTree(String body) { + try { + return OBJECT_MAPPER.readTree(body); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + + return null; + } + + // 创建新节点 + public static ObjectNode createObjectNode() { + return OBJECT_MAPPER.createObjectNode(); + } + + // 将 JsonNode 对象转成 json + public static String writeValueAsString(JsonNode newNode) { + try { + return OBJECT_MAPPER.writeValueAsString(newNode); + } catch (JsonProcessingException e) { + log.error(e.getMessage(), e); + } + + return null; + } + + public static T parse(String str, Class clazz) { + try { + if (StringUtils.isBlank(str)) { + return null; + } else { + return OBJECT_MAPPER.readValue(str, clazz); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to " + clazz + " type", e); + } + } + + /** + * 将Map对象转换为Bean对象 + * + * @param map Map对象 + * @param clazz Bean对象类 + * @param Bean对象类型 + * @return Bean对象实例 + */ + public static T parse(Map map, Class clazz) { + try { + if (map == null || map.isEmpty()) { + return null; + } else { + // 对象实例化 + T bean = BeanUtils.instantiateClass(clazz); + if (SwMap.class.isAssignableFrom(clazz)) { + ((SwMap) bean).putAll(map); + } else { + // 循环设置对象属性 + PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz); + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + String properName = propertyDescriptor.getName(); + // 过滤class属性 + if (!"class".equals(properName)) { + if (map.containsKey(properName)) { + Method writeMethod = propertyDescriptor.getWriteMethod(); + if (writeMethod != null) { + Object value = map.get(properName); + if (!writeMethod.isAccessible()) { + writeMethod.setAccessible(true); + } + writeMethod.invoke(bean, value); + } + } + } + } + } + + return bean; + } + } catch (Exception e) { + throw new JsonParseException("can't convert map to " + clazz + " type", e); + } + } + + public static T parse(InputStream is, Class clazz) { + try { + if (is == null) { + return null; + } else { + return OBJECT_MAPPER.readValue(is, clazz); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to " + clazz + " type", e); + } + } + + public static T parse(byte[] str, Class clazz) { + try { + if (str == null || str.length == 0) { + return null; + } else { + return OBJECT_MAPPER.readValue(str, clazz); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to " + clazz + " type", e); + } + } + + public static JsonNode parse(String str) { + try { + if (StringUtils.isBlank(str)) { + return null; + } else { + return OBJECT_MAPPER.readTree(str); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to JsonNode", e); + } + } + + /** + * 转换json文本为对象列表 + * + * @param is json文本流 + * @param 列表中对象类 + * @param clazz 列表中的对象类 + * @return 列表对象 + */ + public static List parseList(InputStream is, Class clazz) { + try { + if (is == null) { + return null; + } else { + JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); + return OBJECT_MAPPER.readValue(is, javaType); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to list type", e); + } + } + + /** + * 转换json文本为对象列表 + * + * @param str json文本字节数组 + * @param 列表中对象类 + * @param clazz 列表中的对象类 + * @return 列表对象 + */ + public static List parseList(byte[] str, Class clazz) { + try { + if (str == null || str.length == 0) { + return null; + } else { + JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); + return OBJECT_MAPPER.readValue(str, javaType); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to list type", e); + } + } + + /** + * 转换json文本为对象列表 + * + * @param str json文本 + * @param 列表中对象类 + * @param clazz 列表中的对象类 + * @return 列表对象 + */ + public static List parseList(String str, Class clazz) { + try { + if (StringUtils.isBlank(str)) { + return null; + } else { + JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); + return OBJECT_MAPPER.readValue(str, javaType); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to list<" + clazz.getSimpleName() + "> type", e); + } + } + + public static Map parseMap(String str) { + try { + if (StringUtils.isBlank(str)) { + return null; + } else { + return OBJECT_MAPPER.readValue(str, Map.class); + } + } catch (Exception e) { + throw new JsonParseException("can't convert this json to Map type", e); + } + } + + public static String encodeString(Object obj) { + try { + return OBJECT_MAPPER.writeValueAsString(obj); + } catch (JsonProcessingException e) { + throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); + } + } + + public static byte[] encodeBytes(Object obj) { + try { + return OBJECT_MAPPER.writeValueAsBytes(obj); + } catch (JsonProcessingException e) { + throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); + } + } + + public static SwMap bean2Map(Object obj) { + return parse(encodeString(obj), SwMap.class); + } + + public static List bean2MapList(Object obj) { + List list = new ArrayList<>(); + SwMap[] arr = parse(encodeString(obj), SwMap[].class); + Collections.addAll(list, arr); + return list; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/NumberUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/NumberUtil.java new file mode 100644 index 0000000..0d6cd8e --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/NumberUtil.java @@ -0,0 +1,621 @@ +package cc.smtweb.framework.core.util; + +import org.apache.commons.jexl3.JexlBuilder; +import org.apache.commons.jexl3.JexlContext; +import org.apache.commons.jexl3.JexlExpression; +import org.apache.commons.jexl3.MapContext; +import org.apache.commons.lang3.StringUtils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.util.Map; + +public class NumberUtil { + private NumberUtil() {} + + //整数 + private static DecimalFormat dfLng = new DecimalFormat("##############0"); + private static DecimalFormat dfLong = new DecimalFormat("###,###,###,###,##0"); + //一位小数 + private static DecimalFormat df1 = new DecimalFormat("##############0.0"); + private static DecimalFormat df1Format = new DecimalFormat("###,###,###,###,##0.0"); + //两位小数 + private static DecimalFormat df2 = new DecimalFormat("##############0.00"); + private static DecimalFormat df2Format = new DecimalFormat("###,###,###,###,##0.00"); + //四位小数 + private static DecimalFormat df4 = new DecimalFormat("###,###,###,###,##0.0000"); + //六位小数 + private static DecimalFormat df6Number = new DecimalFormat("#######################0.000000"); + private static DecimalFormat df6NumberF = new DecimalFormat("#,###,###,###,###,###,##0.000000"); + + public final static DecimalFormat stdAmountFormat = new DecimalFormat("###,###,###,###,##0.00"); + public final static DecimalFormat stdNumberFormat = new DecimalFormat("#0.00"); + public final static String DEF_NUM_TEN_THOUSAND = "10000";//万 + public static final double MAX_VALUE = 9999999999999.99D; + public static final double MIN_VALUE = -9999999999999.99D; + + private final static BigDecimal ONE_BIG = new BigDecimal(1.00D); + private static final String UNIT = "万仟佰拾亿仟佰拾万仟佰拾元角分"; + private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖"; + + /** + * 4舍5入double,2位小数 + */ + public static double roundDouble(double src) { + return roundDouble(src, 2); + } + + /** + * 4舍5入double,N 位小数 + * + * @param src + * @param scale 小数位数 + * @return + */ + public static double roundDouble(Object src, int scale) { + if (src == null) return 0.0; + String v = src.toString(); + if (StringUtils.isEmpty(v)) return 0.0; + if (scale < 0) scale = 2; + + BigDecimal src_b = new BigDecimal(v); + BigDecimal src_v = src_b.divide(ONE_BIG, scale + 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 + src_v = src_v.divide(ONE_BIG, scale, BigDecimal.ROUND_HALF_UP);// 4舍5入 + return src_v.doubleValue(); + } + + /** + * 舍位处理,原生floor有坑,部分浮点数记录为.99999999999形式,导致floor结果错误 + * + * @param d + * @return + */ + public static double floor(double d) { + return Math.floor(roundDouble(d, 2)); + } + + /** + * 比较两Double是否相等,将会吧他们专程BigDecimal进行比较; + * + * @param src double1 + * @param tag double2 + * @return src > tag 返回1, src < tag 返回-1, 否则返回0 + */ + public static int compare(double src, double tag) { + BigDecimal src_b = new BigDecimal(src); + BigDecimal src_v = src_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 + + BigDecimal tag_b = new BigDecimal(tag); + BigDecimal tag_v = tag_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 + + return src_v.compareTo(tag_v); + } + + /** + * 自动过滤金额中的逗号转换为double,如果出错,则返回0 + * + * @param s 源串,可能为带逗号的金额串; + * @return double + */ + public static Double toDouble(String s) { + return todouble(s); + } + + /** + * 自动过滤金额中的逗号转换为double,如果出错,则返回0 + * + * @param s 源串,可能为带逗号的金额串; + * @return double + */ + public static double todouble(String s) { + try { + return Double.parseDouble(s.replaceAll(",", "")); + } catch (Exception e) { + return 0.00; + } + } + + /** + * 获取double,主要过滤d为null的情况; + * + * @param d Double对象; + * @return double + */ + public static double todouble(Double d) { + if (d == null) return 0.0d; + return d.doubleValue(); + } + + /** + * 自动过滤金额中的逗号转换为float,如果出错,则返回0 + * + * @param s 源串,可能为带逗号的金额串; + * @return Float + */ + public static Float toFloat(String s) { + return tofloat(s); + } + + /** + * 自动过滤金额中的逗号转换为float,如果出错,则返回0 + * + * @param s 源串,可能为带逗号的金额串; + * @return Float + */ + public static float tofloat(String s) { + try { + return Float.parseFloat(s.replaceAll(",", "")); + } catch (Exception e) { + return 0.0f; + } + } + + public static long tolong(String src, long defaultvalue) { + try { + return Long.parseLong(src); + } catch (Exception e) { + return defaultvalue; + } + } + + public static int toint(String src, int defaultvalue) { + try { + return Integer.parseInt(src); + } catch (Exception e) { + return defaultvalue; + } + } + + /** + * 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001 + * + * @param value double类型 + * @return boolean + */ + public static boolean isBigThanZero(double value) { + return (value > 0.00001); + } + + /** + * 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001 + * + * @param value String类型 + * @return boolean + */ + public static boolean isBigThanZero(String value) { + return !StringUtils.isEmpty(value) && isBigThanZero(toDouble(value)); + } + + /** + * 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。 + * + * @param value double类型 + * @return boolean + */ + public static boolean isEqualsZero(double value) { + return (-0.00001 < value && value < 0.00001); + } + + /** + * 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。 + * + * @param value String类型 + * @return boolean + */ + public static boolean isEqualsZero(String value) { + return StringUtils.isEmpty(value) || isEqualsZero(toDouble(value)); + } + + /** + * 是否是负数 + * + * @param db_val 要判断的double + * @return 负数则返回true; + */ + public static boolean isNegative(double db_val) { + return (compare(db_val, 0.00D) == -1); + } + + /** + * 是否是正数 + * + * @param db_val 要判断的double + * @return 正数则返回true; + */ + public static boolean isPlus(double db_val) { + return (compare(db_val, 0.00D) == 1); + } + + /** + * 得到金额字符串,保持小数点2位 + * + * @param db 将double转换为金额字符串; + * @return 金额字符串#0.00; + */ + public static String toStdNumberString(double db) { + try { + return stdNumberFormat.format(db); + } catch (Exception e) { + return "0.00"; + } + } + + public static String toStdNumberStringEx(double db) { + try { + if (compare(db, -1d) == 0) return "-"; + return stdNumberFormat.format(db); + } catch (Exception e) { + return "0.00"; + } + } + + /** + * 将金额格式字符串,如23,333,093.01 去掉逗号 + * + * @param s 金额串 + * @return String 去掉逗号后的串,如果amount为空,则返回0.00 + */ + public static String toStdNumberString(String s) { + if (StringUtils.isEmpty(s)) + return "0.00"; + return stdNumberFormat.format(todouble(s)); + } + + /** + * 将数据转换为两位小数的数字格式; + * + * @param d 数据 + * @param isZeroToEmpty 如果未0,是否返回“”; + * @return 两位小数的字符串; + */ + public static String toStdNumberString(double d, boolean isZeroToEmpty) { + if (isEqualsZero(d)) { + return isZeroToEmpty ? "" : "0.00"; + } + return stdNumberFormat.format(d); + } + + public static String toStdNumberString(String s, boolean isZeroToEmpty) { + return toStdNumberString(todouble(s), isZeroToEmpty); + } + + public static String toStdNumberString(double d, int scale) { + DecimalFormat dfn = null; + if (scale == 1) dfn = df1Format; + if (scale == 2) dfn = df2Format; + else if (scale == 4) dfn = df4; + else if (scale == 6) dfn = df6NumberF; + else if (scale <= 0) dfn = dfLong; + else { + StringBuilder sb = new StringBuilder("###,###,###,###,##0."); + for (int i = 0; i < scale; i++) sb.append("0"); + dfn = new DecimalFormat(sb.toString()); + } + return dfn.format(d); + } + + /** + * 将数字乘100,保留小数点后两位, 然后后面添加% + * + * @param d 值 + * @param isZeroToEmpty,如果值为0,是否返回空; + * @return 字符串; + */ + public static String toStdPercentNumberStr(double d, boolean isZeroToEmpty) { + if (d > -0.00000000001 && d < 0.00000000001) { + return isZeroToEmpty ? "" : "0.00%"; + } + return toStdNumberString(d * 100) + "%"; + } + + + public static String toStdAmountString(double d) { + return toStdAmountString(d, false); + } + + /** + * 将数据转换为两位小数的金额格式,带逗号; + * + * @param d 数据 + * @param isZeroToEmpty 如果未0,是否返回“”; + * @return 金额格式的字符串; + */ + public static String toStdAmountString(double d, boolean isZeroToEmpty) { + if (isEqualsZero(d)) { + return isZeroToEmpty ? "" : "0.00"; + } + return stdAmountFormat.format(d); + } + + public static String toStdAmountString(String s) { + return toStdAmountString(todouble(s), false); + } + + public static String toStdAmountString(String s, boolean isZeroToEmpty) { + return toStdAmountString(todouble(s), isZeroToEmpty); + } + + + /** + * 将小写金额转换为人民币大写金额 + * + * @param s 金额格式的串 + * @return String 转换结果 + */ + public static String toCapsAmountString(String s) { + if (StringUtils.isEmpty(s)) return ""; + return toCapsAmountString(todouble(s)); + } + + /** + * 将小写金额转换为人民币大写金额 + * + * @param v double + * @return String 转换结果 + */ + public static String toCapsAmountString(double v) { + if (v < MIN_VALUE || v > MAX_VALUE) return "参数非法!"; + + boolean negative = isNegative(v); + + if (negative) v = Math.abs(v); + long l = Math.round(v * 100); + if (l == 0) return "零元整"; + + String strValue = String.valueOf(l); + // i用来控制数 + int i = 0; + // j用来控制单位 + int j = UNIT.length() - strValue.length(); + StringBuilder rs = new StringBuilder(32); + boolean isZero = false; + for (; i < strValue.length(); i++, j++) { + char ch = strValue.charAt(i); + if (ch == '0') { + isZero = true; + if (UNIT.charAt(j) == '亿' || UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元') { + rs.append(UNIT.charAt(j)); + isZero = false; + } + } else { + if (isZero) { + rs.append('零'); + isZero = false; + } + rs.append(DIGIT.charAt(ch - '0')).append(UNIT.charAt(j)); + } + } + if (rs.charAt(rs.length() - 1) != '分') + rs.append('整'); + + i = rs.indexOf("亿万"); + if (i > 0) rs.delete(i + 1, i + 2); // i+1 ->万 + + if (negative) + return rs.insert(0, '负').toString(); + else + return rs.toString(); + } + + /** + * 返回0 到 maxvalue的随机数 + * + * @param maxvalue 随机数的最大值 + * @return int + */ + public static int rnd(int maxvalue) { + return (int) (Math.random() * (maxvalue + 1)); + } + + + public static double chkDbNull(Double v) { + return v == null ? 0 : v; + } + + public static double max(double d1, double d2) { + return compare(d1, d2) < 0 ? d2 : d1; + } + + public static double min(double d1, double d2) { + return compare(d1, d2) < 0 ? d1 : d2; + } + + /** + * 获取浮点数(有错误默认为0),可以识别金额中的逗号格式 + * + * @param str 带转换的字符串 + * @return 浮点数 + */ + public static double getDoubleIgnoreErr(String str) { + if (str == null) + return 0.0; + str = str.trim(); + if (str.equals("")) + return 0.0; + str = str.replaceAll(",", "").replaceAll(",", ""); + try { + return Double.valueOf(str); + } catch (Exception e) { + return 0.0; + } + } + + public static int getIntIgnoreErr(String str) { + if (StringUtils.isEmpty(str)) + return 0; + str = str.replaceAll(",", "").replaceAll(",", ""); + if (str.contains(".")) + str = str.substring(0, str.indexOf('.')); + try { + return Integer.valueOf(str); + } catch (Exception e) { + return 0; + } + } + + public static long getLongIgnoreErr(String str) { + if (StringUtils.isEmpty(str)) + return 0L; + str = str.replaceAll(",", "").replaceAll(",", ""); + try { + return Long.valueOf(str); + } catch (Exception e) { + return 0L; + } + } + + /** + * 计算公式 参数以Map方式传入 + * + * @param expr 表达式 + * @param mapVar 变量 + * @return 计算结果 + */ + public static Object calcExprMapObject(String expr, Map mapVar) { + if (StringUtils.isEmpty(expr)) return ""; + JexlContext jc = new MapContext(); + for (String k : mapVar.keySet()) jc.set(k, mapVar.get(k)); + JexlExpression e = new JexlBuilder().create().createExpression(expr); + return e.evaluate(jc); + } + + /** + * 计算公式,参数以数组方式传入,key、value交替 + * + * @param expr 表达式 + * @param vars 变量 + * @return + */ + public static Object calcExprObjectEx(String expr, Object... vars) { + if (StringUtils.isEmpty(expr)) return ""; + JexlContext jc = new MapContext(); + for (int i = 0, len = vars.length; i < len; ) { + jc.set((String) vars[i++], vars[i++]); + } + JexlExpression e = new JexlBuilder().create().createExpression(expr); + return e.evaluate(jc); + } + + public static double calcExprMapDouble(String expr, Map mapVar) { + Object o = calcExprMapObject(expr, mapVar); + if (o != null) return getDoubleIgnoreErr(o.toString()); + return 0.0; + } + + public static double calcExprDoubleEx(String expr, Object... vars) { + Object o = calcExprObjectEx(expr, vars); + if (o != null) return getDoubleIgnoreErr(o.toString()); + return 0.0; + } + + public static int calcExprMapInt(String expr, Map mapVar) { + Object o = calcExprMapObject(expr, mapVar); + if (o != null) return getIntIgnoreErr(o.toString()); + return 0; + } + + public static int calcExprIntEx(String expr, Object... vars) { + Object o = calcExprObjectEx(expr, vars); + if (o != null) return getIntIgnoreErr(o.toString()); + return 0; + } + + public static boolean calcExprMapBool(String expr, Map mapVar) { + Object o = calcExprMapObject(expr, mapVar); + if (o != null) return (Boolean)o; + return false; + } + + public static boolean calcExprBoolEx(String expr, Object... vars) { + Object o = calcExprObjectEx(expr, vars); + if (o != null) return (Boolean)o; + return false; + } + +/* + public static Object calcExprObjectJ(String expr, Object... vars) throws Exception{ + if (StringUtils.isEmpty(expr)) return ""; + ExpressionEvaluator ee = new ExpressionEvaluator(); + ee.setExpressionType(int.class); + ee.setParameters(new String[]{"a", "b", "c"}, new Class[]{int.class, int.class, String.class}); + ee.cook(expr); + return ee.evaluate(vars); + } +*/ + + public static void main(String[] args) throws Exception{ + /*long t = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + System.out.print(calcExprIntEx("\"add\".equals(c) ? a + b : a - b", "a", 5, "b", 2, "c", "t")); + } + System.out.println(); + System.out.println(System.currentTimeMillis() - t); +// System.out.println(calcExprBoolEx("1==2")); + + t = System.currentTimeMillis(); + for (int i = 0; i < 10000; i++) { + System.out.print(calcExprObjectJ("\"add\".equals(c) ? a + b : a - b", 5, 2, "t")); + } + System.out.println(); + System.out.println(System.currentTimeMillis() - t);*/ + } + + /** + * double 去尾法 + * + * @param src 待处理数据 + * @param scale 保留小数位数 + * @return + */ + public static double cutDouble(double src, int scale) { + String v = toStdNumberString(src, 6);//先到6位小数,再去计算,否则容易出错,如8.3成8.29999999999,舍位就成了8.29了 + DecimalFormat formater = new DecimalFormat(); + formater.setMaximumFractionDigits(scale); + formater.setGroupingSize(0); + formater.setRoundingMode(RoundingMode.FLOOR); + return new BigDecimal(formater.format(toDouble(v))).doubleValue(); + } + + /** + * double 进位法 + * + * @param src 待处理数据 + * @param scale 保留小数位数 + * @return + */ + public static double upDouble(double src, int scale) { + String v = toStdNumberString(src, 6);//先到6位小数,再去计算 + DecimalFormat formater = new DecimalFormat(); + formater.setMaximumFractionDigits(scale); + formater.setGroupingSize(0); + formater.setRoundingMode(RoundingMode.UP); + return new BigDecimal(formater.format(toDouble(v))).doubleValue(); + } + + public static byte[] longToBytes(long l) { + byte[] result = new byte[8]; + for (int i = 7; i >= 0; i--) { + result[i] = (byte) (l & 0xFF); + l >>= 8; + } + return result; + } + + public static long bytesToLong(byte[] b) { + long result = 0; + for (int i = 0; i < 8; i++) { + result <<= 8; + result |= (b[i] & 0xFF); + } + return result; + } + + public static boolean longEquals(Long l1, Long l2) { + if (l1 != null) { + return l1.equals(l2); + } + + return l2 == null; + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/SpringUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/SpringUtil.java new file mode 100644 index 0000000..7063c85 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/SpringUtil.java @@ -0,0 +1,42 @@ +package cc.smtweb.framework.core.util; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * @Author: tanghp + * @Date: 2021-07-28 11:00 + * @Desc: + */ +@Component +public class SpringUtil implements ApplicationContextAware { + private static ApplicationContext applicationContext; + + public SpringUtil() { + } + + public void setApplicationContext(ApplicationContext applicationContext) { + if (SpringUtil.applicationContext == null) { + SpringUtil.applicationContext = applicationContext; + } + + } + + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + public static T getBean(String name) { + return (T)applicationContext.getBean(name); + } + + public static T getBean(Class clazz) { + return applicationContext.getBean(clazz); + } + + public static T getBean(String name, Class clazz) { + return applicationContext.getBean(name, clazz); + } +} + diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/VariableUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/VariableUtil.java new file mode 100644 index 0000000..a425403 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/VariableUtil.java @@ -0,0 +1,65 @@ +package cc.smtweb.framework.core.util; + +/** + * 变量命名规则工具类 + */ +public class VariableUtil { + private VariableUtil() {} + + /*** + * 下划线命名转为驼峰命名 + * + * @param para + * 下划线命名的字符串 + */ + public static String underlineToHump(String para){ + StringBuilder result = new StringBuilder(); + String[] a = para.split("_"); + for(String s:a){ + if(result.length()==0){ + result.append(s.toLowerCase()); + }else{ + result.append(s.substring(0, 1).toUpperCase()); + result.append(s.substring(1).toLowerCase()); + } + } + return result.toString(); + } + + /*** + * 下划线命名转为大写驼峰命名 + * 大驼峰式命名法(upper camel case) + * + * @param para + * 下划线命名的字符串 + */ + public static String underlineToUpperHump(String para){ + StringBuilder result=new StringBuilder(); + String[] a = para.split("_"); + for(String s : a){ + result.append(s.substring(0, 1).toUpperCase()); + result.append(s.substring(1).toLowerCase()); + } + return result.toString(); + } + + + /*** + * 驼峰命名转为下划线命名 + * + * @param para + * 驼峰命名的字符串 + */ + public static String humpToUnderline(String para){ + StringBuilder sb = new StringBuilder(para); + //偏移量,第i个下划线的位置是 当前的位置+ 偏移量(i-1),第一个下划线偏移量是0 + int temp = 0; + for(int i = 0; i { + + @Override + public void serialize(BaseBean value, JsonGenerator gen, + SerializerProvider serializers) throws IOException, + JsonProcessingException { + if (value == null) { + gen.writeNull(); + } else { + gen.writeObject(value.getData()); + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/DateDeserializer.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/DateDeserializer.java new file mode 100644 index 0000000..7fe37eb --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/DateDeserializer.java @@ -0,0 +1,30 @@ +package cc.smtweb.framework.core.util.jackson; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateDeserializer extends JsonDeserializer { + @Override + public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + if (jsonParser != null && StringUtils.isNotEmpty(jsonParser.getText())) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + try { + return dateFormat.parse(jsonParser.getText()); + } catch (ParseException e) { + throw new InvalidFormatException(jsonParser, e.getMessage(), jsonParser.getText(), Long.class); + } + } else { + return null; + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/LongDeserializer.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/LongDeserializer.java new file mode 100644 index 0000000..ed8225b --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/LongDeserializer.java @@ -0,0 +1,25 @@ +package cc.smtweb.framework.core.util.jackson; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; + +public class LongDeserializer extends JsonDeserializer { + @Override + public Long deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + if (jsonParser != null && StringUtils.isNotBlank(jsonParser.getText())) { + try { + return Long.valueOf(jsonParser.getText()); + } catch (NumberFormatException e) { + throw new InvalidFormatException(jsonParser, e.getMessage(), jsonParser.getText(), Long.class); + } + } else { + return null; + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/LongSerializer.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/LongSerializer.java new file mode 100644 index 0000000..d48d678 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/LongSerializer.java @@ -0,0 +1,19 @@ +package cc.smtweb.framework.core.util.jackson; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +public class LongSerializer extends JsonSerializer { + + @Override + public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + if (value == null) { + gen.writeNull(); + } else { + gen.writeString(String.valueOf(value)); + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/NullSerializer.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/NullSerializer.java new file mode 100644 index 0000000..1c57c81 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/NullSerializer.java @@ -0,0 +1,15 @@ +package cc.smtweb.framework.core.util.jackson; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +public class NullSerializer extends JsonSerializer { + @Override + public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) + throws IOException { + jgen.writeString(""); + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/TimestampDeserializer.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/TimestampDeserializer.java new file mode 100644 index 0000000..fb1a3a0 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/jackson/TimestampDeserializer.java @@ -0,0 +1,29 @@ +package cc.smtweb.framework.core.util.jackson; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.exc.InvalidFormatException; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public class TimestampDeserializer extends JsonDeserializer { + @Override + public Timestamp deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + if (jsonParser != null && StringUtils.isNotEmpty(jsonParser.getText())) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + try { + return new Timestamp(dateFormat.parse(jsonParser.getText()).getTime()); + } catch (ParseException e) { + throw new InvalidFormatException(jsonParser, e.getMessage(), jsonParser.getText(), Long.class); + } + } else { + return null; + } + } +} diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/kryo/KryoTool.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/kryo/KryoTool.java new file mode 100644 index 0000000..f444964 --- /dev/null +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/util/kryo/KryoTool.java @@ -0,0 +1,78 @@ +package cc.smtweb.framework.core.util.kryo; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import com.esotericsoftware.kryo.pool.KryoFactory; +import com.esotericsoftware.kryo.pool.KryoPool; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Serializable; + +/** + * 序列化工具类,单例 + */ +public class KryoTool { + private static KryoTool INST; + + static { + INST = new KryoTool(); + } + + public static KryoTool getINST() { + return INST; + } + + private KryoPool pool; + + public KryoTool() { + KryoFactory factory = () -> { + Kryo kryo = new Kryo(); + kryo.setReferences(false); + // 关闭注册 + kryo.setRegistrationRequired(false); + return kryo; + }; + + // Build pool with SoftReferences enabled (optional) + pool = new KryoPool.Builder(factory).softReferences().build(); + } + + public byte[] writeObject(T obj) { + byte[] result = null; + + if (obj != null) { + Kryo kryo = pool.borrow(); + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Output output = new Output(baos); + kryo.writeObject(output, obj); + output.close(); + + result = baos.toByteArray(); + } finally { + pool.release(kryo); + } + } + + return result; + } + + public T readObject(byte[] data, Class clazz) { + T result = null; + + if (data != null) { + Kryo kryo = pool.borrow(); + try { + ByteArrayInputStream bais = new ByteArrayInputStream(data); + Input input = new Input(bais); + result = kryo.readObject(input, clazz); + } finally { + pool.release(kryo); + } + } + + return result; + } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/AbstractTimerTrigger.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/AbstractTimerTrigger.java new file mode 100644 index 0000000..cd1ecbf --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/AbstractTimerTrigger.java @@ -0,0 +1,25 @@ +package com.serotonin.timer; + +import java.util.Date; + +abstract public class AbstractTimerTrigger extends TimerTrigger { + private final boolean delayed; + private final long first; + + public AbstractTimerTrigger(long delay) { + this.delayed = true; + first = delay; + } + + public AbstractTimerTrigger(Date start) { + delayed = false; + first = start.getTime(); + } + + @Override + final protected long getFirstExecutionTime() { + if (delayed) + return timer.currentTimeMillis() + first; + return first; + } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/CronExpression.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/CronExpression.java new file mode 100644 index 0000000..8439758 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/CronExpression.java @@ -0,0 +1,1444 @@ +package com.serotonin.timer; + +import java.text.ParseException; +import java.util.*; + +/** + * Significant portions of this code (i.e. most of it) were lifted from the Quartz scheduling library for Java. + * + * @see http://www.quartz-scheduler.org/api/2.1.0/ + * + * @author Matthew Lohbihler (edits to make compatible with this package) + */ +public class CronExpression implements Cloneable { + protected static final int YEAR_AT_WHICH_TO_GIVE_UP_SCHEDULING = 2299; + + protected static final int SECOND = 0; + protected static final int MINUTE = 1; + protected static final int HOUR = 2; + protected static final int DAY_OF_MONTH = 3; + protected static final int MONTH = 4; + protected static final int DAY_OF_WEEK = 5; + protected static final int YEAR = 6; + protected static final int ALL_SPEC_INT = 99; // '*' + protected static final int NO_SPEC_INT = 98; // '?' + protected static final Integer ALL_SPEC = new Integer(ALL_SPEC_INT); + protected static final Integer NO_SPEC = new Integer(NO_SPEC_INT); + + protected static final Map monthMap = new HashMap(20); + protected static final Map dayMap = new HashMap(60); + static { + monthMap.put("JAN", new Integer(0)); + monthMap.put("FEB", new Integer(1)); + monthMap.put("MAR", new Integer(2)); + monthMap.put("APR", new Integer(3)); + monthMap.put("MAY", new Integer(4)); + monthMap.put("JUN", new Integer(5)); + monthMap.put("JUL", new Integer(6)); + monthMap.put("AUG", new Integer(7)); + monthMap.put("SEP", new Integer(8)); + monthMap.put("OCT", new Integer(9)); + monthMap.put("NOV", new Integer(10)); + monthMap.put("DEC", new Integer(11)); + + dayMap.put("SUN", new Integer(1)); + dayMap.put("MON", new Integer(2)); + dayMap.put("TUE", new Integer(3)); + dayMap.put("WED", new Integer(4)); + dayMap.put("THU", new Integer(5)); + dayMap.put("FRI", new Integer(6)); + dayMap.put("SAT", new Integer(7)); + } + + private String cronExpression = null; + private TimeZone timeZone = null; + protected transient TreeSet seconds; + protected transient TreeSet minutes; + protected transient TreeSet hours; + protected transient TreeSet daysOfMonth; + protected transient TreeSet months; + protected transient TreeSet daysOfWeek; + protected transient TreeSet years; + + protected transient boolean lastdayOfWeek = false; + protected transient int nthdayOfWeek = 0; + protected transient boolean lastdayOfMonth = false; + protected transient boolean nearestWeekday = false; + protected transient boolean expressionParsed = false; + + /** + * Constructs a new CronExpression based on the specified parameter. + * + * @param cronExpression + * String representation of the cron expression the new object should represent + * @throws ParseException + * if the string expression cannot be parsed into a valid CronExpression + */ + public CronExpression(String cronExpression) throws ParseException { + if (cronExpression == null) { + throw new IllegalArgumentException("cronExpression cannot be null"); + } + + this.cronExpression = cronExpression.toUpperCase(Locale.US); + + buildExpression(this.cronExpression); + } + + /** + * Indicates whether the given date satisfies the cron expression. Note that milliseconds are ignored, so two Dates + * falling on different milliseconds of the same second will always have the same result here. + * + * @param date + * the date to evaluate + * @return a boolean indicating whether the given date satisfies the cron expression + */ + public boolean isSatisfiedBy(Date date) { + Calendar testDateCal = Calendar.getInstance(getTimeZone()); + testDateCal.setTime(date); + testDateCal.set(Calendar.MILLISECOND, 0); + Date originalDate = testDateCal.getTime(); + + testDateCal.add(Calendar.SECOND, -1); + + Date timeAfter = getTimeAfter(testDateCal.getTime()); + + return ((timeAfter != null) && (timeAfter.equals(originalDate))); + } + + /** + * Returns the next date/time after the given date/time which satisfies the cron expression. + * + * @param date + * the date/time at which to begin the search for the next valid date/time + * @return the next valid date/time + */ + public Date getNextValidTimeAfter(Date date) { + return getTimeAfter(date); + } + + /** + * Returns the next date/time after the given date/time which does not satisfy the expression + * + * @param date + * the date/time at which to begin the search for the next invalid date/time + * @return the next valid date/time + */ + public Date getNextInvalidTimeAfter(Date date) { + long difference = 1000; + + // move back to the nearest second so differences will be accurate + Calendar adjustCal = Calendar.getInstance(getTimeZone()); + adjustCal.setTime(date); + adjustCal.set(Calendar.MILLISECOND, 0); + Date lastDate = adjustCal.getTime(); + + Date newDate = null; + + // TODO: (QUARTZ-481) IMPROVE THIS! The following is a BAD solution to this problem. Performance will be very + // bad here, depending on the cron expression. It is, however A solution. + + // keep getting the next included time until it's farther than one second + // apart. At that point, lastDate is the last valid fire time. We return + // the second immediately following it. + while (difference == 1000) { + newDate = getTimeAfter(lastDate); + + difference = newDate.getTime() - lastDate.getTime(); + + if (difference == 1000) { + lastDate = newDate; + } + } + + return new Date(lastDate.getTime() + 1000); + } + + /** + * Returns the time zone for which this CronExpression will be resolved. + */ + public TimeZone getTimeZone() { + if (timeZone == null) { + timeZone = TimeZone.getDefault(); + } + + return timeZone; + } + + /** + * Sets the time zone for which this CronExpression will be resolved. + */ + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + } + + /** + * Returns the string representation of the CronExpression + * + * @return a string representation of the CronExpression + */ + @Override + public String toString() { + return cronExpression; + } + + /** + * Indicates whether the specified cron expression can be parsed into a valid cron expression + * + * @param cronExpression + * the expression to evaluate + * @return a boolean indicating whether the given expression is a valid cron expression + */ + public static boolean isValidExpression(String cronExpression) { + + try { + new CronExpression(cronExpression); + } + catch (ParseException pe) { + return false; + } + + return true; + } + + // ////////////////////////////////////////////////////////////////////////// + // + // Expression Parsing Functions + // + // ////////////////////////////////////////////////////////////////////////// + + protected void buildExpression(String expression) throws ParseException { + expressionParsed = true; + + try { + + if (seconds == null) { + seconds = new TreeSet(); + } + if (minutes == null) { + minutes = new TreeSet(); + } + if (hours == null) { + hours = new TreeSet(); + } + if (daysOfMonth == null) { + daysOfMonth = new TreeSet(); + } + if (months == null) { + months = new TreeSet(); + } + if (daysOfWeek == null) { + daysOfWeek = new TreeSet(); + } + if (years == null) { + years = new TreeSet(); + } + + int exprOn = SECOND; + + StringTokenizer exprsTok = new StringTokenizer(expression, " \t", false); + + while (exprsTok.hasMoreTokens() && exprOn <= YEAR) { + String expr = exprsTok.nextToken().trim(); + + // throw an exception if L is used with other days of the month + if (exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.indexOf(",") >= 0) { + throw new ParseException( + "Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1); + } + // throw an exception if L is used with other days of the week + if (exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.indexOf(",") >= 0) { + throw new ParseException( + "Support for specifying 'L' with other days of the week is not implemented", -1); + } + + StringTokenizer vTok = new StringTokenizer(expr, ","); + while (vTok.hasMoreTokens()) { + String v = vTok.nextToken(); + storeExpressionVals(0, v, exprOn); + } + + exprOn++; + } + + if (exprOn <= DAY_OF_WEEK) { + throw new ParseException("Unexpected end of expression.", expression.length()); + } + + if (exprOn <= YEAR) { + storeExpressionVals(0, "*", YEAR); + } + + TreeSet dow = getSet(DAY_OF_WEEK); + TreeSet dom = getSet(DAY_OF_MONTH); + + // Copying the logic from the UnsupportedOperationException below + boolean dayOfMSpec = !dom.contains(NO_SPEC); + boolean dayOfWSpec = !dow.contains(NO_SPEC); + + if (dayOfMSpec && !dayOfWSpec) { + // skip + } + else if (dayOfWSpec && !dayOfMSpec) { + // skip + } + else { + throw new ParseException( + "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0); + } + } + catch (ParseException pe) { + throw pe; + } + catch (Exception e) { + throw new ParseException("Illegal cron expression format (" + e.toString() + ")", 0); + } + } + + protected int storeExpressionVals(int pos, String s, int type) throws ParseException { + + int incr = 0; + int i = skipWhiteSpace(pos, s); + if (i >= s.length()) { + return i; + } + char c = s.charAt(i); + if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW"))) { + String sub = s.substring(i, i + 3); + int sval = -1; + int eval = -1; + if (type == MONTH) { + sval = getMonthNumber(sub) + 1; + if (sval <= 0) { + throw new ParseException("Invalid Month value: '" + sub + "'", i); + } + if (s.length() > i + 3) { + c = s.charAt(i + 3); + if (c == '-') { + i += 4; + sub = s.substring(i, i + 3); + eval = getMonthNumber(sub) + 1; + if (eval <= 0) { + throw new ParseException("Invalid Month value: '" + sub + "'", i); + } + } + } + } + else if (type == DAY_OF_WEEK) { + sval = getDayOfWeekNumber(sub); + if (sval < 0) { + throw new ParseException("Invalid Day-of-Week value: '" + sub + "'", i); + } + if (s.length() > i + 3) { + c = s.charAt(i + 3); + if (c == '-') { + i += 4; + sub = s.substring(i, i + 3); + eval = getDayOfWeekNumber(sub); + if (eval < 0) { + throw new ParseException("Invalid Day-of-Week value: '" + sub + "'", i); + } + } + else if (c == '#') { + try { + i += 4; + nthdayOfWeek = Integer.parseInt(s.substring(i)); + if (nthdayOfWeek < 1 || nthdayOfWeek > 5) { + throw new Exception(); + } + } + catch (Exception e) { + throw new ParseException("A numeric value between 1 and 5 must follow the '#' option", i); + } + } + else if (c == 'L') { + lastdayOfWeek = true; + i++; + } + } + + } + else { + throw new ParseException("Illegal characters for this position: '" + sub + "'", i); + } + if (eval != -1) { + incr = 1; + } + addToSet(sval, eval, incr, type); + return (i + 3); + } + + if (c == '?') { + i++; + if ((i + 1) < s.length() && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) { + throw new ParseException("Illegal character after '?': " + s.charAt(i), i); + } + if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) { + throw new ParseException("'?' can only be specfied for Day-of-Month or Day-of-Week.", i); + } + if (type == DAY_OF_WEEK && !lastdayOfMonth) { + int val = (daysOfMonth.last()).intValue(); + if (val == NO_SPEC_INT) { + throw new ParseException("'?' can only be specfied for Day-of-Month -OR- Day-of-Week.", i); + } + } + + addToSet(NO_SPEC_INT, -1, 0, type); + return i; + } + + if (c == '*' || c == '/') { + if (c == '*' && (i + 1) >= s.length()) { + addToSet(ALL_SPEC_INT, -1, incr, type); + return i + 1; + } + else if (c == '/' && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s.charAt(i + 1) == '\t')) { + throw new ParseException("'/' must be followed by an integer.", i); + } + else if (c == '*') { + i++; + } + c = s.charAt(i); + if (c == '/') { // is an increment specified? + i++; + if (i >= s.length()) { + throw new ParseException("Unexpected end of string.", i); + } + + incr = getNumericValue(s, i); + + i++; + if (incr > 10) { + i++; + } + if (incr > 59 && (type == SECOND || type == MINUTE)) { + throw new ParseException("Increment > 60 : " + incr, i); + } + else if (incr > 23 && (type == HOUR)) { + throw new ParseException("Increment > 24 : " + incr, i); + } + else if (incr > 31 && (type == DAY_OF_MONTH)) { + throw new ParseException("Increment > 31 : " + incr, i); + } + else if (incr > 7 && (type == DAY_OF_WEEK)) { + throw new ParseException("Increment > 7 : " + incr, i); + } + else if (incr > 12 && (type == MONTH)) { + throw new ParseException("Increment > 12 : " + incr, i); + } + } + else { + incr = 1; + } + + addToSet(ALL_SPEC_INT, -1, incr, type); + return i; + } + else if (c == 'L') { + i++; + if (type == DAY_OF_MONTH) { + lastdayOfMonth = true; + } + if (type == DAY_OF_WEEK) { + addToSet(7, 7, 0, type); + } + if (type == DAY_OF_MONTH && s.length() > i) { + c = s.charAt(i); + if (c == 'W') { + nearestWeekday = true; + i++; + } + } + return i; + } + else if (c >= '0' && c <= '9') { + int val = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + addToSet(val, -1, -1, type); + } + else { + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(val, s, i); + val = vs.value; + i = vs.pos; + } + i = checkNext(i, s, val, type); + return i; + } + } + else { + throw new ParseException("Unexpected character: " + c, i); + } + + return i; + } + + protected int checkNext(int pos, String s, int val, int type) throws ParseException { + + int end = -1; + int i = pos; + + if (i >= s.length()) { + addToSet(val, end, -1, type); + return i; + } + + char c = s.charAt(pos); + + if (c == 'L') { + if (type == DAY_OF_WEEK) { + lastdayOfWeek = true; + } + else { + throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i); + } + TreeSet set = getSet(type); + set.add(new Integer(val)); + i++; + return i; + } + + if (c == 'W') { + if (type == DAY_OF_MONTH) { + nearestWeekday = true; + } + else { + throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i); + } + TreeSet set = getSet(type); + set.add(new Integer(val)); + i++; + return i; + } + + if (c == '#') { + if (type != DAY_OF_WEEK) { + throw new ParseException("'#' option is not valid here. (pos=" + i + ")", i); + } + i++; + try { + nthdayOfWeek = Integer.parseInt(s.substring(i)); + if (nthdayOfWeek < 1 || nthdayOfWeek > 5) { + throw new Exception(); + } + } + catch (Exception e) { + throw new ParseException("A numeric value between 1 and 5 must follow the '#' option", i); + } + + TreeSet set = getSet(type); + set.add(new Integer(val)); + i++; + return i; + } + + if (c == '-') { + i++; + c = s.charAt(i); + int v = Integer.parseInt(String.valueOf(c)); + end = v; + i++; + if (i >= s.length()) { + addToSet(val, end, 1, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v, s, i); + int v1 = vs.value; + end = v1; + i = vs.pos; + } + if (i < s.length() && ((c = s.charAt(i)) == '/')) { + i++; + c = s.charAt(i); + int v2 = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + addToSet(val, end, v2, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v2, s, i); + int v3 = vs.value; + addToSet(val, end, v3, type); + i = vs.pos; + return i; + } + + addToSet(val, end, v2, type); + return i; + } + + addToSet(val, end, 1, type); + return i; + } + + if (c == '/') { + i++; + c = s.charAt(i); + int v2 = Integer.parseInt(String.valueOf(c)); + i++; + if (i >= s.length()) { + addToSet(val, end, v2, type); + return i; + } + c = s.charAt(i); + if (c >= '0' && c <= '9') { + ValueSet vs = getValue(v2, s, i); + int v3 = vs.value; + addToSet(val, end, v3, type); + i = vs.pos; + return i; + } + + throw new ParseException("Unexpected character '" + c + "' after '/'", i); + } + + addToSet(val, end, 0, type); + i++; + return i; + } + + public String getCronExpression() { + return cronExpression; + } + + public String getExpressionSummary() { + StringBuffer buf = new StringBuffer(); + + buf.append("seconds: "); + buf.append(getExpressionSetSummary(seconds)); + buf.append("\n"); + buf.append("minutes: "); + buf.append(getExpressionSetSummary(minutes)); + buf.append("\n"); + buf.append("hours: "); + buf.append(getExpressionSetSummary(hours)); + buf.append("\n"); + buf.append("daysOfMonth: "); + buf.append(getExpressionSetSummary(daysOfMonth)); + buf.append("\n"); + buf.append("months: "); + buf.append(getExpressionSetSummary(months)); + buf.append("\n"); + buf.append("daysOfWeek: "); + buf.append(getExpressionSetSummary(daysOfWeek)); + buf.append("\n"); + buf.append("lastdayOfWeek: "); + buf.append(lastdayOfWeek); + buf.append("\n"); + buf.append("nearestWeekday: "); + buf.append(nearestWeekday); + buf.append("\n"); + buf.append("NthDayOfWeek: "); + buf.append(nthdayOfWeek); + buf.append("\n"); + buf.append("lastdayOfMonth: "); + buf.append(lastdayOfMonth); + buf.append("\n"); + buf.append("years: "); + buf.append(getExpressionSetSummary(years)); + buf.append("\n"); + + return buf.toString(); + } + + protected String getExpressionSetSummary(Set set) { + + if (set.contains(NO_SPEC)) { + return "?"; + } + if (set.contains(ALL_SPEC)) { + return "*"; + } + + StringBuffer buf = new StringBuffer(); + + Iterator itr = set.iterator(); + boolean first = true; + while (itr.hasNext()) { + Integer iVal = itr.next(); + String val = iVal.toString(); + if (!first) { + buf.append(","); + } + buf.append(val); + first = false; + } + + return buf.toString(); + } + + protected String getExpressionSetSummary(List list) { + + if (list.contains(NO_SPEC)) { + return "?"; + } + if (list.contains(ALL_SPEC)) { + return "*"; + } + + StringBuffer buf = new StringBuffer(); + + Iterator itr = list.iterator(); + boolean first = true; + while (itr.hasNext()) { + Integer iVal = itr.next(); + String val = iVal.toString(); + if (!first) { + buf.append(","); + } + buf.append(val); + first = false; + } + + return buf.toString(); + } + + protected int skipWhiteSpace(int i, String s) { + for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++) { + ; + } + + return i; + } + + protected int findNextWhiteSpace(int i, String s) { + for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) { + ; + } + + return i; + } + + protected void addToSet(int val, int end, int incr, int type) throws ParseException { + + TreeSet set = getSet(type); + + if (type == SECOND || type == MINUTE) { + if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) { + throw new ParseException("Minute and Second values must be between 0 and 59", -1); + } + } + else if (type == HOUR) { + if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) { + throw new ParseException("Hour values must be between 0 and 23", -1); + } + } + else if (type == DAY_OF_MONTH) { + if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT) && (val != NO_SPEC_INT)) { + throw new ParseException("Day of month values must be between 1 and 31", -1); + } + } + else if (type == MONTH) { + if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) { + throw new ParseException("Month values must be between 1 and 12", -1); + } + } + else if (type == DAY_OF_WEEK) { + if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT) && (val != NO_SPEC_INT)) { + throw new ParseException("Day-of-Week values must be between 1 and 7", -1); + } + } + + if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) { + if (val != -1) { + set.add(new Integer(val)); + } + else { + set.add(NO_SPEC); + } + + return; + } + + int startAt = val; + int stopAt = end; + + if (val == ALL_SPEC_INT && incr <= 0) { + incr = 1; + set.add(ALL_SPEC); // put in a marker, but also fill values + } + + if (type == SECOND || type == MINUTE) { + if (stopAt == -1) { + stopAt = 59; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 0; + } + } + else if (type == HOUR) { + if (stopAt == -1) { + stopAt = 23; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 0; + } + } + else if (type == DAY_OF_MONTH) { + if (stopAt == -1) { + stopAt = 31; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } + else if (type == MONTH) { + if (stopAt == -1) { + stopAt = 12; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } + else if (type == DAY_OF_WEEK) { + if (stopAt == -1) { + stopAt = 7; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1; + } + } + else if (type == YEAR) { + if (stopAt == -1) { + stopAt = YEAR_AT_WHICH_TO_GIVE_UP_SCHEDULING; + } + if (startAt == -1 || startAt == ALL_SPEC_INT) { + startAt = 1970; + } + } + + // if the end of the range is before the start, then we need to overflow into + // the next day, month etc. This is done by adding the maximum amount for that + // type, and using modulus max to determine the value being added. + int max = -1; + if (stopAt < startAt) { + switch (type) { + case SECOND: + max = 60; + break; + case MINUTE: + max = 60; + break; + case HOUR: + max = 24; + break; + case MONTH: + max = 12; + break; + case DAY_OF_WEEK: + max = 7; + break; + case DAY_OF_MONTH: + max = 31; + break; + case YEAR: + throw new IllegalArgumentException("Start year must be less than stop year"); + default: + throw new IllegalArgumentException("Unexpected type encountered"); + } + stopAt += max; + } + + for (int i = startAt; i <= stopAt; i += incr) { + if (max == -1) { + // ie: there's no max to overflow over + set.add(new Integer(i)); + } + else { + // take the modulus to get the real value + int i2 = i % max; + + // 1-indexed ranges should not include 0, and should include their max + if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH)) { + i2 = max; + } + + set.add(new Integer(i2)); + } + } + } + + protected TreeSet getSet(int type) { + switch (type) { + case SECOND: + return seconds; + case MINUTE: + return minutes; + case HOUR: + return hours; + case DAY_OF_MONTH: + return daysOfMonth; + case MONTH: + return months; + case DAY_OF_WEEK: + return daysOfWeek; + case YEAR: + return years; + default: + return null; + } + } + + protected ValueSet getValue(int v, String s, int i) { + char c = s.charAt(i); + String s1 = String.valueOf(v); + while (c >= '0' && c <= '9') { + s1 += c; + i++; + if (i >= s.length()) { + break; + } + c = s.charAt(i); + } + ValueSet val = new ValueSet(); + + val.pos = (i < s.length()) ? i : i + 1; + val.value = Integer.parseInt(s1); + return val; + } + + protected int getNumericValue(String s, int i) { + int endOfVal = findNextWhiteSpace(i, s); + String val = s.substring(i, endOfVal); + return Integer.parseInt(val); + } + + protected int getMonthNumber(String s) { + Integer integer = monthMap.get(s); + + if (integer == null) { + return -1; + } + + return integer.intValue(); + } + + protected int getDayOfWeekNumber(String s) { + Integer integer = dayMap.get(s); + + if (integer == null) { + return -1; + } + + return integer.intValue(); + } + + // ////////////////////////////////////////////////////////////////////////// + // + // Computation Functions + // + // ////////////////////////////////////////////////////////////////////////// + + protected Date getTimeAfter(Date afterTime) { + + // Computation is based on Gregorian year only. + Calendar cl = new GregorianCalendar(getTimeZone()); + + // move ahead one second, since we're computing the time *after* the + // given time + afterTime = new Date(afterTime.getTime() + 1000); + // CronTrigger does not deal with milliseconds + cl.setTime(afterTime); + cl.set(Calendar.MILLISECOND, 0); + + boolean gotOne = false; + // loop until we've computed the next time, or we've past the endTime + while (!gotOne) { + + // if (endTime != null && cl.getTime().after(endTime)) return null; + if (cl.get(Calendar.YEAR) > 2999) { // prevent endless loop... + return null; + } + + SortedSet st = null; + int t = 0; + + int sec = cl.get(Calendar.SECOND); + int min = cl.get(Calendar.MINUTE); + + // get second................................................. + st = seconds.tailSet(new Integer(sec)); + if (st != null && st.size() != 0) { + sec = (st.first()).intValue(); + } + else { + sec = (seconds.first()).intValue(); + min++; + cl.set(Calendar.MINUTE, min); + } + cl.set(Calendar.SECOND, sec); + + min = cl.get(Calendar.MINUTE); + int hr = cl.get(Calendar.HOUR_OF_DAY); + t = -1; + + // get minute................................................. + st = minutes.tailSet(new Integer(min)); + if (st != null && st.size() != 0) { + t = min; + min = (st.first()).intValue(); + } + else { + min = (minutes.first()).intValue(); + hr++; + } + if (min != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, min); + setCalendarHour(cl, hr); + continue; + } + cl.set(Calendar.MINUTE, min); + + hr = cl.get(Calendar.HOUR_OF_DAY); + int day = cl.get(Calendar.DAY_OF_MONTH); + t = -1; + + // get hour................................................... + st = hours.tailSet(new Integer(hr)); + if (st != null && st.size() != 0) { + t = hr; + hr = (st.first()).intValue(); + } + else { + hr = (hours.first()).intValue(); + day++; + } + if (hr != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + setCalendarHour(cl, hr); + continue; + } + cl.set(Calendar.HOUR_OF_DAY, hr); + + day = cl.get(Calendar.DAY_OF_MONTH); + int mon = cl.get(Calendar.MONTH) + 1; + // '+ 1' because calendar is 0-based for this field, and we are + // 1-based + t = -1; + int tmon = mon; + + // get day................................................... + boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC); + boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC); + if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule + st = daysOfMonth.tailSet(new Integer(day)); + if (lastdayOfMonth) { + if (!nearestWeekday) { + t = day; + day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + } + else { + t = day; + day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + + Calendar tcal = Calendar.getInstance(getTimeZone()); + tcal.set(Calendar.SECOND, 0); + tcal.set(Calendar.MINUTE, 0); + tcal.set(Calendar.HOUR_OF_DAY, 0); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR)); + + int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + int dow = tcal.get(Calendar.DAY_OF_WEEK); + + if (dow == Calendar.SATURDAY && day == 1) { + day += 2; + } + else if (dow == Calendar.SATURDAY) { + day -= 1; + } + else if (dow == Calendar.SUNDAY && day == ldom) { + day -= 2; + } + else if (dow == Calendar.SUNDAY) { + day += 1; + } + + tcal.set(Calendar.SECOND, sec); + tcal.set(Calendar.MINUTE, min); + tcal.set(Calendar.HOUR_OF_DAY, hr); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + Date nTime = tcal.getTime(); + if (nTime.before(afterTime)) { + day = 1; + mon++; + } + } + } + else if (nearestWeekday) { + t = day; + day = (daysOfMonth.first()).intValue(); + + Calendar tcal = Calendar.getInstance(getTimeZone()); + tcal.set(Calendar.SECOND, 0); + tcal.set(Calendar.MINUTE, 0); + tcal.set(Calendar.HOUR_OF_DAY, 0); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR)); + + int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + int dow = tcal.get(Calendar.DAY_OF_WEEK); + + if (dow == Calendar.SATURDAY && day == 1) { + day += 2; + } + else if (dow == Calendar.SATURDAY) { + day -= 1; + } + else if (dow == Calendar.SUNDAY && day == ldom) { + day -= 2; + } + else if (dow == Calendar.SUNDAY) { + day += 1; + } + + tcal.set(Calendar.SECOND, sec); + tcal.set(Calendar.MINUTE, min); + tcal.set(Calendar.HOUR_OF_DAY, hr); + tcal.set(Calendar.DAY_OF_MONTH, day); + tcal.set(Calendar.MONTH, mon - 1); + Date nTime = tcal.getTime(); + if (nTime.before(afterTime)) { + day = (daysOfMonth.first()).intValue(); + mon++; + } + } + else if (st != null && st.size() != 0) { + t = day; + day = (st.first()).intValue(); + // make sure we don't over-run a short month, such as february + int lastDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + if (day > lastDay) { + day = (daysOfMonth.first()).intValue(); + mon++; + } + } + else { + day = (daysOfMonth.first()).intValue(); + mon++; + } + + if (day != t || mon != tmon) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we + // are 1-based + continue; + } + } + else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule + if (lastdayOfWeek) { // are we looking for the last XXX day of + // the month? + int dow = (daysOfWeek.first()).intValue(); // desired + // d-o-w + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } + if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + + if (day + daysToAdd > lDay) { // did we already miss the + // last one? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } + + // find date of last occurance of this day in this month... + while ((day + daysToAdd + 7) <= lDay) { + daysToAdd += 7; + } + + day += daysToAdd; + + if (daysToAdd > 0) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' here because we are not promoting the month + continue; + } + + } + else if (nthdayOfWeek != 0) { + // are we looking for the Nth XXX day in the month? + int dow = (daysOfWeek.first()).intValue(); // desired + // d-o-w + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } + else if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + boolean dayShifted = false; + if (daysToAdd > 0) { + dayShifted = true; + } + + day += daysToAdd; + int weekOfMonth = day / 7; + if (day % 7 > 0) { + weekOfMonth++; + } + + daysToAdd = (nthdayOfWeek - weekOfMonth) * 7; + day += daysToAdd; + if (daysToAdd < 0 || day > getLastDayOfMonth(mon, cl.get(Calendar.YEAR))) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } + else if (daysToAdd > 0 || dayShifted) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' here because we are NOT promoting the month + continue; + } + } + else { + int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w + int dow = (daysOfWeek.first()).intValue(); // desired + // d-o-w + st = daysOfWeek.tailSet(new Integer(cDow)); + if (st != null && st.size() > 0) { + dow = (st.first()).intValue(); + } + + int daysToAdd = 0; + if (cDow < dow) { + daysToAdd = dow - cDow; + } + if (cDow > dow) { + daysToAdd = dow + (7 - cDow); + } + + int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); + + if (day + daysToAdd > lDay) { // will we pass the end of + // the month? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon); + // no '- 1' here because we are promoting the month + continue; + } + else if (daysToAdd > 0) { // are we swithing days? + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, day + daysToAdd); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, + // and we are 1-based + continue; + } + } + } + else { // dayOfWSpec && !dayOfMSpec + throw new UnsupportedOperationException( + "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented."); + // TODO: + } + cl.set(Calendar.DAY_OF_MONTH, day); + + mon = cl.get(Calendar.MONTH) + 1; + // '+ 1' because calendar is 0-based for this field, and we are + // 1-based + int year = cl.get(Calendar.YEAR); + t = -1; + + // test for expressions that never generate a valid fire date, + // but keep looping... + if (year > YEAR_AT_WHICH_TO_GIVE_UP_SCHEDULING) { + return null; + } + + // get month................................................... + st = months.tailSet(new Integer(mon)); + if (st != null && st.size() != 0) { + t = mon; + mon = (st.first()).intValue(); + } + else { + mon = (months.first()).intValue(); + year++; + } + if (mon != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + cl.set(Calendar.YEAR, year); + continue; + } + cl.set(Calendar.MONTH, mon - 1); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + + year = cl.get(Calendar.YEAR); + t = -1; + + // get year................................................... + st = years.tailSet(new Integer(year)); + if (st != null && st.size() != 0) { + t = year; + year = (st.first()).intValue(); + } + else { + return null; // ran out of years... + } + + if (year != t) { + cl.set(Calendar.SECOND, 0); + cl.set(Calendar.MINUTE, 0); + cl.set(Calendar.HOUR_OF_DAY, 0); + cl.set(Calendar.DAY_OF_MONTH, 1); + cl.set(Calendar.MONTH, 0); + // '- 1' because calendar is 0-based for this field, and we are + // 1-based + cl.set(Calendar.YEAR, year); + continue; + } + cl.set(Calendar.YEAR, year); + + gotOne = true; + } // while( !done ) + + return cl.getTime(); + } + + /** + * Advance the calendar to the particular hour paying particular attention to daylight saving problems. + * + * @param cal + * @param hour + */ + protected void setCalendarHour(Calendar cal, int hour) { + cal.set(Calendar.HOUR_OF_DAY, hour); + if (cal.get(Calendar.HOUR_OF_DAY) != hour && hour != 24) { + cal.set(Calendar.HOUR_OF_DAY, hour + 1); + } + } + + /** + * NOT YET IMPLEMENTED: Returns the time before the given time that the CronExpression matches. + */ + protected Date getTimeBefore(@SuppressWarnings("unused") Date endTime) { + // TODO: implement QUARTZ-423 + return null; + } + + /** + * NOT YET IMPLEMENTED: Returns the final time that the CronExpression will match. + */ + public Date getFinalFireTime() { + // TODO: implement QUARTZ-423 + return null; + } + + protected boolean isLeapYear(int year) { + return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)); + } + + protected int getLastDayOfMonth(int monthNum, int year) { + + switch (monthNum) { + case 1: + return 31; + case 2: + return (isLeapYear(year)) ? 29 : 28; + case 3: + return 31; + case 4: + return 30; + case 5: + return 31; + case 6: + return 30; + case 7: + return 31; + case 8: + return 31; + case 9: + return 30; + case 10: + return 31; + case 11: + return 30; + case 12: + return 31; + default: + throw new IllegalArgumentException("Illegal month number: " + monthNum); + } + } + + private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException { + stream.defaultReadObject(); + try { + buildExpression(cronExpression); + } + catch (Exception ignore) { + // never happens + } + } + + @Override + public Object clone() { + CronExpression copy = null; + try { + copy = new CronExpression(getCronExpression()); + if (getTimeZone() != null) + copy.setTimeZone((TimeZone) getTimeZone().clone()); + } + catch (ParseException ex) { // never happens since the source is valid... + throw new IncompatibleClassChangeError("Not Cloneable."); + } + return copy; + } +} + +class ValueSet { + public int value; + + public int pos; +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/FixedRateTrigger.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/FixedRateTrigger.java new file mode 100644 index 0000000..0e778e2 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/FixedRateTrigger.java @@ -0,0 +1,49 @@ +package com.serotonin.timer; + +import java.util.Date; + +public class FixedRateTrigger extends AbstractTimerTrigger { + private final long period; + + /** + * Use this constructor to quantize the start of the trigger to the period. + * + * @param period + * @param now + * @param quantize + * unused. Required for signature uniqueness. + */ + public FixedRateTrigger(long period, long now, boolean quantize) { + this(new Date(now + period - (now % period)), period); + } + + public FixedRateTrigger(long delay, long period) { + super(delay); + this.period = period; + } + + public FixedRateTrigger(Date start, long period) { + super(start); + this.period = period; + } + + @Override + protected long calculateNextExecutionTimeImpl() { + return nextExecutionTime + period; + } + + @Override + protected long calculateNextExecutionTimeImpl(long after) { + long d = after - nextExecutionTime; + if (d < 0) + return nextExecutionTime + period; + + long periods = d / period; + return nextExecutionTime + period * (periods + 1); + } + + @Override + public long mostRecentExecutionTime() { + return nextExecutionTime - period; + } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/ModelTimeoutClient.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/ModelTimeoutClient.java new file mode 100644 index 0000000..91c0f1e --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/ModelTimeoutClient.java @@ -0,0 +1,9 @@ +/* + Copyright (C) 2006-2011 Serotonin Software Technologies Inc. All rights reserved. + @author Matthew Lohbihler + */ +package com.serotonin.timer; + +public interface ModelTimeoutClient { + void scheduleTimeout(T model, long fireTime); +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/ModelTimeoutTask.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/ModelTimeoutTask.java new file mode 100644 index 0000000..5f5438d --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/ModelTimeoutTask.java @@ -0,0 +1,34 @@ +package com.serotonin.timer; + +import java.util.Date; + +/** + * A parameterizable one-time task. Allows the pass-through of a model to the target. + * + * @author Matthew + * + * @param + */ +public class ModelTimeoutTask extends TimerTask { + private final ModelTimeoutClient client; + private final T model; + + public ModelTimeoutTask(long delay, ModelTimeoutClient client, T model) { + this(new OneTimeTrigger(delay), client, model); + } + + public ModelTimeoutTask(Date date, ModelTimeoutClient client, T model) { + this(new OneTimeTrigger(date), client, model); + } + + public ModelTimeoutTask(TimerTrigger trigger, ModelTimeoutClient client, T model) { + super(trigger); + this.client = client; + this.model = model; + } + + @Override + public void run(long runtime) { + client.scheduleTimeout(model, runtime); + } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/NonConcurrentTask.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/NonConcurrentTask.java new file mode 100644 index 0000000..37229a4 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/NonConcurrentTask.java @@ -0,0 +1,49 @@ +package com.serotonin.timer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Date; + +/** + * Extends the timer task to prevent tasks from running concurrently. This is useful when a job is run regularly on a + * schedule, and there may be cases where a particular run could go on so long that is not finished before the next is + * scheduled to begin. In such cases, the next job will be aborted, and a warning message will be written to the log. + * + * @author Matthew Lohbihler + */ +abstract public class NonConcurrentTask extends TimerTask { + private static final Log LOG = LogFactory.getLog(NonConcurrentTask.class); + + private Thread thread; + private long threadRuntime; + + public NonConcurrentTask(TimerTrigger trigger) { + super(trigger); + } + + public NonConcurrentTask(TimerTrigger trigger, String name) { + super(trigger, name); + } + + @Override + final public void run(long runtime) { + Thread localThread = thread; + if (localThread != null) { + LOG.warn("NonConcurrentTask run at " + new Date(runtime) + " aborted because another run at " + + new Date(threadRuntime) + " has not yet completed: " + getClass().getName()); + return; + } + + try { + thread = Thread.currentThread(); + threadRuntime = runtime; + runNonConcurrent(runtime); + } + finally { + thread = null; + } + } + + abstract public void runNonConcurrent(long runtime); +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/OneTimeTrigger.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/OneTimeTrigger.java new file mode 100644 index 0000000..a804238 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/OneTimeTrigger.java @@ -0,0 +1,28 @@ +package com.serotonin.timer; + +import java.util.Date; + +public class OneTimeTrigger extends AbstractTimerTrigger { + public OneTimeTrigger(long delay) { + super(delay); + } + + public OneTimeTrigger(Date start) { + super(start); + } + + @Override + protected long calculateNextExecutionTimeImpl() { + return 0; + } + + @Override + protected long calculateNextExecutionTimeImpl(long after) { + return 0; + } + + @Override + final public long mostRecentExecutionTime() { + return nextExecutionTime; + } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/RealTimeTimer.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/RealTimeTimer.java new file mode 100644 index 0000000..22f43b3 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/RealTimeTimer.java @@ -0,0 +1,320 @@ +package com.serotonin.timer; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.*; + + +public class RealTimeTimer extends AbstractTimer { + private static final Log LOG = LogFactory.getLog(RealTimeTimer.class); + + /** + * The timer task queue. This data structure is shared with the timer thread. The timer produces tasks, via its + * various schedule calls, and the timer thread consumes, executing timer tasks as appropriate, and removing them + * from the queue when they're obsolete. + */ + private final TaskQueue queue = new TaskQueue(); + + /** + * The timer thread. + */ + private TimerThread thread; + + // Do i own the executor? + private boolean ownsExecutor; + private Exception cancelStack; + + private TimeSource timeSource = new SystemTimeSource(); + + public void setTimeSource(TimeSource timeSource) { + this.timeSource = timeSource; + } + + public void init(int minThread, int maxThread) { + ownsExecutor = true; + ThreadFactory threadFactory = new BasicThreadFactory.Builder() + .namingPattern("sw-timer-").build(); + init(new ThreadPoolExecutor(minThread, maxThread, 30L, TimeUnit.SECONDS, new SynchronousQueue<>(), threadFactory)); + } + + public void init(ExecutorService executorService) { + thread = new TimerThread(queue, executorService, timeSource); + thread.setName("Serotonin Timer"); + thread.setDaemon(false); + thread.start(); + } + + @Override + public boolean isInitialized() { + return thread != null; + } + + /** + * This object causes the timer's task execution thread to exit gracefully when there are no live references to the + * Timer object and no tasks in the timer queue. It is used in preference to a finalizer on Timer as such a + * finalizer would be susceptible to a subclass's finalizer forgetting to call it. + */ + @Override + protected void finalize() { + synchronized (queue) { + if (thread != null) + thread.newTasksMayBeScheduled = false; + if (cancelStack == null) + cancelStack = new Exception(); + queue.notify(); + } + } + + /** + * A convenience method that executes the given command in the executor service immediately. + * + * @param command + * @throws ExecutionRejectedException + */ + @Override + public void execute(Runnable command) { + if (thread == null) + throw new IllegalStateException("Run init first"); + thread.execute(command); + } + + /** + * A convenience method that executes the given command in the executor service immediately. + * + * @param command + * @throws ExecutionRejectedException + */ + @Override + public void execute(ScheduledRunnable command, long fireTime) { + if (thread == null) + throw new IllegalStateException("Run init first"); + thread.execute(command, fireTime); + } + + /** + * Schedule the specified timer task for execution at the specified time with the specified period, in milliseconds. + * If period is positive, the task is scheduled for repeated execution; if period is zero, the task is scheduled for + * one-time execution. Time is specified in Date.getTime() format. This method checks timer state, task state, and + * initial execution time, but not period. + * + * @throws IllegalArgumentException + * if time() is negative. + * @throws IllegalStateException + * if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated. + */ + @Override + protected void scheduleImpl(TimerTask task) { + if (thread == null) + throw new IllegalStateException("Run init first"); + + if (task.state == TimerTask.CANCELLED || task.state == TimerTask.EXECUTED) + throw new IllegalStateException("Task already executed or cancelled"); + + synchronized (queue) { + if (!thread.newTasksMayBeScheduled) { + if (cancelStack != null) { + LOG.error("Timer already cancelled."); + LOG.error(" Cancel stack:", cancelStack); + LOG.error(" Current stack:", new Exception()); + throw new IllegalStateException("Timer already cancelled.", cancelStack); + } + throw new IllegalStateException("Timer already cancelled."); + } + + synchronized (task.lock) { + if (task.state == TimerTask.VIRGIN) { + long time = task.trigger.getFirstExecutionTime(); + + if (time < 0) + throw new IllegalArgumentException("Illegal execution time."); + + task.trigger.nextExecutionTime = time; + task.state = TimerTask.SCHEDULED; + } + } + + queue.add(task); + if (queue.getMin() == task) + queue.notify(); + } + } + + /** + * Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing + * task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more + * tasks may be scheduled on it. + * + *

+ * Note that calling this method from within the run method of a timer task that was invoked by this timer + * absolutely guarantees that the ongoing task execution is the last task execution that will ever be performed by + * this timer. + * + *

+ * This method may be called repeatedly; the second and subsequent calls have no effect. + */ + @Override + public List cancel() { + List tasks; + synchronized (queue) { + thread.newTasksMayBeScheduled = false; + if (cancelStack == null) + cancelStack = new Exception(); + tasks = getTasks(); + queue.clear(); + queue.notify(); // In case queue was already empty. + } + + if (ownsExecutor) + getExecutorService().shutdown(); + + return tasks; + } + + public ExecutorService getExecutorService() { + return thread.getExecutorService(); + } + + /** + * Removes all canceled tasks from this timer's task queue. Calling this method has no effect on the behavior of + * the timer, but eliminates the references to the canceled tasks from the queue. If there are no external + * references to these tasks, they become eligible for garbage collection. + * + *

+ * Most programs will have no need to call this method. It is designed for use by the rare application that cancels + * a large number of tasks. Calling this method trades time for space: the runtime of the method may be proportional + * to n + c log n, where n is the number of tasks in the queue and c is the number of canceled tasks. + * + *

+ * Note that it is permissible to call this method from within a a task scheduled on this timer. + * + * @return the number of tasks removed from the queue. + * @since 1.5 + */ + @Override + public int purge() { + int result = 0; + + synchronized (queue) { + for (int i = queue.size(); i > 0; i--) { + if (queue.get(i).state == TimerTask.CANCELLED) { + queue.quickRemove(i); + result++; + } + } + + if (result != 0) + queue.heapify(); + } + + return result; + } + + @Override + public int size() { + return queue.size(); + } + + @Override + public List getTasks() { + List result = new ArrayList(); + synchronized (queue) { + for (int i = 0; i < queue.size(); i++) + result.add(queue.get(i + 1)); + } + return result; + } + + @Override + public long currentTimeMillis() { + return timeSource.currentTimeMillis(); + } + // + // @SuppressWarnings("unchecked") + // public static void main(String[] args) throws Exception { + // RealTimeTimer timer = new RealTimeTimer(); + // ExecutorService executorService = Executors.newCachedThreadPool(); + // timer.init(executorService); + // + // timer.schedule(new NamedTask("task 7", new OneTimeTrigger(25000))); + // timer.schedule(new NamedTask("task 1", new OneTimeTrigger(1000))); + // timer.schedule(new NamedTask("task 2", new OneTimeTrigger(2000))); + // timer.schedule(new NamedTask("task 4", new OneTimeTrigger(20000))); + // timer.schedule(new NamedTask("task 5", new OneTimeTrigger(21000))); + // timer.schedule(new NamedTask("task 3", new OneTimeTrigger(10000))); + // timer.schedule(new NamedTask("task 6", new OneTimeTrigger(22000))); + // timer.schedule(new NamedTask("rate", new FixedRateTrigger(5000, 1800))); + // timer.schedule(new NamedTask("delay", new FixedDelayTrigger(6000, + // 2100))); + // timer.schedule(new NamedTask("cron", new + // CronTimerTrigger("0/6 * * * * ?"))); + // + // Thread.sleep(15000); + // System.out.println("Serializing"); + // + // List tasks = timer.cancel(); + // timer = null; + // + // ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // ObjectOutputStream oos = new ObjectOutputStream(baos); + // oos.writeObject(tasks); + // + // Thread.sleep(20000); + // + // ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + // ObjectInputStream ois = new ObjectInputStream(bais); + // tasks = (List) ois.readObject(); + // + // System.out.println("Simulating"); + // SimulationTimer sim = new SimulationTimer(); + // for (TimerTask task : tasks) + // sim.schedule(task); + // + // for (int i = 0; i < 10; i++) { + // long start = System.currentTimeMillis(); + // sim.fastForwardTo(start); + // System.out.println("Run " + i + " took " + (System.currentTimeMillis() - + // start) + " ms"); + // } + // + // System.out.println("Real time"); + // timer = new RealTimeTimer(); + // timer.init(executorService); + // timer.scheduleAll(sim); + // + // Thread.sleep(10000); + // + // timer.cancel(); + // executorService.shutdown(); + // } + // + // static class NamedTask extends TimerTask { + // private static final long serialVersionUID = 1L; + // + // String name; + // + // NamedTask(String name, TimerTrigger trigger) { + // super(trigger); + // this.name = name; + // } + // + // @Override + // public String toString() { + // return "NamedTask(" + name + ")"; + // } + // + // @Override + // protected void run(long runtime) { + // System.out.println(name + " ran at " + runtime); + // try { + // Thread.sleep(300); + // } + // catch (InterruptedException e) { + // // no op + // } + // } + // } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/SystemTimeSource.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/SystemTimeSource.java new file mode 100644 index 0000000..3f377c1 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/SystemTimeSource.java @@ -0,0 +1,12 @@ +package com.serotonin.timer; + +/** + * An implementation of TimeSource that returns the host time via System. + * + * @author Matthew Lohbihler + */ +public class SystemTimeSource implements TimeSource { + public long currentTimeMillis() { + return System.currentTimeMillis(); + } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/TaskQueue.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/TaskQueue.java new file mode 100644 index 0000000..92cf612 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/TaskQueue.java @@ -0,0 +1,148 @@ +package com.serotonin.timer; + +import java.util.Arrays; + +class TaskQueue { + /** + * Priority queue represented as a balanced binary heap: the two children of queue[n] are queue[2*n] and + * queue[2*n+1]. The priority queue is ordered on the nextExecutionTime field: The TimerTask with the lowest + * nextExecutionTime is in queue[1] (assuming the queue is nonempty). For each node n in the heap, and each + * descendant of n, d, n.nextExecutionTime <= d.nextExecutionTime. + */ + private TimerTask[] queue = new TimerTask[128]; + + /** + * The number of tasks in the priority queue. (The tasks are stored in queue[1] up to queue[size]). + */ + private int size = 0; + + /** + * Returns the number of tasks currently on the queue. + */ + int size() { + return size; + } + + /** + * Adds a new task to the priority queue. + */ + void add(TimerTask task) { + // Grow backing store if necessary + if (size + 1 == queue.length) + queue = Arrays.copyOf(queue, 2 * queue.length); + + queue[++size] = task; + fixUp(size); + } + + /** + * Return the "head task" of the priority queue. (The head task is an task with the lowest nextExecutionTime.) + */ + TimerTask getMin() { + return queue[1]; + } + + /** + * Return the ith task in the priority queue, where i ranges from 1 (the head task, which is returned by getMin) to + * the number of tasks on the queue, inclusive. + */ + TimerTask get(int i) { + return queue[i]; + } + + /** + * Remove the head task from the priority queue. + */ + void removeMin() { + queue[1] = queue[size]; + queue[size--] = null; // Drop extra reference to prevent memory leak + fixDown(1); + } + + /** + * Removes the ith element from queue without regard for maintaining the heap invariant. Recall that queue is + * one-based, so 1 <= i <= size. + */ + void quickRemove(int i) { + assert i <= size; + + queue[i] = queue[size]; + queue[size--] = null; // Drop extra ref to prevent memory leak + } + + /** + * Sets the nextExecutionTime associated with the head task to the specified value, and adjusts priority queue + * accordingly. + */ + void rescheduleMin(long newTime) { + queue[1].trigger.nextExecutionTime = newTime; + fixDown(1); + } + + /** + * Returns true if the priority queue contains no elements. + */ + boolean isEmpty() { + return size == 0; + } + + /** + * Removes all elements from the priority queue. + */ + void clear() { + // Null out task references to prevent memory leak + for (int i = 1; i <= size; i++) + queue[i] = null; + + size = 0; + } + + /** + * Establishes the heap invariant (described above) assuming the heap satisfies the invariant except possibly for + * the leaf-node indexed by k (which may have a nextExecutionTime less than its parent's). + * + * This method functions by "promoting" queue[k] up the hierarchy (by swapping it with its parent) repeatedly until + * queue[k]'s nextExecutionTime is greater than or equal to that of its parent. + */ + private void fixUp(int k) { + while (k > 1) { + int j = k >> 1; + if (queue[j].trigger.nextExecutionTime <= queue[k].trigger.nextExecutionTime) + break; + TimerTask tmp = queue[j]; + queue[j] = queue[k]; + queue[k] = tmp; + k = j; + } + } + + /** + * Establishes the heap invariant (described above) in the subtree rooted at k, which is assumed to satisfy the heap + * invariant except possibly for node k itself (which may have a nextExecutionTime greater than its children's). + * + * This method functions by "demoting" queue[k] down the hierarchy (by swapping it with its smaller child) + * repeatedly until queue[k]'s nextExecutionTime is less than or equal to those of its children. + */ + private void fixDown(int k) { + int j; + while ((j = k << 1) <= size && j > 0) { + if (j < size && queue[j].trigger.nextExecutionTime > queue[j + 1].trigger.nextExecutionTime) + j++; // j indexes smallest kid + if (queue[k].trigger.nextExecutionTime <= queue[j].trigger.nextExecutionTime) + break; + TimerTask tmp = queue[j]; + queue[j] = queue[k]; + queue[k] = tmp; + k = j; + } + } + + /** + * Establishes the heap invariant (described above) in the entire tree, assuming nothing about the order of the + * elements prior to the call. + */ + void heapify() { + for (int i = size / 2; i >= 1; i--) + fixDown(i); + } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/TimeSource.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/TimeSource.java new file mode 100644 index 0000000..488fb87 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/TimeSource.java @@ -0,0 +1,11 @@ +package com.serotonin.timer; + +/** + * An interface to abstract the source of current time away from System. This allows code to run in simulations where + * the time is controlled explicitly. + * + * @author Matthew Lohbihler + */ +public interface TimeSource { + long currentTimeMillis(); +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/TimerTask.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/TimerTask.java new file mode 100644 index 0000000..17648d8 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/TimerTask.java @@ -0,0 +1,167 @@ +package com.serotonin.timer; + +import org.apache.commons.lang3.StringUtils; + +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public abstract class TimerTask implements Runnable { + /** + * This object is used to control access to the TimerTask internals. + */ + Object lock = new Object(); + + /** + * The state of this task, chosen from the constants below. + */ + volatile int state = VIRGIN; + + /** + * This task has not yet been scheduled. + */ + static final int VIRGIN = 0; + + /** + * This task is scheduled for execution. If it is a non-repeating task, it has not yet been executed. + */ + static final int SCHEDULED = 1; + + /** + * This non-repeating task has already executed (or is currently executing) and has not been cancelled. + */ + static final int EXECUTED = 2; + + /** + * This task has been cancelled (with a call to TimerTask.cancel). + */ + static final int CANCELLED = 3; + + TimerTrigger trigger; + private final String name; + + /** + * Indicates that if the task is running at the moment it is cancelled, the cancellation should wait until the task + * is done. This is useful if the task uses resources that need to be shut down before the timer is shutdown. + */ + private boolean completeBeforeCancel; + + private final ReadWriteLock cancelLock = new ReentrantReadWriteLock(); + + public TimerTask(TimerTrigger trigger) { + this(trigger, null); + } + + public TimerTask(TimerTrigger trigger, String name) { + if (trigger == null) + throw new NullPointerException(); + this.trigger = trigger; + this.name = name; + } + + public boolean isCompleteBeforeCancel() { + return completeBeforeCancel; + } + + public void setCompleteBeforeCancel(boolean completeBeforeCancel) { + this.completeBeforeCancel = completeBeforeCancel; + } + + /** + * Cancels this timer task. If the task has been scheduled for one-time execution and has not yet run, or has not + * yet been scheduled, it will never run. If the task has been scheduled for repeated execution, it will never run + * again. (If the task is running when this call occurs, the task will run to completion, but will never run again.) + * + *

+ * Note that calling this method from within the run method of a repeating timer task absolutely guarantees + * that the timer task will not run again. + * + *

+ * This method may be called repeatedly; the second and subsequent calls have no effect. + * + * @return true if this task is scheduled for one-time execution and has not yet run, or this task is scheduled for + * repeated execution. Returns false if the task was scheduled for one-time execution and has already run, + * or if the task was never scheduled, or if the task was already cancelled. (Loosely speaking, this method + * returns true if it prevents one or more scheduled executions from taking place.) + */ + public boolean cancel() { + synchronized (lock) { + boolean result = (state == SCHEDULED); + + if (completeBeforeCancel) { + try { + cancelLock.writeLock().lock(); + state = CANCELLED; + } + finally { + cancelLock.writeLock().unlock(); + } + } + else + state = CANCELLED; + + return result; + } + } + + abstract public void run(long runtime); + + @Override + final public void run() { + // TODO if the task is not called quickly enough, the nextExecutionTime + // may have already been changed. It would + // be better to have the value assigned at the moment the task is + // submitted to the thread pool, but the + // interface doesn't allow it. For now, this will have to do. + long t; + synchronized (lock) { + t = trigger.mostRecentExecutionTime(); + } + + String originalName = null; + try { + if (!StringUtils.isBlank(name)) { + // This uses roughly the same code as in NamedRunnable to rename + // the thread for the duration of the task execution. + originalName = Thread.currentThread().getName(); + + // Append the given name to the original name. + Thread.currentThread().setName(originalName + " --> " + name); + } + + if (completeBeforeCancel) { + try { + cancelLock.readLock().lock(); + if (state != CANCELLED) + run(t); + } + finally { + cancelLock.readLock().unlock(); + } + } + else + // Ok, go ahead and run the thingy. + run(t); + } + finally { + if (originalName != null) + // Return the name to its original. + Thread.currentThread().setName(originalName); + } + } + + public boolean isCancelled() { + return state == CANCELLED; + } + + public long getNextExecutionTime() { + return trigger.nextExecutionTime; + } + + void setTimer(AbstractTimer timer) { + trigger.setTimer(timer); + } + + AbstractTimer getTimer() { + return trigger.getTimer(); + } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java new file mode 100644 index 0000000..b087ad6 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java @@ -0,0 +1,137 @@ +/* + Copyright (C) 2006-2009 Serotonin Software Technologies Inc. + @author Matthew Lohbihler + */ +package com.serotonin.timer.sync; + +import com.serotonin.timer.AbstractTimer; + +/** + * This class is useful when an exclusive, long-running task gets called more often than is practical. For example, a + * large object needs to be persisted, but it changes fairly often. This class will execute the submitted runnable + * if there is currently nothing running. If another task is already running, the new task will wait. If there is + * already a task waiting, the new task will replace the waiting task. So, tasks that are started are always allowed to + * complete, but tasks that are no necessary to run are discarded. + * + * @author Matthew Lohbihler + */ +public class SingleExecutorSingleWaiter { + final AbstractTimer timer; + final Object lock = new Object(); + + Runnable executing; + Runnable waiting; + + public SingleExecutorSingleWaiter(AbstractTimer timer) { + this.timer = timer; + } + + public void execute(Runnable task) { + synchronized (lock) { + if (executing != null) { + waiting = task; + return; + } + + executing = task; + executeImpl(); + } + } + + void executeImpl() { + timer.execute(new TaskWrapper(executing)); + } + + class TaskWrapper implements Runnable { + private final Runnable command; + + public TaskWrapper(Runnable command) { + this.command = command; + } + + @Override + public void run() { + try { + command.run(); + } + finally { + synchronized (lock) { + if (waiting != null) { + executing = waiting; + waiting = null; + executeImpl(); + } + else + executing = null; + } + } + } + } + // + // public static void main(String[] args) throws Exception { + // ExecutorService executorService = Executors.newCachedThreadPool(); + // RealTimeTimer timer = new RealTimeTimer(); + // timer.init(executorService); + // + // SingleExecutorSingleWaiter e = new SingleExecutorSingleWaiter(timer); + // TestRunnable r1 = new TestRunnable(1); + // TestRunnable r2 = new TestRunnable(2); + // TestRunnable r3 = new TestRunnable(3); + // TestRunnable r4 = new TestRunnable(4); + // TestRunnable r5 = new TestRunnable(5); + // TestRunnable r6 = new TestRunnable(6); + // TestRunnable r7 = new TestRunnable(7); + // TestRunnable r8 = new TestRunnable(8); + // TestRunnable r9 = new TestRunnable(9); + // + // e.execute(r1); // 1 + // e.execute(r2); // 2 + // e.execute(r3); // 3 + // e.execute(r4); // 3 + // + // Thread.sleep(1000); + // e.execute(r5); // 3 + // + // Thread.sleep(1500); + // e.execute(r6); // 2 + // + // Thread.sleep(4000); + // e.execute(r7); // 1 + // e.execute(r8); // 2 + // e.execute(r9); // 3 + // + // // Running 1 + // // Finished 1 + // // Running 5 + // // Finished 5 + // // Running 6 + // // Finished 6 + // // Running 7 + // // Finished 7 + // // Running 9 + // // Finished 9 + // + // Thread.sleep(4000); + // timer.cancel(); + // executorService.shutdown(); + // } + // + // static class TestRunnable implements Runnable { + // int id; + // + // public TestRunnable(int id) { + // this.id = id; + // } + // + // @Override + // public void run() { + // System.out.println("Running " + id); + // try { + // Thread.sleep(2000); + // } + // catch (InterruptedException e) { + // } + // System.out.println("Finished " + id); + // } + // } +} diff --git a/smtweb-framework/core/src/main/java/com/serotonin/timer/sync/Synchronizer.java b/smtweb-framework/core/src/main/java/com/serotonin/timer/sync/Synchronizer.java new file mode 100644 index 0000000..5a9e7c4 --- /dev/null +++ b/smtweb-framework/core/src/main/java/com/serotonin/timer/sync/Synchronizer.java @@ -0,0 +1,235 @@ +package com.serotonin.timer.sync; + +import com.serotonin.timer.AbstractTimer; +import com.serotonin.timer.RealTimeTimer; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * This class acts as a synchronizing monitor where an arbitrary number of tasks can be added with string identifiers. + * Then, the tasks can be executed using the provided executor and the calling thread will be blocked until they are all + * completed, after which then tasks can be asked for by name to get their results. + * + * This allows parts of processing that would benefit from being asynchronous - such as database concurrency - to easily + * be managed by a controlling thread. + * + * @author Matthew Lohbihler + * + * @param + * a task object that implements Runnable + */ +public class Synchronizer { + private final List tasks = new ArrayList(); + + // A lock that is used when there are more tasks to run than allowed concurrently. This monitor notifies the + // completion of any task. + final Object multiLock = new Object(); + + private final int maxConcurrent; + + public Synchronizer() { + this(0); + } + + public Synchronizer(int maxConcurrent) { + this.maxConcurrent = maxConcurrent; + } + + public void addTask(T task) { + addTask(null, task); + } + + public void addTask(String name, T task) { + tasks.add(new TaskWrapper(name, task)); + } + + public void executeAndWait(AbstractTimer timer) { + List running; + + if (maxConcurrent <= 0 || tasks.size() <= maxConcurrent) { + // Start all of the tasks. + for (TaskWrapper tw : tasks) + timer.execute(tw); + running = tasks; + } + else { + List remaining = new ArrayList(tasks); + running = new ArrayList(); + + // We have more tasks to run than we can run concurrently. We need a polling method to monitor the tasks. + while (!remaining.isEmpty()) { + // Start tasks + while (running.size() < maxConcurrent && !remaining.isEmpty()) { + TaskWrapper tw = remaining.remove(remaining.size() - 1); + timer.execute(tw); + running.add(tw); + } + + // Wait for completed tasks. + while (true) { + synchronized (multiLock) { + boolean completions = false; + for (int i = running.size() - 1; i >= 0; i--) { + TaskWrapper tw = running.get(i); + synchronized (tw) { + if (tw.isComplete()) { + running.remove(i); + completions = true; + } + } + } + + if (completions) + // Completed task(s) were found, so break. + break; + + // No tasks completed, so wait for a notification. + try { + multiLock.wait(); + } + catch (InterruptedException e) { + // no op + } + } + } + } + } + + // Wait for the tasks to complete. + for (TaskWrapper tw : running) { + synchronized (tw) { + try { + if (!tw.isComplete()) { + // System.out.println("Waiting on " + tw.task); + tw.wait(); + } + } + catch (InterruptedException e) { + // no op + } + } + } + } + + public T getTask(String name) { + for (TaskWrapper tw : tasks) { + if (StringUtils.equals(name, tw.name)) + return tw.task; + } + return null; + } + + public int getSize() { + return tasks.size(); + } + + public List getTasks() { + List result = new ArrayList(); + for (TaskWrapper tw : tasks) + result.add(tw.task); + return result; + } + + class TaskWrapper implements Runnable { + final String name; + final T task; + private volatile boolean complete; + + public TaskWrapper(String name, T task) { + this.name = name; + this.task = task; + } + + public String getName() { + return name; + } + + @Override + public void run() { + try { + task.run(); + } + finally { + synchronized (this) { + complete = true; + notify(); + } + synchronized (multiLock) { + multiLock.notify(); + } + } + } + + public boolean isComplete() { + return complete; + } + } + + public static void main(String[] args) { + Synchronizer synchronizer = new Synchronizer(20); + synchronizer.addTask("A", new TestTask("a", 4000)); + synchronizer.addTask("B", new TestTask("b", 5000)); + synchronizer.addTask("C", new TestTask("c", 10000)); + synchronizer.addTask("D", new TestTask("d", 3000)); + synchronizer.addTask("E", new TestTask("e", 1000)); + synchronizer.addTask("F", new TestTask("f", 70)); + synchronizer.addTask("G", new TestTask("g", 1)); + synchronizer.addTask("H", new TestTask("h", 10)); + synchronizer.addTask("I", new TestTask("i", 100)); + synchronizer.addTask("J", new TestTask("j", 800)); + synchronizer.addTask("K", new TestTask("k", 40)); + synchronizer.addTask("L", new TestTask("l", 250)); + synchronizer.addTask("M", new TestTask("m", 300)); + synchronizer.addTask("N", new TestTask("n", 700)); + synchronizer.addTask("O", new TestTask("o", 700)); + synchronizer.addTask("P", new TestTask("p", 700)); + synchronizer.addTask("Q", new TestTask("q", 4)); + synchronizer.addTask("R", new TestTask("r", 5)); + synchronizer.addTask("S", new TestTask("s", 6)); + synchronizer.addTask("T", new TestTask("t", 7)); + + RealTimeTimer timer = new RealTimeTimer(); + ExecutorService executor = Executors.newCachedThreadPool(); + timer.init(executor); + + System.out.println("*** Begin"); + synchronizer.executeAndWait(timer); + System.out.println("*** Done"); + + timer.cancel(); + executor.shutdown(); + } + + static long start = System.currentTimeMillis(); + + static class TestTask implements Runnable { + private final String id; + private final long sleepTime; + + public TestTask(String id, long sleepTime) { + this.id = id; + this.sleepTime = sleepTime; + } + + @Override + public void run() { + System.out.println((System.currentTimeMillis() - start) + ": started " + id); + try { + Thread.sleep(sleepTime); + } + catch (InterruptedException e) { + // no op + } + System.out.println((System.currentTimeMillis() - start) + ": ended " + id); + } + + @Override + public String toString() { + return id; + } + } +} diff --git a/smtweb-framework/core/src/main/resources/META-INF/spring.factories b/smtweb-framework/core/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..341ca1d --- /dev/null +++ b/smtweb-framework/core/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cc.smtweb.framework.core.CoreAutoConfiguration diff --git a/smtweb-framework/core/src/main/resources/config/application-dev.yaml b/smtweb-framework/core/src/main/resources/config/application-dev.yaml new file mode 100644 index 0000000..bf8c0cf --- /dev/null +++ b/smtweb-framework/core/src/main/resources/config/application-dev.yaml @@ -0,0 +1,61 @@ +smtweb: + machine-id: 1 + file: + local-path: /data/files/smart/ + host: http://127.0.0.1 + url: ${smtweb.file.host}:${server.port}${server.servlet.context-path}/${smtweb.file.local-path} + db: + type: mysql + default: + rule: + prefix: _smt_ + replace: smt_ +server: + port: 8888 + servlet: + context-path: / +logging: + level: + root: INFO + cc.smtweb: DEBUG +spring: + # 设置服务名 + application: + name: smtweb_core + main: + allow-bean-definition-overriding: true + mvc: + static-path-pattern: /static/** + redis: + name: ${smtweb.machine-id} + host: 127.0.0.1 + port: 6379 + password: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/smt_asp?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false + username: root + password: root + servlet: + multipart: + max-file-size: 104857600000 + max-request-size: 10485760000000 +# profiles: +# include: role + cache: + type: caffeine + cache-names: + - core + caffeine: + spec: maximumSize=1024,expireAfterWrite=2h +park: + secret: + key: null +# key: cmVmb3JtZXJyZWZvcm1lcg== +swagger: + name: smtweb-core + version: 2.0 + enabled: true + + + diff --git a/smtweb-framework/core/src/main/resources/config/application-prod.yaml b/smtweb-framework/core/src/main/resources/config/application-prod.yaml new file mode 100644 index 0000000..eaed90b --- /dev/null +++ b/smtweb-framework/core/src/main/resources/config/application-prod.yaml @@ -0,0 +1,52 @@ +sme: + machine-id: 1 + file-local-path: /data/files/smart/ + file-host: http://member.sumi168.cn + file-url: ${sme.file-host}:${server.port}${server.servlet.context-path}/${sme.file-local-path} + +server: + port: 10001 + servlet: + context-path: /user + +feign: + hystrix: + enabled: false +logging: + level: + smtweb: DEBUG + +spring: + # 设置服务名 + application: + name: smtweb-user + main: + allow-bean-definition-overriding: true + mvc: + static-path-pattern: /static/** + redis: + host: 127.0.0.1 + port: 6379 + datasource: + user: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/smt_user?useUnicode=true&characterEncoding=utf-8&useTimezone=true&serverTimezone=CTT&allowMultiQueries=true + username: smt + password: smt_123456 + + servlet: + multipart: + max-file-size: 104857600000 + max-request-size: 10485760000000 + +swagger: + name: smart + version: 1.0.1 + enabled: false + +weixin: + url: http://devpk.smart.smefdd.com + appId: wx8d11474c01b92378 + appSecret: e1fa7bcdf27b46e7d69edad68ea8724b + + diff --git a/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/DaoTransTest.java b/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/DaoTransTest.java new file mode 100644 index 0000000..0d227cf --- /dev/null +++ b/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/DaoTransTest.java @@ -0,0 +1,30 @@ +package cc.smtweb.framework.test; + + +import cc.smtweb.framework.core.common.SwMap; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("TransSql测试") +public class DaoTransTest { + + @Test + public void testSelect() { + + } + + @Test + public void testMapClass() { + boolean ret = call(SwMap.class); + + System.out.println(ret); + } + + private boolean call(Class clazz) { + if (java.util.Map.class.isAssignableFrom(clazz)) { + return true; + } + + return false; + } +} diff --git a/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/NamedJdbcTest.java b/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/NamedJdbcTest.java new file mode 100644 index 0000000..fc2bfa6 --- /dev/null +++ b/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/NamedJdbcTest.java @@ -0,0 +1,30 @@ +package cc.smtweb.framework.test; + +import cc.smtweb.framework.core.CoreApplication; +import cc.smtweb.framework.core.db.DbEngine; +import cc.smtweb.framework.core.db.impl.DefaultEntity; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by Akmm at 2022/4/24 14:58 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = CoreApplication.class) +public class NamedJdbcTest { + @Test + public void testSelect() { + List list = DbEngine.getInstance().query("select * from asp_model_project", DefaultEntity.class); + System.out.println(list.size()); + Map params = new HashMap<>(); + params.put("id", 1); + list = DbEngine.getInstance().queryN("select * from asp_model_project where prj_id=:id", params, DefaultEntity.class); + System.out.println(list.size()); + } +} diff --git a/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/SqlBuilderTest.java b/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/SqlBuilderTest.java new file mode 100644 index 0000000..8ad25ee --- /dev/null +++ b/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/SqlBuilderTest.java @@ -0,0 +1,69 @@ +package cc.smtweb.framework.test; + + +import cc.smtweb.framework.core.db.sqlbuilder.SelectSqlBuilder; +import cc.smtweb.framework.core.db.sqlbuilder.SqlBuilder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("SqlBuilder测试") +public class SqlBuilderTest { + + @Test + public void select() { + SelectSqlBuilder sb = SqlBuilder.createSelect("sw_im_log.im_user_msg_log"); + sb.add("uml_Id,uml_content"); + sb.addWhereOrBegin(); + sb.addWhere("uml_small_uid", 1); + sb.addWhere("uml_big_uid", 2); + sb.addWhereOrEnd(); + + sb.exec((sql, params) -> { + Assertions.assertEquals("select uml_Id,uml_content from sw_im_log.im_user_msg_log where (uml_small_uid=? or uml_big_uid=?)", sql); + return true; + }); + + sb = SqlBuilder.createSelect("sw_im_log.im_user_msg_log"); + sb.add("uml_Id,uml_content"); + sb.addWhere("uml_time", 1); + sb.addWhereOrBegin(); + sb.addWhere("uml_small_uid", 2); + sb.addWhere("uml_big_uid", 3); + sb.addWhereOrEnd(); + sb.addWhere("uml_id", 4); + + sb.exec((sql, params) -> { + Assertions.assertEquals("select uml_Id,uml_content from sw_im_log.im_user_msg_log where uml_time=? and (uml_small_uid=? or uml_big_uid=?) and uml_id=?", sql); + return true; + }); + + sb = SqlBuilder.createSelect("sw_im_log.im_user_msg_log"); + sb.add("uml_Id,uml_content"); + sb.addWhere("uml_time", 1); + sb.addWhereOrBegin(); + sb.addWhere("uml_small_uid", 2); + sb.addWhere("uml_big_uid", 3); + sb.addWhereOrEnd(); + + sb.exec((sql, params) -> { + Assertions.assertEquals("select uml_Id,uml_content from sw_im_log.im_user_msg_log where uml_time=? and (uml_small_uid=? or uml_big_uid=?)", sql); + return true; + }); + + sb = SqlBuilder.createSelect("sw_im_log.im_user_msg_log"); + sb.add("uml_Id,uml_content"); + sb.addWhereOrBegin(); + sb.addWhere("uml_small_uid", 2); + sb.addWhere("uml_big_uid", 3); + sb.addWhereOrEnd(); + sb.addWhere("uml_id", 4); + + sb.exec((sql, params) -> { + Assertions.assertEquals("select uml_Id,uml_content from sw_im_log.im_user_msg_log where (uml_small_uid=? or uml_big_uid=?) and uml_id=?", sql); + return true; + }); + + } + +} diff --git a/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/ToolEnum2Js.java b/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/ToolEnum2Js.java new file mode 100644 index 0000000..0b3b1ed --- /dev/null +++ b/smtweb-framework/core/src/test/java/cc/smtweb/framework/test/ToolEnum2Js.java @@ -0,0 +1,118 @@ +package cc.smtweb.framework.test; + + + +import cc.smtweb.framework.core.common.AbstractEnum; +import cc.smtweb.framework.core.common.IntEnum; +import cc.smtweb.framework.core.common.StrEnum; +import cc.smtweb.framework.core.common.SwEnum; +import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; + +/** + * Created by Akmm at 2017/5/12 17:14 + * 枚举类转js定义 + */ +public class ToolEnum2Js { + public static void main(String[] args) throws Exception { + buildJs(SwEnum.class);//传枚举定义类 + } + + private static void buildJs(Class cls) throws Exception { + Class[] classes = cls.getDeclaredClasses();// 获得代表内部类的Class对象组成的数组 + StringBuilder sb = new StringBuilder(); + for (Class clazz : classes) {// 遍历Class对象数组 +// System.out.println("类的标准名称:" + clazz.getCanonicalName()); +// System.out.println("类的修饰符:" + Modifier.toString(clazz.getModifiers())); + Type superClass = clazz.getGenericSuperclass();// 获得直接父类 + +// System.out.print("类的直接继承类:"); + if (superClass.equals(IntEnum.class)) { + buildJsInt(clazz, sb); + }else if (superClass.equals(StrEnum.class)) { + buildJsStr(clazz, sb); + }else if (superClass.getTypeName().startsWith(AbstractEnum.class.getTypeName()+"<")){ + buildJsBean(clazz,sb); + } + + } + System.out.println(sb.substring(1)); + } + + private static void buildJsInt(Class clazz, StringBuilder sb) throws Exception { + IntEnum instance = (IntEnum) clazz.newInstance(); + Field[] fields = clazz.getDeclaredFields();// 获得该类对象的所有非继承域 + if (fields.length == 0) return; + StringBuilder sbc = new StringBuilder(128); + StringBuilder sbDefines = new StringBuilder(128); + for (Field field : fields) { + if (!field.getType().equals(AbstractEnum.IntEnumBean.class)) continue; + AbstractEnum.IntEnumBean value = (AbstractEnum.IntEnumBean) field.get(instance); + sbc.append(",\n").append(field.getName()).append(": ").append(value.value); + sbDefines.append(",\n").append("{ value: ").append(value.value).append(", label: \"").append(value.name).append("\" }"); + } + sb.append("\n").append("export const ").append(clazz.getSimpleName()).append(" = {\n").append(sbc.length()>2?sbc.substring(2):"").append(",\n...useEnumProps([\n").append(sbDefines.length()>2?sbDefines.substring(2):"").append("\n])").append("\n}"); + } + + private static void buildJsStr(Class clazz, StringBuilder sb) throws Exception { + StrEnum instance = (StrEnum) clazz.newInstance(); + Field[] fields = clazz.getDeclaredFields();// 获得该类对象的所有非继承域 + if (fields.length == 0) return; + StringBuilder sbc = new StringBuilder(128); + StringBuilder sbDefines = new StringBuilder(128); + for (Field field : fields) { + if (!field.getType().equals(AbstractEnum.StrEnumBean.class)) continue; + AbstractEnum.StrEnumBean value = (AbstractEnum.StrEnumBean) field.get(instance); + sbc.append(",\n").append(field.getName()).append(": \"").append(value.value).append("\""); + sbDefines.append(",\n").append("{ value: \"").append(value.value).append("\", label: \"").append(value.name).append("\" }"); + } + sb.append("\n").append("export const ").append(clazz.getSimpleName()).append(" = {\n").append(sbc.length()>2?sbc.substring(2):"").append(",\n...useEnumProps([\n").append(sbDefines.length()>2?sbDefines.substring(2):"").append("\n])").append("\n}"); + } + + private static void buildJsBean(Class clazz, StringBuilder sb)throws Exception{ + Object instance = clazz.newInstance(); + Field[] fields = clazz.getDeclaredFields();// 获得该类对象的所有非继承域 + Type type1 = ((ParameterizedTypeImpl) clazz.getGenericSuperclass()).getActualTypeArguments()[0]; + Type type2 = ((ParameterizedTypeImpl) clazz.getGenericSuperclass()).getActualTypeArguments()[1]; + if (fields.length == 0) return; + boolean isNumber = Integer.class.getTypeName().equals(type1.getTypeName()); + StringBuilder sbc = new StringBuilder(128); + StringBuilder sbDefines = new StringBuilder(128); + for (Field field : fields) { + if (!field.getType().equals(type2)) continue; + Object value = field.get(instance); + if (isNumber){ + AbstractEnum.IntEnumBean tempValue = (AbstractEnum.IntEnumBean) field.get(instance); + sbc.append(",\n").append(field.getName()).append(": ").append(tempValue.value); + sbDefines.append(",\n").append("{ value: ").append(tempValue.value).append(", label: \"").append(tempValue.name).append("\""); + }else { + AbstractEnum.StrEnumBean tempValue = (AbstractEnum.StrEnumBean) field.get(instance); + sbc.append(",\n").append(field.getName()).append(": \"").append(tempValue.value).append("\""); + sbDefines.append(",\n").append("{ value: \"").append(tempValue.value).append("\", label: \"").append(tempValue.name).append("\""); + } + // 处理bean + Field[] beanFields = value.getClass().getFields();// 获得该类对象的所有字段 + StringBuilder sbBean = new StringBuilder(); + sbBean.append(" bean: { "); + if(beanFields.length >0 ){ + for(Field beanField: beanFields){ + Object beanValue = beanField.get(value); + String name = beanField.getName(); + sbBean.append("name".equals(name)?"label":name).append(": ").append(formatValue(beanValue)).append(", "); + } + } + sbBean.append("}"); + sbDefines.append(",").append(sbBean.toString()).append(" }"); + } + sb.append("\n").append("export const ").append(clazz.getSimpleName()).append(" = {\n"). + append(sbc.length()>2?sbc.substring(2):"").append(",\n...useEnumProps([\n").append(sbDefines.length()>2?sbDefines.substring(2):"").append("\n])").append("\n}"); + } + private static String formatValue(Object obj){ + if(obj instanceof String){ + return "\""+obj.toString()+"\""; + } + return obj.toString(); + } +} diff --git a/smtweb-framework/sw-framework-core/doc/TODO.mk b/smtweb-framework/sw-framework-core/doc/TODO.mk deleted file mode 100644 index 4f5bf71..0000000 --- a/smtweb-framework/sw-framework-core/doc/TODO.mk +++ /dev/null @@ -1,8 +0,0 @@ -20210710 - -1. 定时器手动触发 (done) -2. 优化BeanReadUtils的TableName预先进行转换 -2. updateEntity支持悲观锁,并能抛出异常 -3. 缓存支持自定义 key -4. 序列号生成器 -5. redis配置database(0~15) (done) diff --git a/smtweb-framework/sw-framework-core/pom.xml b/smtweb-framework/sw-framework-core/pom.xml deleted file mode 100644 index 1c29d60..0000000 --- a/smtweb-framework/sw-framework-core/pom.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - cc.smtweb - sw-framework-core - 3.1.0-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-parent - 2.5.6 - - - - 4.0.0 - - - - UTF-8 - UTF-8 - 1.8 - 1.8 - 1.8 - true - - - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-web - - - - com.fasterxml.jackson.core - jackson-core - - - - org.springframework.boot - spring-boot-starter-jdbc - - - - - io.lettuce - lettuce-core - 6.1.5.RELEASE - - - org.apache.commons - commons-pool2 - 2.11.1 - - - - commons-codec - commons-codec - 1.15 - - - - - com.esotericsoftware - kryo - 4.0.0 - - - org.projectlombok - lombok - 1.18.22 - - - - org.apache.commons - commons-lang3 - 3.12.0 - - - - org.apache.commons - commons-jexl3 - 3.2.1 - - - - org.apache.tika - tika-core - 2.1.0 - - - - com.github.ben-manes.caffeine - caffeine - - - - mysql - mysql-connector-java - 8.0.27 - runtime - - - commons-collections - commons-collections - 3.2.2 - compile - - - - org.junit.platform - junit-platform-launcher - 1.6.2 - test - - - - org.junit.jupiter - junit-jupiter-api - 5.6.2 - test - - - - org.junit.jupiter - junit-jupiter-engine - 5.6.2 - test - - - org.junit.vintage - junit-vintage-engine - 5.6.2 - test - - - org.junit.jupiter - junit-jupiter-params - 5.6.2 - test - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - verify - - jar-no-fork - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - config/*.yaml - - - - - - - - - - - - - - - - - - - nexus-releases - Nexus Release Repository - http://47.92.149.153:7000/repository/maven-releases/ - - - nexus-snapshots - Nexus Snapshot Repository - http://47.92.149.153:7000/repository/maven-snapshots/ - - - diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplication.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplication.java deleted file mode 100644 index 5c73f81..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplication.java +++ /dev/null @@ -1,11 +0,0 @@ -package cc.smtweb.framework.core; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class CoreApplication { - public static void main(String[] args) { - SpringApplication.run(CoreApplication.class, args); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java deleted file mode 100644 index e53645a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java +++ /dev/null @@ -1,37 +0,0 @@ -package cc.smtweb.framework.core; - -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.db.impl.DatabaseUtil; -import cc.smtweb.framework.core.mvc.controller.scan.ApplicationScanner; -import cc.smtweb.framework.core.systask.TaskStartEvent; -import cc.smtweb.framework.core.systask.WebStartedEvent; -import lombok.SneakyThrows; -import org.springframework.boot.context.event.ApplicationStartedEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.stereotype.Component; - -/** - * 执行接口扫描任务 - */ -@Component -public class CoreApplicationStartedListener implements ApplicationListener { - @SneakyThrows - @Override - public void onApplicationEvent(ApplicationStartedEvent event) { - System.out.println("onApplicationEvent============="); - ConfigurableApplicationContext applicationContext = event.getApplicationContext(); - - applicationContext.publishEvent(new TaskStartEvent()); - //包扫描 - ApplicationScanner.scan(applicationContext); - //初始化数据库 - new DatabaseUtil(true, false).checkDb(); - //初始化缓存 - CacheManager.getIntance().init(); - - // 通知 controller 正式使用 - applicationContext.publishEvent(new WebStartedEvent()); - System.out.println("start end============="); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreAutoConfiguration.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreAutoConfiguration.java deleted file mode 100644 index f576544..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreAutoConfiguration.java +++ /dev/null @@ -1,33 +0,0 @@ -package cc.smtweb.framework.core; - -import cc.smtweb.framework.core.db.jdbc.IdGenerator; -import cc.smtweb.framework.core.mvc.config.ControllerConfig; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.EnableScheduling; - -/** - * @author kevin - */ -@Configuration -@ComponentScan -@EnableScheduling -public class CoreAutoConfiguration { - /** - * ID生成器的分步式机器码(1-1023) - */ - @Value("${smtweb.machine-id}") - private int machineId; - - @Bean - public IdGenerator idGenerator() { - return new IdGenerator(machineId); - } - - @Bean - public ControllerConfig coreControllerConfig() { - return new ControllerConfig("core", "cc.smtweb.framework.core"); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwAction.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwAction.java deleted file mode 100644 index 112ed75..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwAction.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 配置在@SwService中的函数,对应API请求,默认公用函数不用配置拦截器的函数, - * 也可以作为拦截实现的基类 - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) -public @interface SwAction { - /** - * 重写API请求地址,不配置使用: 服务类地址 + “/” + 函数名 - * @return API请求地址 - */ - String value() default ""; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwAttr.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwAttr.java deleted file mode 100644 index e9c3675..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwAttr.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.*; - -/** - * 参数注解,request定制的上下文内容,定制使用 - * @author kevin - * - */ - -@Target( { ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface SwAttr { - String value() default ""; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwBean.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwBean.java deleted file mode 100644 index 31b4376..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwBean.java +++ /dev/null @@ -1,22 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 被该注释修饰的类提供服务,如Dao,Service等 - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD}) -public @interface SwBean { - String value() default ""; - - /** - * 是否强行生成对象,不检查单例 - * @return 是否强行生成对象 - */ - boolean alwaysCreate() default false; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwBody.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwBody.java deleted file mode 100644 index 50ff91b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwBody.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.*; - -/** - * 参数注解,当编译器无法找到参数名称时,需要用该注解标明参数名称,当然你也可以用该参数标注参数别名与表单域字段名同意 - * @author kevin - * - */ -@Target( { ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface SwBody { - String value() default ""; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwCache.java deleted file mode 100644 index b6dbbd4..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwCache.java +++ /dev/null @@ -1,26 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 被该注释修饰的类提供缓存服务 - * - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface SwCache { - //唯一标识 - String ident(); - //标题,展示用 - String title(); - //依赖的缓存ident,多个用英文逗号分隔 - String depends() default ""; - //是否懒加载 - boolean lazy() default false; - //失效时间,单位分钟 - long timeout() default 0; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwColumn.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwColumn.java deleted file mode 100644 index c4d88ed..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwColumn.java +++ /dev/null @@ -1,38 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 被该注释修饰的方法对应了字段名和类型 - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD}) -public @interface SwColumn { - String value() default ""; - - /** 字段作用,前端用RefType表示 */ - Type[] type() default {}; - - public static enum Type { - // 主键 - ID, - // 上级ID,树结构需要 - PARENT_ID, - // 排序字段,树结构需要 - ORDER, - // 编码字段 - CODE, - // 名词字段 - NAME, - // 主表ID,MapToOne - MASTER_ID, - // 创建时间 - CREATE_TIME, - // 更新时间 - LAST_TIME, - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwColumnForeign.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwColumnForeign.java deleted file mode 100644 index fa1ada1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwColumnForeign.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 被该注释修饰的方法对应了外键表名和字段名,名称可选 - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD}) -public @interface SwColumnForeign { - // 外键表名 - String table() default ""; - // ID字段名 - String id() default ""; - // 唯一名称字段名 - String code() default ""; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwConstruct.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwConstruct.java deleted file mode 100644 index ed9eef5..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwConstruct.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 通过对@SwService/@SwBean类中的函数注解,服务启动时会调用一次被注解的函数 - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) -public @interface SwConstruct { - /** - * 销毁顺序,值越小越先创建 - * @return 销毁顺序值 - */ - int order() default 0; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwDestroy.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwDestroy.java deleted file mode 100644 index da89811..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwDestroy.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 通过对@SwService/@SwBean类中的函数注解,服务停止时会调用一次被注解的函数 - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) -public @interface SwDestroy { - /** - * 销毁顺序,值越大越先销毁 - * @return 销毁顺序值 - */ - int order() default 0; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwHeaderParam.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwHeaderParam.java deleted file mode 100644 index 69af9d4..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwHeaderParam.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.*; - - -/** - * 路径注解 - * @author kevin - * - */ -@Target( { ElementType.PARAMETER, ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface SwHeaderParam { - String value() default ""; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwParam.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwParam.java deleted file mode 100644 index 033d671..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwParam.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.*; - - -/** - * 参数注解,当编译器无法找到参数名称时,需要用该注解标明参数名称,当然你也可以用该参数标注参数别名与表单域字段名同意 - * @author kevin - * - */ -@Target( { ElementType.PARAMETER, ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface SwParam { - String value() default ""; - /** 注入类型,有多个类实现/子类时使用 */ - Class type() default Object.class; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwPathParam.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwPathParam.java deleted file mode 100644 index c4ced93..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwPathParam.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.*; - - -/** - * 路径注解 - * @author kevin - * - */ -@Target( { ElementType.PARAMETER, ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface SwPathParam { -// String value() default ""; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwPerm.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwPerm.java deleted file mode 100644 index 0ef2c48..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwPerm.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 被该注释修饰的方法都会经过切面拦截校验权限,默认是需要已登录权限 - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.TYPE}) -public @interface SwPerm { - /** 无权限控制的值,在函数上注解@SwPerm(SwPerm.NONE) */ - static final String NONE = "*"; - static final String SESSION = ""; - - /** 权限定义值 */ - String value() default SESSION; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwScheduling.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwScheduling.java deleted file mode 100644 index 261f1f0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwScheduling.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 通过对@SwService/@SwBean类中的函数注解,定时任务方法注解 - * - * @author xkliu - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(value={ElementType.METHOD}) -public @interface SwScheduling { - /** - * 时间触发条件,如果值是单数字就是用秒定时,否则就是采用linux/unux crondtab 样式 - */ - String value(); - - /** - * 定时任务分组条件, 有值时同一分组不允许并发执行 - */ - String group() default ""; - - /** - * 是否支持多服务同时运行 - */ - boolean multiServer() default false; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwService.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwService.java deleted file mode 100644 index ba25e6c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwService.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 被该注释修饰的类提供控制器服务 - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface SwService { - String value() default ""; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwTable.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwTable.java deleted file mode 100644 index 464f322..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/annotation/SwTable.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.smtweb.framework.core.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 被该注释修饰的类对应了数据库表名(库+表的形式,如 sw_user.sys_user) - * @author kevin - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface SwTable { - /** 库名+表名 */ - String value() default ""; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java deleted file mode 100644 index 8ba38ba..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java +++ /dev/null @@ -1,515 +0,0 @@ -package cc.smtweb.framework.core.cache; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.redis.RedisBroadcastEvent; -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.util.CommUtil; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.github.benmanes.caffeine.cache.LoadingCache; -import com.github.benmanes.caffeine.cache.Scheduler; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.checkerframework.checker.nullness.qual.NonNull; - -import java.io.Serializable; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * 封装caffeine的抽象Cache类,实现内存缓存,并支持用redis广播进行数据缓存同步 - * - * @param <> 缓存的值类 - * @author zhenggm - */ -@Slf4j -public abstract class AbstractCache implements ISwCache { - - protected final static int LS_NONE = 0; - protected final static int LS_LOADING = 1; - protected final static int LS_LOADED = 2; - - //唯一标识 - protected String ident; - //展示名称 - protected String title; - //是否懒加载,懒加载时,将不从库loadall - protected boolean lazy; - //依赖 - protected String[] depends; - - //数据加载状态 - private short loadStatu = LS_NONE; - protected Class pTypeClass = null; - - - private LoadingCache cache; - private Map cacheOrg = new ConcurrentHashMap<>(); - //本地缓存对象,按List缓存,减轻redis压力 - protected Map> mapListLocal = new ConcurrentHashMap<>(); - //本地按其他键值缓存的对象 - protected Map> mapMapLocal = new ConcurrentHashMap<>(); - - /*注册要按list缓存的信息,key=list的类别,按什么字段来缓存。IGetBeanKey为根据bean获取此bean的key - 如资金科目明细项,需按资金科目缓存List。key=sc,value=class_id - */ - protected Map> mapListReg = new HashMap<>(); - protected Map> mapListRegEx = new HashMap<>(); - protected Map> mapMapReg = new HashMap<>(); - - public AbstractCache() { - pTypeClass = CommUtil.getParameterizedType(getClass()); - } - - //注册 - protected void install(ScheduledExecutorService executorService) { - SwCache swCache = this.getClass().getAnnotation(SwCache.class); - if (swCache != null) { - ident = swCache.ident(); - title = swCache.title(); - lazy = swCache.lazy(); - depends = StringUtils.split(swCache.depends(), ","); - } - final @NonNull Caffeine kvCaffeine = Caffeine.newBuilder() - .scheduler(Scheduler.forScheduledExecutorService(executorService)); - if (swCache != null && swCache.timeout() > 0) { - kvCaffeine.expireAfterAccess(swCache.timeout(), TimeUnit.MINUTES); - } - this.cache = kvCaffeine.build(this::onLoad); - } - - public boolean isNotInited() { - return loadStatu == LS_NONE; - } - - /** - * 注册标识,用于同步数据事件通知 - */ - public String getIdent() { - return ident; - } - - public String getTitle() { - return title; - } - - public boolean isLazy() { - return lazy; - } - - public String[] getDepends() { - return depends; - } - - /** - * 初始化 - * redis有,则从redis下载; - * 否则,非lazy,从数据库加载,并更新redis - */ - protected void init() { - if (RedisManager.getInstance().exists(getIdent())) { - log.info("从redis同步缓存!(" + getTitle() + ")"); - //从缓存服务器下载到本地 - syncCache(); - } else if (!lazy) { - log.info("从数据库同步缓存!(" + getTitle() + ")"); - refresh(); - } - } - - /** - * 注册其他key的List缓存,如tree的children - * - * @param key - * @param iGetBeanKey - */ - protected void regList(String key, IGetBeanKey iGetBeanKey) { - mapListReg.put(key, iGetBeanKey); - } - - protected void regListEx(String key, IGetBeanKeys iGetBeanKey) { - mapListRegEx.put(key, iGetBeanKey); - } - - /** - * 注册其他key的Map缓存,如按code缓存 - * - * @param key - * @param iGetBeanKey - */ - - protected void regMap(String key, IGetBeanKey iGetBeanKey) { - mapMapReg.put(key, iGetBeanKey); - } - - //获取bean的id - protected abstract String getId(T bean); - - /** - * 从redis获取全部缓存 - * redis上只保留,拉下来后,自行组织其他格式缓存 - */ - public void syncCache() { - loadStatu = LS_LOADING; - - cache.invalidateAll(); - cacheOrg.clear(); - mapListLocal.clear(); - mapMapLocal.clear(); - - List vals = RedisManager.getInstance().hVals(getIdent()); - for (byte[] v : vals) { - T bean = CommUtil.readObject(v, pTypeClass); - doUpdate(bean); - } - loadStatu = LS_LOADED; - } - - /** - * 监听redis同步事件 - * - * @param event - */ - public void syncCache(RedisBroadcastEvent event) { - //加载中,忽略 - if (loadStatu == LS_LOADING) { - log.info("加载中,忽略本次同步通知:" + event.toString()); - return; - } - switch (event.getAction()) { - case RedisBroadcastEvent.CODE_REMOVE: - doRemove(event.getKey()); - break; - case RedisBroadcastEvent.CODE_CLEAR: - doClear(); - break; - case RedisBroadcastEvent.CODE_CACHE_UPDATE: - T bean = RedisManager.getInstance().hGet(getIdent(), event.getKey(), pTypeClass); - if (bean != null) { - doRemove(getId(bean)); - doUpdate(bean); - } - break; - case RedisBroadcastEvent.CODE_CACHE_REFRESH: - syncCache(); - break; - default: - throw new IllegalStateException("Unexpected value: " + event.getAction()); - } - } - - - /** - * 通过指定的key获取缓存对象值 - * - * @param key 缓存key值 - * @return 缓存对象值 - */ - protected T load(String key) { - return null; - } - - /** - * 从数据库加载全部,lazy模式可以不用实现 - */ - protected List loadAll() { - return null; - } - - /** - * @param key - * @return - */ - private T onLoad(String key) { - if (lazy) {//非懒加载,不管 - T result = load(key); - - if (result != null) { - this.put(result); - } - - return result; - } - return null; - } - - /** - * 删除时,需要拿原来的对象;对象被取出后,可能被修改 - * - * @param key - * @return - */ - public T getOrg(String key) { - return cacheOrg.get(key); - } - - /** - * 本地删除缓存 - * - * @param key - */ - protected void doRemove(String key) { - T oldbean = getOrg(key); - T bean = get(key); - if (bean != null) { - for (Map.Entry> entry : mapListReg.entrySet()) { - doRemoveList(entry.getKey(), getBeanKey(entry.getValue(), oldbean), bean); - } - - for (Map.Entry> entry : mapListRegEx.entrySet()) { - String[] keys = entry.getValue().getKey(oldbean); - for (String k: keys) { - doRemoveList(entry.getKey(), k, bean); - } - } - - for (Map.Entry> entry : mapMapReg.entrySet()) { - doRemoveMap(entry.getKey(), getBeanKey(entry.getValue(), oldbean)); - } - } - cache.invalidate(key); - cacheOrg.remove(key); - } - - /** - * 插入新对象 - */ - protected void doUpdate(T value) { - final String key = getId(value); - cache.put(key, value); - cacheOrg.put(key, CommUtil.cloneObj(value, pTypeClass)); - - for (Map.Entry> entry : mapListReg.entrySet()) { - doUpdateList(entry.getKey(), getBeanKey(entry.getValue(), value), value); - } - - for (Map.Entry> entry : mapListRegEx.entrySet()) { - String[] keys = entry.getValue().getKey(value); - for (String k: keys) { - doUpdateList(entry.getKey(), k, value); - } - } - - for (Map.Entry> entry : mapMapReg.entrySet()) { - doUpdateMap(entry.getKey(), getBeanKey(entry.getValue(), value), value); - } - } - - //本地调用,删除一个对象时,更新列表缓存 - private void doRemoveList(String regionKey, String key, T value) { - if (StringUtils.isEmpty(key)) return; - Set list = mapListLocal.get(regionKey + SwConsts.SPLIT_CHAR + key); - if (list == null) { - return; - } - list.remove(value); - } - - //本地调用,删除对象时,更新map缓存 - private void doRemoveMap(String regionKey, String key) { - if (StringUtils.isEmpty(key)) return; - Map map = mapMapLocal.get(regionKey); - if (map != null) { - map.remove(key); - } - } - - //本地调用,更新列表缓存 - private void doUpdateList(String regionKey, String key, T value) { - if (StringUtils.isEmpty(key)) return; - Set list = mapListLocal.computeIfAbsent(regionKey + SwConsts.SPLIT_CHAR + key, k -> new LinkedHashSet<>()); - list.add(value); - } - - //本地调用,更新对象时,更新map缓存 - private void doUpdateMap(String regionKey, String key, T value) { - if (StringUtils.isEmpty(key)) return; - Map map = mapMapLocal.computeIfAbsent(regionKey, k -> new HashMap<>()); - map.put(key, value); - } - - /** - * 外部调用,更新缓存:先删除,再更新本地缓存,更新并通知redis - * - * @param bean - */ - public final void put(T bean) { - doRemove(getId(bean)); - doUpdate(bean); - if (loadStatu != LS_LOADING) { - RedisManager.getInstance().hSet(getIdent(), getId(bean), bean); - //通知redis - publishUpdate(getId(bean)); - } - } - - /** - * 将对象重置为修改前的值,用于取出修改后,事务提交失败 - * - * @param bean - */ - public final void reset(T bean) { - final String id = getId(bean); - T b = getOrg(id); - if (b != null) { - cache.put(id, b); - } - } - - @Override - public final T get(String key) { - return cache.get(key); - } - - public final T get(long key) { - return cache.get(String.valueOf(key)); - } - - /** - * 按其他key取bean - * - * @param rk 注册类型 - * @param key - * @return - */ - protected final T getByKey(String rk, String key) { - Map map = mapMapLocal.get(rk); - if (map != null) { - return map.get(key); - } - return null; - } - - public final Set getListByKey(String rk, String key) { - return mapListLocal.get(rk + SwConsts.SPLIT_CHAR + key); - } - - /** - * 通知redis更新:更新单个bean - * - * @param key - */ - protected final void publishUpdate(String key) { - RedisBroadcastEvent message = new RedisBroadcastEvent(); - message.setIdent(getIdent()); - message.setKey(key); - message.setAction(RedisBroadcastEvent.CODE_CACHE_UPDATE); - RedisManager.getInstance().publish(message); - } - - /** - * 通知redis更新:删除单个bean - * - * @param key - */ - @Override - public final void publishRemove(String key) { - RedisBroadcastEvent message = new RedisBroadcastEvent(); - message.setIdent(getIdent()); - message.setKey(key); - message.setAction(RedisBroadcastEvent.CODE_REMOVE); - RedisManager.getInstance().publish(message); - } - - /** - * 通知redis更新:清空缓存 - */ - @Override - public final void publishClear() { - RedisBroadcastEvent message = new RedisBroadcastEvent(); - message.setIdent(getIdent()); - message.setAction(RedisBroadcastEvent.CODE_CLEAR); - RedisManager.getInstance().publish(message); - } - - /** - * 通知redis更新:刷新缓存 * - */ - public final void publishRefresh() { - RedisBroadcastEvent message = new RedisBroadcastEvent(); - message.setIdent(getIdent()); - message.setAction(RedisBroadcastEvent.CODE_CACHE_REFRESH); - RedisManager.getInstance().publish(message); - } - - /** - * 外部调用,删除单个对象 - * - * @param key - */ - public void remove(String key) { - this.doRemove(key); - RedisManager.getInstance().hdel(getIdent(), key); - publishRemove(key); - } - - public void remove(long key) { - remove(String.valueOf(key)); - } - - /** - * 本地调用,清空缓存 - */ - protected void doClear() { - cache.cleanUp(); - cacheOrg.clear(); - mapListLocal.clear(); - mapMapLocal.clear(); - } - - /** - * 外部调用,清空缓存:清空本地缓存,并更新redis,通知其他服务 - */ - public void clear() { - doClear(); - RedisManager.getInstance().del(getIdent()); - publishClear(); - } - - /** - * 重载缓存:先清空,再重载 - */ - public void refresh() { - loadStatu = LS_LOADING; - doClear(); - List list = loadAll(); - if (list != null) { - for (T bean : list) { - doUpdate(bean); - } - } - loadStatu = LS_LOADED; - RedisManager.getInstance().hmSet(getIdent(), cacheOrg); - publishRefresh(); - } - - /** - * 根据接口,得到bean的缓存key - * - * @param iGetBeanKey - * @param bean - * @return - */ - protected String getBeanKey(IGetBeanKey iGetBeanKey, T bean) { - return iGetBeanKey.getKey(bean); - } - - public Collection getAll() { - return cacheOrg.values(); - } - - /** - * 获取bean缓存key的接口类,用于按非id的缓存,如code等 - * - * @param - */ - public interface IGetBeanKey { - String getKey(T bean); - } - - public interface IGetBeanKeys { - String[] getKey(T bean); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractEntityCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractEntityCache.java deleted file mode 100644 index 744b0a1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractEntityCache.java +++ /dev/null @@ -1,54 +0,0 @@ -package cc.smtweb.framework.core.cache; - -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -import java.util.List; - -/** - * Created by Akmm at 2022/6/16 15:53 - */ -public class AbstractEntityCache extends AbstractCache { - @Override - protected String getId(T bean) { - return String.valueOf(bean.getEntityId()); - } - - private String getCacheKey(T bean, String fields) { - String[] fs = fields.split(","); - String ret = ""; - for (String f: fs) { - ret += SwConsts.SPLIT_CHAR + bean.getStr(f); - } - return ret.substring(SwConsts.SPLIT_CHAR.length()); - } - - /** - * 注册其他key的List缓存,如tree的children - * - * @param key - * @param fields - */ - protected void regList(String key, String fields) { - regList(key, bean -> getCacheKey(bean, fields)); - } - - /** - * 注册其他key的Map缓存,如按code缓存 - * - * @param key - * @param fields - */ - - protected void regMap(String key, String fields) { - regMap(key, bean -> getCacheKey(bean, fields)); - } - - @Override - protected List loadAll() { - EntityDao dao = DbEngine.getInstance().findDao(pTypeClass); - return dao.query(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/CacheManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/CacheManager.java deleted file mode 100644 index af521d0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/CacheManager.java +++ /dev/null @@ -1,110 +0,0 @@ -package cc.smtweb.framework.core.cache; - -import cc.smtweb.framework.core.cache.redis.RedisBroadcastEvent; -import cc.smtweb.framework.core.db.cache.EntityCache; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.util.SpringUtil; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.event.EventListener; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - -/** - * 内存缓存管理器,管理lazy加载的缓存,长时间不使用会失效 - */ -@Slf4j -public class CacheManager { - //所有缓存对象 - private final Map cacheMap = new HashMap<>(); - private final Map cacheMapCls = new HashMap<>(); - //记录顺序用 - private List listCache = new ArrayList<>(); - //缓存清理线程池 - private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); - - public AbstractCache getCache(String ident) { - final AbstractCache cache = cacheMap.get(ident.toUpperCase()); - if (cache != null && cache.isNotInited()) { - cache.init(); - } - return cache; - } - - public T getCache(Class clazz) { - final T cache = (T) cacheMapCls.get(clazz); - if (cache != null && cache.isNotInited()) { - cache.init(); - } - return cache; - } - - public static CacheManager getIntance() { - return SpringUtil.getBean(CacheManager.class); - } - - // 初始化cache - public boolean install(AbstractCache cache) { - cache.install(executorService); - if (cacheMap.putIfAbsent(cache.getIdent(), cache) == null) { - cacheMapCls.put(cache.getClass(), cache); - listCache.add(cache); - return true; - } - - return false; - } - - /** - * 启动时的初始化及预加载 - * 1、按依赖关系排序 - * 2、预加载(lazy模式不从库加载) - */ - public void init() { - listCache.sort((o1, o2) -> { - //o1依赖o2 - if (isContains(o1.getDepends(), o2.getIdent())) return 1; - //o2依赖o1 - if (isContains(o2.getDepends(), o1.getIdent())) return -1; - - return 0;//getPluginIndex(o1) - getPluginIndex(o2); - }); - for (AbstractCache cache : listCache) { - if (cache.isNotInited()) { - cache.init(); - } - } - //按表加载并初始化 - for (ModelTable table : ModelTableCache.getInstance().getAll()) { - if (table.isNeedCache() && !cacheMap.containsKey(table.getName())) { - EntityCache cache = new EntityCache(table.getName()); - cache.install(executorService); - cacheMapCls.put(cache.getClass(), cache); - cacheMap.put(table.getName(), cache); - } - } - } - - private boolean isContains(String[] src, String dest) { - if (src == null || src.length == 0) return false; - for (String s : src) { - if (s.trim().equals(dest)) return true; - } - return false; - } - - @EventListener - public void onRedisBroadcastEvent(RedisBroadcastEvent event) { - AbstractCache cache = getCache(event.getIdent()); - if (cache == null) { - log.info("接收到不存在的缓存更新!(" + event.toString() + ")"); - return; - } - cache.syncCache(event); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/ISwCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/ISwCache.java deleted file mode 100644 index 59d3c8a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/ISwCache.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.smtweb.framework.core.cache; - -public interface ISwCache { - /** 权限缓存名称 */ - String REALM_CACHE = "RealmCache"; - - /** - * 根据键值获取缓存对象 - * @param key 缓存唯一键值 - * @return 缓存对象 - */ - V get(K key); - - /** - * 给redis发送广播消息,多服务同步删除相同key值的缓存对象 - * @param key 缓存键值 - */ - void publishRemove(K key); - - /** - * 给redis发送广播消息,多服务同步清空相同类型的缓存对象 - */ - void publishClear(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/SessionCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/SessionCache.java deleted file mode 100644 index 7b32a62..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/SessionCache.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.smtweb.framework.core.cache; - -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; - -import java.util.concurrent.TimeUnit; - -/** - * Created by Akmm at 2022/3/14 10:22 - */ -public class SessionCache { - private Cache cache; - - public SessionCache(long timeout) { - if (timeout <= 0L) timeout = Long.MAX_VALUE; - this.cache = Caffeine.newBuilder() - .expireAfterAccess(timeout, TimeUnit.MINUTES).build(); - } - - public void put(String id, Object bean) { - if (bean != null) cache.put(id, bean); - } - - public void remove(String id) { - cache.invalidate(id); - } - - public void clear() { - cache.invalidateAll(); - } - - @SuppressWarnings({"unchecked"}) - public T get(String id) { - return (T) cache.getIfPresent(id); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/SessionCacheFactory.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/SessionCacheFactory.java deleted file mode 100644 index 8ad6fdc..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/SessionCacheFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -package cc.smtweb.framework.core.cache; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Created by Akmm at 2022/3/14 10:42 - */ -public class SessionCacheFactory { - private static SessionCacheFactory INSTANCE = null; - private Map buffer = new ConcurrentHashMap<>(); - - private SessionCacheFactory() { - } - - /*获取单例*/ - public static SessionCacheFactory getInstance() { - if (INSTANCE == null) { - synchronized (SessionCacheFactory.class) { - if (INSTANCE == null) { - INSTANCE = new SessionCacheFactory(); - } - } - } - return INSTANCE; - } - - //得到用户缓存对象 - public SessionCache getUserCache(long userId) { - return getUserCache(userId, 0L); - } - - public SessionCache getUserCache(long userId, long timeout) { - SessionCache cache; - - cache = buffer.get(userId); - if (cache == null) { - cache = buffer.get(userId); - if (cache != null) return cache; - cache = new SessionCache(timeout); - buffer.put(userId, cache); - } - return cache; - - } - - //删除用户缓存 - public void remove(String userId) { - buffer.remove(userId); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisBroadcastEvent.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisBroadcastEvent.java deleted file mode 100644 index f9d00bf..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisBroadcastEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.smtweb.framework.core.cache.redis; - -import lombok.Data; - -/** - * redis 广播消息 - */ -@Data -public class RedisBroadcastEvent { - public static final int CODE_REMOVE = 1; - public static final int CODE_CLEAR = 2; - /** 缓存更新 */ - public static final int CODE_CACHE_UPDATE = 3; - public static final int CODE_CACHE_REFRESH = 4; - - private int action; - private String ident; - private String key; - - @Override - public String toString() { - return "ident=" + ident + "&&key=" + key + "&&act=" + action; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisConnection.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisConnection.java deleted file mode 100644 index 25a4701..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisConnection.java +++ /dev/null @@ -1,300 +0,0 @@ -package cc.smtweb.framework.core.cache.redis; - -import cc.smtweb.framework.core.util.CommUtil; -import io.lettuce.core.KeyValue; -import io.lettuce.core.SetArgs; -import io.lettuce.core.api.sync.RedisCommands; -import lombok.extern.slf4j.Slf4j; - -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author kevin - */ -@Slf4j -public class RedisConnection { - public static final int DEL_COUNT = 200; - private RedisCommands redis; - - public RedisConnection(RedisCommands redisCommands) { - this.redis = redisCommands; - } - - /** - * 获取指定key对应的值,并更新超时时间 - * - * @param key 关键字KEY - * @return byte[] 对象 - */ - public byte[] get(String key) { - byte[] binKey = getBytes(key); - return redis.get(binKey); - } - -// public T get(String key, Class clazz) { -// byte[] b = get(key); -// if (b != null) { -// return this.readObject(b, clazz); -// } -// -// return null; -// } - - public boolean expire(String key, int expireSec) { - byte[] bkey = getBytes(key); - return redis.expire(bkey, expireSec); - } - - /** - * 设置指定key对应的值,并更新超时时间 - * - * @param key 关键字KEY - * @param value 值 - * @param seconds 超时删除时间(秒) - * @return boolean 是否设置成功 - */ - public boolean set(byte[] key, byte[] value, int seconds) { - if (value != null) { - Boolean result = Boolean.FALSE; - String ret; - if (seconds > 0) { - ret = redis.setex(key, seconds, value); - } else { - ret = redis.set(key, value); - } - - if ("OK".equals(ret)) { - result = Boolean.TRUE; - } - - return result; - } else { - Long ret = redis.del(key); - - return (ret != null && ret == 1L); - } - } - - public boolean setnx(byte[] key, byte[] value, int seconds) { - if (value != null) { - Boolean result = Boolean.FALSE; - String ret; - if (seconds > 0) { - ret = redis.set(key, value, new SetArgs().ex(seconds).nx()); - if ("OK".equals(ret)) { - result = Boolean.TRUE; - } - } else { - result = redis.setnx(key, value); - } - - return result; - } else { - Long ret = redis.del(key); - - return (ret != null && ret == 1L); - } - } - - public boolean setnx(String key, T obj, int seconds) { - return setnx(getBytes(key), CommUtil.writeObject(obj), seconds); - } - - private byte[] getBytes(String key) { - return key.getBytes(StandardCharsets.UTF_8); - } - - /** - * 获取指定key对应的值,并更新超时时间 - * - * @param keys 关键字KEY - * @return byte[] 对象 - */ - public List> mget(String[] keys, int expireSec) { - byte[][] bkeys = new byte[keys.length][]; - for (int i = 0; i < keys.length; i++) { - bkeys[i] = getBytes(keys[i]); - } - - List> result = redis.mget(bkeys); - - if (result != null && expireSec > 0) { - redis.expire(bkeys[0], expireSec); - } - - return result; - } - - /** - * 获取指定key里指定的域对应的值。 此时,key对应的存储对象是map。 - * - * @param key redis关键字KEY - * @param field map的KEY值 - * @return byte[] 对象 - */ - public byte[] hGet(String key, String field) { - return redis.hget(getBytes(key), getBytes(field)); - } - - public List hVals(String key) { - return redis.hvals(getBytes(key)); - } - - public boolean exists(String key) { - return redis.exists(getBytes(key)) == 1; - } - - static byte[] writeObject(Serializable obj) { - return CommUtil.writeObject(obj); - } - - static T readObject(byte[] value, Class clazz) { - return CommUtil.readObject(value, clazz); - } - - public boolean set(String key, T obj, int seconds) { - return set(getBytes(key), CommUtil.writeObject(obj), seconds); - } - - public boolean del(String key) { - Long ret = redis.del(getBytes(key)); - return (ret != null && ret > 0); - } - - public Long delKeys(String... keys) { -// Long[] result = new Long[keys.length]; - - byte[][] batchKey = new byte[keys.length][]; - - for (int i = 0; i < keys.length; i++) { - batchKey[i] = getBytes(keys[i]); - } - - return redis.del(batchKey); - } - - public boolean hSet(String key, byte[] field, byte[] value) { - return redis.hset(getBytes(key), field, value); - } - - private boolean lhmSet(String key, Map values) { - String ret = redis.hmset(getBytes(key), values); - return "OK".equals(ret); - } - - public boolean hmSet(String key, Map values) { - boolean ret = true; - if (values == null || values.isEmpty()) { - return ret; - } - final int size = 200; - Map map = new HashMap<>(size); - int count = 0; - for (Map.Entry e : values.entrySet()) { - map.put(getBytes(e.getKey()), CommUtil.writeObject(e.getValue())); - if (++count >= size) { - ret = ret && lhmSet(key, map); - count = 0; - map.clear(); - } - } - if (count > 0) { - ret = ret && lhmSet(key, map); - } - return ret; - } - - /** - * 获取指定key里指定的域对应的值,并转换为指定对象 此时,key对应的存储对象是map。 - * - * @param key redis关键字KEY - * @param field map的KEY值 - * @param clazz 对象存储类型 - * @return T 对象 - */ - public T hGet(String key, String field, Class clazz) { - return CommUtil.readObject(hGet(key, field), clazz); - } - - public boolean hSet(String key, String field, Serializable value) { - return hSet(key, getBytes(field), CommUtil.writeObject(value)); - } - - public long hdel(String key, String field) { - return redis.hdel(getBytes(key), getBytes(field)); - } - - public Long ttl(String key) { - return redis.ttl(getBytes(key)); - } - - public T get(String key, Class clazz) { - return CommUtil.readObject(get(key), clazz); - } - - public Map hGetAll(String key) { - return redis.hgetall(getBytes(key)); - } - - /** - * 模糊查询keys,影响性能,谨慎使用 - * - * @param keyLike 支持*表达模糊搜索 - * @return 查询到的列表 - */ - public List matchKeys(String keyLike) { - List list = redis.keys(getBytes(keyLike)); - if (list != null && !list.isEmpty()) { - List result = new ArrayList<>(list.size()); - for (byte[] b : list) { - result.add(new String(b, StandardCharsets.UTF_8)); - } - return result; - } - - return null; - } - - /** - * 模糊删除keys,影响性能,谨慎使用 - * - * @param keyLike 支持*表达模糊搜索 - * @return 成功删除的条数 - */ - public Long delMatchKeys(String keyLike) { - long result = 0; - List list = redis.keys(getBytes(keyLike)); - if (list != null) { - int size = list.size(); - - for (int i = 0; i < size; i += DEL_COUNT) { - int len = DEL_COUNT; - if (i + len > size) { - len = size - i; - } - - Long ret = delKeys(list, i, len); - if (ret != null) { - result += ret; - } - } - } - - return result; - } - - private Long delKeys(List keys, int start, int len) { - byte[][] batchKey = new byte[len][]; - - for (int i = 0; i < len; i++) { - batchKey[i] = keys.get(i + start); - } - - return redis.del(batchKey); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisManager.java deleted file mode 100644 index faf0b59..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisManager.java +++ /dev/null @@ -1,220 +0,0 @@ -package cc.smtweb.framework.core.cache.redis; - -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.systask.SysTaskManager; -import cc.smtweb.framework.core.util.JsonUtil; -import cc.smtweb.framework.core.util.SpringUtil; -import io.lettuce.core.RedisClient; -import io.lettuce.core.RedisURI; -import io.lettuce.core.api.StatefulRedisConnection; -import io.lettuce.core.api.sync.RedisCommands; -import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; -import io.lettuce.core.pubsub.api.sync.RedisPubSubCommands; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.pool2.impl.GenericObjectPool; -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.context.ApplicationContext; - -import javax.annotation.PreDestroy; -import java.io.Serializable; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -/** - * Redis管理器 - * - * @author kevin - */ -@Slf4j -public class RedisManager implements DisposableBean { - // SESSION - public static final String PREFIX_SESSION = "SID"; - // 定时器锁 - public static final String PREFIX_TIMER = "TIM"; - /** - * UserSession 超时时间 - */ - public static final int SESSION_EXPIRE_SEC = 30 * 60; - /** - * 订阅发布的主题 - */ - private static final String SCRIBE_SYSTEM = "SW_SYSTEM_"; -// private static final String SCRIBE_CACHED = "SW_CACHED"; - - private final RedisSysTask redisSysTask; - private RedisClient redisClient; - private GenericObjectPool> pool; - // 定义通道名称 - private final String channel; - - public static RedisManager getInstance() { - return SpringUtil.getBean(RedisManager.class); - } - - /** - * 初始化Redis连接池 - */ - public RedisManager(final ApplicationContext applicationContext, SysTaskManager sysTaskManager, RedisURI redisUri) { -// this.applicationContext = applicationContext; - redisClient = RedisClient.create(redisUri); - channel = SCRIBE_SYSTEM + redisUri.getDatabase() + "_" + redisUri.getClientName(); - - GenericObjectPoolConfig config = new GenericObjectPoolConfig(); - config.setTestWhileIdle(true); - pool = new GenericObjectPool<>(new RedisPooledObjectFactory(redisClient), config); - -// pool = ConnectionPoolSupport.createGenericObjectPool( -// () -> redisClient.connect(ByteArrayCodec.INSTANCE), -// new GenericObjectPoolConfig(), false); - - redisSysTask = new RedisSysTask(applicationContext, redisClient, SCRIBE_SYSTEM + redisUri.getDatabase() + "_*", channel); - sysTaskManager.add(redisSysTask); - } - - @PreDestroy - public void shutdown() { - pool.close(); - redisSysTask.close(); - redisClient.shutdown(); - } - - /** - * 执行redis命令 - */ - public T command(Function handler) { -// StatefulRedisConnection connection = redisClient.connect(ByteArrayCodec.INSTANCE); - - StatefulRedisConnection connection = null; - try { - connection = pool.borrowObject(); - } catch (Exception e) { - throw new SwException(e); - } - - try { - RedisCommands redisCommands = connection.sync(); - RedisConnection redis = new RedisConnection(redisCommands); - return handler.apply(redis); - } finally { - pool.returnObject(connection); - } - } - - public boolean expire(String key, int expireSec) { - return command(redis -> { - return redis.expire(key, expireSec); - }); - } - - /** - * 设置指定key对应的值,并更新超时时间 - * - * @param key 关键字KEY - * @param value 值 - * @param seconds 超时删除时间(秒) - * @return boolean 是否设置成功 - */ - public boolean set(byte[] key, byte[] value, int seconds) { - return command(redis -> redis.set(key, value, seconds)); - } - - public boolean setnx(byte[] key, byte[] value, int seconds) { - return command(redis -> redis.setnx(key, value, seconds)); - } - - public boolean setnx(String key, T obj, int seconds) { - return command(redis -> redis.setnx(key, obj, seconds)); - } - - public boolean set(String key, T obj, int seconds) { - return command(redis -> redis.set(key, obj, seconds)); - } - - public boolean del(String key) { - return command(redis -> redis.del(key)); - } - - public Long delKeys(String... keys) { - return command(redis -> redis.delKeys(keys)); - } - - public boolean hSet(String key, byte[] field, byte[] value) { - return command(redis -> redis.hSet(key, field, value)); - } - - - public boolean hmSet(String key, Map values) { - return command(redis -> redis.hmSet(key, values)); - } - - /** - * 获取指定key里指定的域对应的值,并转换为指定对象 此时,key对应的存储对象是map。 - * - * @param key redis关键字KEY - * @param field map的KEY值 - * @param clazz 对象存储类型 - * @return T 对象 - */ - public T hGet(String key, String field, Class clazz) { - return command(redis -> redis.hGet(key, field, clazz)); - } - - public List hVals(String key) { - return command(redis -> redis.hVals(key)); - } - - public boolean hSet(String key, String field, Serializable value) { - return command(redis -> redis.hSet(key, field, value)); - } - - public long hdel(String key, String field) { - return command(redis -> redis.hdel(key, field)); - } - - public Long ttl(String key) { - return command(redis -> redis.ttl(key)); - } - - public boolean exists(String key) { - return command(redis -> redis.exists(key)); - } - - // 发布系统消息 - public void publish(RedisBroadcastEvent message) { - try (StatefulRedisPubSubConnection connection = redisClient.connectPubSub()) { - RedisPubSubCommands sync = connection.sync(); - sync.publish(channel, JsonUtil.encodeString(message)); - } - } - - public Map hGetAll(String key) { - return command(redis -> redis.hGetAll(key)); - } - - public T get(String key, Class clazz) { - return command(redis -> redis.get(key, clazz)); - } - - public List matchKeys(String keyLike) { - return command(redis -> redis.matchKeys(keyLike)); - } - - public Long delMatchKeys(String keyLike) { - return command(redis -> redis.delMatchKeys(keyLike)); - } - - public byte[] writeObject(Serializable entity) { - return RedisConnection.writeObject(entity); - } - - public T readObject(byte[] value, Class clazz) { - return RedisConnection.readObject(value, clazz); - } - - @Override - public void destroy() throws Exception { - this.shutdown(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisPooledObjectFactory.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisPooledObjectFactory.java deleted file mode 100644 index 0c0c4c6..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisPooledObjectFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.smtweb.framework.core.cache.redis; - -import io.lettuce.core.RedisClient; -import io.lettuce.core.api.StatefulRedisConnection; -import io.lettuce.core.codec.ByteArrayCodec; -import org.apache.commons.pool2.PooledObject; -import org.apache.commons.pool2.PooledObjectFactory; -import org.apache.commons.pool2.impl.DefaultPooledObject; - -class RedisPooledObjectFactory implements PooledObjectFactory> { - private RedisClient redisClient; - - public RedisPooledObjectFactory(RedisClient redisClient) { - this.redisClient = redisClient; - } - - @Override - public void activateObject(PooledObject> pooledObject) throws Exception { - } - - @Override - public void destroyObject(PooledObject> pooledObject) throws Exception { - pooledObject.getObject().close(); - } - - @Override - public PooledObject> makeObject() throws Exception { - return new DefaultPooledObject<>(redisClient.connect(ByteArrayCodec.INSTANCE)); - } - - @Override - public void passivateObject(PooledObject> pooledObject) throws Exception { - } - - @Override - public boolean validateObject(PooledObject> pooledObject) { - return pooledObject.getObject().isOpen(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisSysTask.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisSysTask.java deleted file mode 100644 index b679838..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/RedisSysTask.java +++ /dev/null @@ -1,61 +0,0 @@ -package cc.smtweb.framework.core.cache.redis; - -import cc.smtweb.framework.core.systask.ISysTask; -import cc.smtweb.framework.core.util.JsonUtil; -import io.lettuce.core.RedisClient; -import io.lettuce.core.pubsub.RedisPubSubAdapter; -import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; -import io.lettuce.core.pubsub.api.sync.RedisPubSubCommands; -import org.springframework.context.ApplicationContext; - -public class RedisSysTask implements ISysTask { - private ApplicationContext applicationContext; - private StatefulRedisPubSubConnection connection; - private RedisClient redisClient; - //订阅消息的channel,一般带通配符 - private String scribeChannel; - //自己的唯一标记,自己发的消息不处理 - private String selfChannel; - - public RedisSysTask(ApplicationContext applicationContext, RedisClient redisClient, String scribeChannel, String selfChannel) { - this.applicationContext = applicationContext; - this.redisClient = redisClient; - this.scribeChannel = scribeChannel; - this.selfChannel = selfChannel; - } - - @Override - public int run() { - // 非集群模式下的发布订阅 - if (connection == null) { - connection = redisClient.connectPubSub(); - - if (connection != null) { - connection.addListener(new RedisPubSubAdapter() { - @Override - public void message(String channel, String message) { - if (channel.equalsIgnoreCase(selfChannel)) return; - RedisBroadcastEvent redisBroadcast = JsonUtil.parse(message, RedisBroadcastEvent.class); - - applicationContext.publishEvent(redisBroadcast); - -// log.debug("Redis [" + channel + "] message:" + redisBroadcast); - } - }); - - // 订阅 - RedisPubSubCommands sync = connection.sync(); - sync.subscribe(scribeChannel); - } - } - - return 0; - } - - public void close() { - if (connection != null) { - connection.close(); - connection = null; - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/config/RedisConfig.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/config/RedisConfig.java deleted file mode 100644 index 83367e3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/redis/config/RedisConfig.java +++ /dev/null @@ -1,64 +0,0 @@ -package cc.smtweb.framework.core.cache.redis.config; - - -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.systask.SysTaskManager; -import io.lettuce.core.RedisURI; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * 〈redis配置〉 - * - * @author kevin - * @since 1.0.0 - */ -@Configuration -public class RedisConfig { - @Value("${spring.redis.name:127.0.0.1}") - private String clientName; - - @Value("${spring.redis.host:127.0.0.1}") - private String redisHost; - - @Value("${spring.redis.port:6379}") - private int redisPort; - - @Value("${spring.redis.username:}") - private String redisUserName; - - @Value("${spring.redis.password:}") - private String redisPassword; - - @Value("${spring.redis.database:}") - private String redisDb; - - @Autowired - private ApplicationContext applicationContext; - - @Autowired - private SysTaskManager sysTaskManager; - - @Bean - public RedisManager redisManager() { - RedisURI redisUri = RedisURI.create (redisHost, redisPort); - if (StringUtils.isNotBlank(clientName)) { - redisUri.setClientName(clientName); - } - if (StringUtils.isNotBlank(redisDb)) { - redisUri.setDatabase(Integer.parseInt(redisDb)); - } - if (StringUtils.isNotBlank(redisUserName)) { - redisUri.setUsername(redisUserName.trim()); - } - if (StringUtils.isNotBlank(redisPassword)) { - redisUri.setPassword((CharSequence)redisPassword.trim()); - } - - return new RedisManager(applicationContext, sysTaskManager, redisUri); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/AbstractEnum.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/AbstractEnum.java deleted file mode 100644 index 29f6bb9..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/AbstractEnum.java +++ /dev/null @@ -1,106 +0,0 @@ -package cc.smtweb.framework.core.common; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Created by Akmm at 2017/5/3 17:25 - * 枚举基类 - */ -public abstract class AbstractEnum { - public Map mapAll = new LinkedHashMap<>(); - - public V addEnum(K value, String name) { - final V bean = buildBean(value, name); - mapAll.put(value, bean); - return bean; - } - - public void delEnum(K value) { - mapAll.remove(value); - } - - protected abstract V buildBean(K value, String name); - - protected Object getSqlValue(V pbs) { - return pbs.value; - } - - //根据值获取对象 - public V getByValue(K value) { - V v = mapAll.get(value); - if (v != null) return v; - return getDefault(); - } - - public V getByName(String name) { - for (V bs : mapAll.values()) { - if (bs.name.equals(name)) return bs; - } - return null; - } - - //根据value获取name - public String getName(K value) { - V bean = getByValue(value); - return bean != null ? bean.name: ""; - } - - //默认值 - public V getDefault() { - return null; - } - - //所有枚举定义 - public Collection values() { - return mapAll.values(); - } - - public boolean contains(K value) { - return mapAll.containsKey(value); - } - - //遍历枚举类 - public void doEnum(IEnumWorker worker) { - for (V bean: mapAll.values()) { - worker.work(bean); - } - } - - /** - * 枚举值对象定义 - */ - public static class EnumBean { - public T value; - public String name; - - public EnumBean(T value, String name) { - this.value = value; - this.name = name; - } - } - - /** - * Int、Text 枚举值对象定义 - */ - public static class IntEnumBean extends EnumBean { - public IntEnumBean(Integer value, String name) { - super(value, name); - } - } - - /** - * Str、Text 枚举值对象定义 - */ - public static class StrEnumBean extends EnumBean { - public StrEnumBean(String value, String name) { - super(value, name); - } - } - - //枚举回调类 - public interface IEnumWorker { - public void work(V enumBean); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/IntEnum.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/IntEnum.java deleted file mode 100644 index 7cdd183..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/IntEnum.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.smtweb.framework.core.common; - -/** - * Created by Akmm at 2017/5/3 17:25 - * int、text型枚举 - */ -public class IntEnum extends AbstractEnum { - @Override - protected AbstractEnum.IntEnumBean buildBean(Integer value, String name) { - return new AbstractEnum.IntEnumBean(value, name); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/R.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/R.java deleted file mode 100644 index 4a91157..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/R.java +++ /dev/null @@ -1,118 +0,0 @@ -package cc.smtweb.framework.core.common; - -import cc.smtweb.framework.core.exception.ExceptionMessage; - -import java.util.Date; - -/** - * 〈返回结果集〉 - * - * @author kevin - * @since 1.0.0 - */ -public class R extends SwMap { - protected R() { - this(0); - } - - protected R(int code) { - put("now", new Date()); - put("code", code); - } - - public static R success() { - return new R(); - } - - public static R success(Object data) { - return new R().put("data", data); - } - - public static R success(String name, Object data) { - return new R().put(name, data); - } - - public static R error() { - return error(ExceptionMessage.INNER_ERROR.getMsg()); - } - - public static R error(String msg) { - R r = new R(ExceptionMessage.INNER_ERROR.getCode()); - r.put("msg", msg); - return r; - } - - public static R error(int code, String msg) { - R r = new R(code); - r.put("msg", msg); - return r; - } - - public static R errorf(String format, Object...args) { - R r = new R(ExceptionMessage.INNER_ERROR.getCode()); - r.put("msg", String.format(format, args)); - return r; - } - -// public static R error(ExceptionMessage cm) { -// R r = new R(cm.getCode()); -// r.put("msg", cm.getMsg()); -// return r; -// } - -// public static R error(ExceptionMessage cm, Throwable ex) { -// R r = new R(cm.getCode()); -// r.put("msg", cm.getMsg()); -// r.put("exception", ex.getMessage()); -// return r; -// } - - public static R error(String msg, Throwable ex) { - R r = new R(ExceptionMessage.INNER_ERROR.getCode()); - r.put("msg", msg); - r.put("exception", ex.getMessage()); - ex.printStackTrace(); - return r; - } - - public static R error(ExceptionMessage cm, String msg) { - R r = new R(cm.getCode()); - r.put("msg", msg); - return r; - } - - @Override - public R put(String key, Object value) { - super.put(key, value); - return this; - } - - public R putNotNull(String key, Object value) { - if (value != null) { - super.put(key, value); - } - - return this; - } - - public void setMessage(ExceptionMessage cm) { - this.put("code", cm.getCode()); - this.put("msg", cm.getMsg()); - } - - public void setData(Object data) { - this.put("data", data); - } - - public int readCode() { - return this.readInt("code"); - } - - public String readMsg() { - return this.readString("msg"); - } - - public boolean readSuccess() { - return this.readInt("code", -1) == 0; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/StrEnum.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/StrEnum.java deleted file mode 100644 index 2ada2ae..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/StrEnum.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.framework.core.common; - -import org.apache.commons.lang3.StringUtils; - -/** - * Created by Akmm at 2017/5/3 17:25 - * int、text型枚举 - */ -public class StrEnum extends AbstractEnum { - @Override - protected Object getSqlValue(StrEnumBean pbs) { - return "'" + pbs.value + "'"; - } - - @Override - protected AbstractEnum.StrEnumBean buildBean(String value, String name) { - return new AbstractEnum.StrEnumBean(value, name); - } - - //根据value获取name - public String getNames(String value) { - if (StringUtils.isEmpty(value)) return ""; - StringBuilder sb = new StringBuilder(128); - for (String s : value.split(",")) { - String n = getName(s); - if (StringUtils.isNotEmpty(n)) sb.append(",").append(n); - } - return sb.substring(1); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java deleted file mode 100644 index 65df21a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.smtweb.framework.core.common; - -/** - * Created by Akmm at 2022/3/23 9:46 - */ -public interface SwConsts { - //缓存中:树节点按parent的key - String KEY_PARENT_ID = "pr"; - //级次码、字符串连接符 - String SPLIT_CHAR = "-"; - //默认根节点 - String DEF_ROOT_ID = "-1"; - - //列表分页的页码和每页记录数 - String PARAM_PAGE = "page"; - String PARAM_ROWS = "rows"; - String TOTAL_KEY = "total_count"; - String DEF_DB_NAME = "sys"; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java deleted file mode 100644 index d859d04..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java +++ /dev/null @@ -1,290 +0,0 @@ -package cc.smtweb.framework.core.common; - -import org.apache.commons.lang3.StringUtils; - -import java.sql.Types; - -/** - * Created by Akmm at 2022/3/23 9:39 - * 系统的一些枚举变量 - */ -public interface SwEnum { - - - /** - * Created by Akmm at 2022/2/9 10:01 - * 字段业务类别 - */ - class FieldTypeBean extends AbstractEnum.IntEnumBean { - public String dataType; - public int notNull; - - public FieldTypeBean(Integer value, String name, String dataType) { - super(value, name); - this.dataType = dataType; - this.notNull = 0; - } - public FieldTypeBean(Integer value, String name, String dataType, int notNull) { - super(value, name); - this.dataType = dataType; - this.notNull = notNull; - } - } - - class FieldType extends AbstractEnum { - public static FieldType instance = new FieldType(); - - public static FieldTypeBean ID = instance.addEnum(1, "主键", DataType.ID.value,1); - public static FieldTypeBean CODE = instance.addEnum(2, "编码字段", DataType.CODE.value,1); - public static FieldTypeBean NAME = instance.addEnum(3, "名称字段", DataType.NAME.value,1); - public static FieldTypeBean PARENT_ID = instance.addEnum(4, "父ID", DataType.ID.value); - public static FieldTypeBean LEVEL_CODE = instance.addEnum(5, "级次码", DataType.CODE.value); - public static FieldTypeBean ORDER = instance.addEnum(6, "排序字段", ""); - public static FieldTypeBean CREATE_USER = instance.addEnum(7, "创建人", DataType.ID.value); - public static FieldTypeBean CREATE_TIME = instance.addEnum(8, "创建时间", DataType.DATETIME.value); - public static FieldTypeBean UPDATE_USER = instance.addEnum(9, "更新人", DataType.ID.value); - public static FieldTypeBean LAST_TIME = instance.addEnum(10, "更新时间", DataType.DATETIME.value); - - @Override - protected FieldTypeBean buildBean(Integer value, String name) { - return new FieldTypeBean(value, name, ""); - } - - public FieldTypeBean addEnum(Integer value, String name, String dataType) { - final FieldTypeBean bean = new FieldTypeBean(value, name, dataType); - mapAll.put(value, bean); - return bean; - } - public FieldTypeBean addEnum(Integer value, String name, String dataType, int notNull) { - final FieldTypeBean bean = new FieldTypeBean(value, name, dataType,notNull); - mapAll.put(value, bean); - return bean; - } - } - - /** - * 字段编辑类型 - */ - class EditorType extends StrEnum { - public static EditorType instance = new EditorType(); - - public static StrEnumBean INPUT = instance.addEnum("text", "文本"); - public static StrEnumBean TEXT = instance.addEnum("textarea", "长文本"); - public static StrEnumBean NUMBER = instance.addEnum("number", "数字"); - public static StrEnumBean SWITCH = instance.addEnum("switch", "布尔型"); - public static StrEnumBean DATE = instance.addEnum("date", "日期"); - public static StrEnumBean TIME = instance.addEnum("time", "时间"); - public static StrEnumBean DATETIME = instance.addEnum("datetime", "日期时间"); - public static StrEnumBean COMBO = instance.addEnum("select", "下拉列表"); - public static StrEnumBean TREE = instance.addEnum("select-tree", "下拉树"); - } - - /** - * 数据字段类型Bean - */ - class DataTypeBean extends AbstractEnum.StrEnumBean { - public String sqlType; - public int dataLength; - public String javaType; - public String shortJavaType; - //java.sql.Types里的值 - public int type; - public String defaultValue; - public String editor; - - public DataTypeBean(String value, String name, String sqlType, int dataLength, String javaType, String shortJavaType, int type, String defaultValue, String editor) { - super(value, name); - this.sqlType = sqlType; - this.dataLength = dataLength; - this.javaType = javaType; - this.shortJavaType = shortJavaType; - this.defaultValue = defaultValue; - this.editor = editor; - this.type = type; - } - - public String getSqlTypeCreate() { - if (dataLength > 0) return sqlType + "(" + dataLength + ")"; - return sqlType; - } - - } - - /** - * 数据类型定义,参见design_db.yaml配置 - */ - class DataType extends AbstractEnum { - public final static String TYPE_BOOL = "bool"; - public final static String TYPE_DATE = "date"; - public final static String TYPE_DATETIME = "datetime"; - - public static DataType instance = new DataType(); - public static DataTypeBean ID = instance.addEnum("id", "ID", "bigint", 0, "long", "Long", Types.BIGINT, "", EditorType.INPUT.value); - public static DataTypeBean CODE = instance.addEnum("code", "编码", "varchar", 32, "String", "Str", Types.VARCHAR, "", EditorType.INPUT.value); - public static DataTypeBean NAME = instance.addEnum("name", "名称", "varchar", 100, "String", "Str", Types.VARCHAR, "", EditorType.INPUT.value); - public static DataTypeBean REMARK = instance.addEnum("remark", "备注", "varchar", 255, "String", "Str", Types.VARCHAR, "", EditorType.INPUT.value); - public static DataTypeBean TEXT = instance.addEnum("text", "大文本", "text", 0, "String", "Str", Types.CLOB, "", EditorType.TEXT.value); - public static DataTypeBean LONG = instance.addEnum("long", "长整型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.INPUT.value); - public static DataTypeBean INT = instance.addEnum("int", "整型", "int", 0, "int", "Int", Types.INTEGER, "0", EditorType.NUMBER.value); - public static DataTypeBean SHORT = instance.addEnum("short", "短整型", "smallint", 0, "int", "Int", Types.SMALLINT, "0", EditorType.NUMBER.value); - public static DataTypeBean BOOL = instance.addEnum("bool", "布尔型", "tinyint", 0, "boolean", "Bool", Types.TINYINT, "0", EditorType.SWITCH.value); - public static DataTypeBean CURRENCY = instance.addEnum("currency", "金额型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.NUMBER.value); - public static DataTypeBean DATE = instance.addEnum("date", "日期型", "bigint", 0, "long","Long", Types.BIGINT, "0", EditorType.DATE.value); - public static DataTypeBean TIME = instance.addEnum("time", "时间型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.TIME.value); - public static DataTypeBean DATETIME = instance.addEnum("datetime", "日期时间型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.DATETIME.value); - - @Override - protected DataTypeBean buildBean(String value, String name) { - return null; - } - - public DataTypeBean addEnum(String value, String name, String sqlType, int dataLength, String javaType, String shortJavaType, int type, String defaultValue, String editor) { - final DataTypeBean bean = new DataTypeBean(value, name, sqlType, dataLength, javaType, shortJavaType, type, defaultValue, editor); - mapAll.put(value, bean); - return bean; - } - - @Override - public DataTypeBean getByValue(String value) { - if (value == null) return null; - return super.getByValue(value.toLowerCase()); - } - - //根据数据库查询的metadata适配类型 - public static DataTypeBean getBySqlType(int sqlType, int precision, int scale) { - for (DataTypeBean bean: instance.mapAll.values()) { - if (bean.type != sqlType) continue; - if (bean.dataLength == 0 || bean.dataLength == precision) return bean; - } - return REMARK; - } - } - - /** - * 数据字段类型Bean - */ - class IndexTypeBean extends AbstractEnum.StrEnumBean { - public String fullName; - - public IndexTypeBean(String value, String name, String fullName) { - super(value, name); - this.fullName = fullName; - } - } - - class IndexType extends AbstractEnum { - public static IndexType instance = new IndexType(); - public static IndexTypeBean PK = instance.addEnum("P", "主键", "prim-key"); - public static IndexTypeBean I = instance.addEnum("I", "一般索引", ""); - public static IndexTypeBean U = instance.addEnum("U", "唯一索引", "unique"); - - @Override - protected IndexTypeBean buildBean(String value, String name) { - return null; - } - - public IndexTypeBean addEnum(String value, String name, String fullName) { - final IndexTypeBean bean = new IndexTypeBean(value, name, fullName); - mapAll.put(value, bean); - return bean; - } - } - - /** - * 表类型 - */ - class TableType extends IntEnum { - public static TableType instance = new TableType(); - - public static AbstractEnum.IntEnumBean TYPE_GENERAL = instance.addEnum(0, "普通表"); - public static AbstractEnum.IntEnumBean TYPE_TREE = instance.addEnum(1, "树型表"); - public static AbstractEnum.IntEnumBean TYPE_CODE = instance.addEnum(2, "编码表"); - public static AbstractEnum.IntEnumBean TYPE_ABSTRACT = instance.addEnum(3, "虚拟抽象表"); - public static AbstractEnum.IntEnumBean TYPE_VIEW = instance.addEnum(4, "视图"); - } - - /** - * 界面定义类型:::控件/页面 - */ - class FormType extends IntEnum { - public static FormType instance = new FormType(); - - public static IntEnumBean PAGE = instance.addEnum(0, "页面"); - public static IntEnumBean WIDGET = instance.addEnum(1, "控件"); - } - - /** - * 控件类型:::grid,tree,combotree,combogrid、custom - */ - class WidgetType extends StrEnum { - public static WidgetType instance = new WidgetType(); - - public static StrEnumBean GRID = instance.addEnum("grid", "表格"); - public static StrEnumBean TREE = instance.addEnum("tree", "树"); - public static StrEnumBean COMBOGRID = instance.addEnum("combogrid", "下拉表格"); - public static StrEnumBean COMBOTREE = instance.addEnum("combotree", "下拉树"); - public static StrEnumBean CUSTOM = instance.addEnum("custom", "自定义"); - } - - /** - * 数据集类型:::list-列表;form-表单;editList-编辑列表;tree;enum - */ - class DatasetType extends StrEnum { - public static DatasetType instance = new DatasetType(); - - public static StrEnumBean LIST = instance.addEnum("list", "查询列表"); - public static StrEnumBean FORM = instance.addEnum("form", "表单"); - public static StrEnumBean ITEM = instance.addEnum("item", "子表编辑"); - public static StrEnumBean TREE = instance.addEnum("tree", "树"); - public static StrEnumBean ENUM = instance.addEnum("enum", "枚举"); - } - - /** - * 过滤条件类型:::控件/参数/link/const - */ - class FilterType extends StrEnum { - public static FilterType instance = new FilterType(); - - public static StrEnumBean INPUT = instance.addEnum("input", "输入"); - public static StrEnumBean PARAM = instance.addEnum("param", "参数"); - public static StrEnumBean LINK = instance.addEnum("link", "关联"); - public static StrEnumBean CONST = instance.addEnum("const", "常量"); - } - - /** - * 操作符类型:::and/or/=/>=/<=/like/p - */ - class OptType extends StrEnum { - public static OptType instance = new OptType(); - - public static StrEnumBean AND = instance.addEnum("and", "且"); - public static StrEnumBean OR = instance.addEnum("or", "或"); - - public static StrEnumBean EQ = instance.addEnum("=", "等于"); - public static StrEnumBean NE = instance.addEnum("<>", "不等于"); - public static StrEnumBean GT = instance.addEnum(">", "大于"); - public static StrEnumBean GE = instance.addEnum(">=", "大于等于"); - public static StrEnumBean LT = instance.addEnum("<", "小于"); - public static StrEnumBean LE = instance.addEnum("<=", "小于等于"); - public static StrEnumBean BT = instance.addEnum("bt", "介于"); - public static StrEnumBean PLIKE = instance.addEnum("plike", "开始以"); - public static StrEnumBean LIKE = instance.addEnum("like", "包含"); - } - - //合计栏类型 "summary": "COUNT/SUM/AVG/MAX/MIN/其他为文本" - class SummaryType extends StrEnum { - public static SummaryType instance = new SummaryType(); - - public static StrEnumBean COUNT = instance.addEnum("count", "计数"); - public static StrEnumBean SUM = instance.addEnum("sum", "求和"); - public static StrEnumBean AVG = instance.addEnum("avg", "均值"); - public static StrEnumBean MAX = instance.addEnum("max", "最大值"); - public static StrEnumBean MIN = instance.addEnum("min", "最小值"); - - //是字符串 - public boolean isText(String v) { - if (StringUtils.isEmpty(v)) return true; - return !mapAll.containsKey(v.toLowerCase()); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwIpAddr.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwIpAddr.java deleted file mode 100644 index ab2b357..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwIpAddr.java +++ /dev/null @@ -1,9 +0,0 @@ -package cc.smtweb.framework.core.common; - -import lombok.Data; - -@Data -public class SwIpAddr { - private String ip; - private int port; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwMap.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwMap.java deleted file mode 100644 index e55fe7a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwMap.java +++ /dev/null @@ -1,116 +0,0 @@ -package cc.smtweb.framework.core.common; - -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.util.MapUtil; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * 通用map对象,用于无具体类型的传值 - * - * @author kevin - */ -public class SwMap extends HashMap { - public SwMap() { - } - - public SwMap(int initialCapacity) { - super(initialCapacity); - } - - public String readString(String name) { - return MapUtil.readString(this, name); - } - - public SwMap readMap(String name) { - Object v = get(name); - if (v == null) return null; - if (v instanceof SwMap) return (SwMap)v; - if (v instanceof Map) { - Map m = (Map)v; - SwMap map = new SwMap(m.size()); - map.putAll(m); - put(name, map); - return map; - } - throw new SwException("不是合法的Map对象!" + v.getClass().getName()); - } - - public List> readListMap(String name) { - return MapUtil.readListMap(this, name); - } - - public String readString(String name, String defaultValue) { - return MapUtil.readString(this, name, defaultValue); - } - - public long readLong(String name) { - return MapUtil.readLong(this, name); - } - - public Long readLong(String name, Long defaultValue) { - return MapUtil.readLong(this, name, defaultValue); - } - - public Long[] readLongArray(String name) { - return MapUtil.readLongArray(this, name); - } - - public Long[] readLongArray(String name, Long[] defaultValue) { - return MapUtil.readLongArray(this, name, defaultValue); - } - - public Set readLongSet(String name) { - return MapUtil.readLongSet(this, name); - } - - public int readInt(String name) { - return MapUtil.readInt(this, name); - } - - public int readInt(String name, Integer defaultValue) { - return MapUtil.readInt(this, name, defaultValue); - } - - public float readFloat(String name) { - return MapUtil.readFloat(this, name); - } - - public float readFloat(String name, Float defaultValue) { - return MapUtil.readFloat(this, name, defaultValue); - } - - public double readDouble(String name) { - return MapUtil.readDouble(this, name); - } - - public double readDouble(String name, Double defaultValue) { - return MapUtil.readDouble(this, name, defaultValue); - } - - public boolean readBool(String name) { - return MapUtil.readBool(this, name); - } - - public boolean readBool(String name, Boolean defaultValue) { - return MapUtil.readBool(this, name, defaultValue); - } - - @Override - public SwMap put(String name, Object value) { - if (value != null) { - super.put(name, value); - } else { - super.remove(name); - } - - return this; - } - - public static SwMap of(String name, Object value) { - return new SwMap().put(name, value); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java deleted file mode 100644 index d0b77ba..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java +++ /dev/null @@ -1,278 +0,0 @@ -package cc.smtweb.framework.core.db; - -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.jdbc.IdGenerator; -import cc.smtweb.framework.core.db.jdbc.JdbcEngine; -import cc.smtweb.framework.core.mvc.controller.scan.BeanManager; -import cc.smtweb.framework.core.util.SpringUtil; -import lombok.extern.slf4j.Slf4j; -import org.springframework.jdbc.core.ResultSetExtractor; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 提供数据库基本操作和代理EntityDao操作,在DbEngineConfiguration中初始化 - * - * @author xkliu - */ -@Slf4j -public class DbEngine extends JdbcEngine { - private String dbSchema; - private final Map, EntityDao> daoMap = new ConcurrentHashMap<>(); - private final Map> tableDaoMap = new ConcurrentHashMap<>(); - - public static DbEngine getInstance() { - return SpringUtil.getBean(DbEngine.class); - } - - public DbEngine(NamedParameterJdbcTemplate namedJdbcTemplate, IdGenerator idGenerator, String type) { - super(namedJdbcTemplate, idGenerator, type); - } - - /** - * bean为Data格式,调用此方法 - * @param type bean类 - * @param - * @return - */ - public EntityDao findDao(Class type) { - EntityDao handler = (EntityDao) daoMap.get(type); - - if (handler == null) { - synchronized (daoMap) { - handler = new EntityDao<>(type, this); - daoMap.put(type, handler); - } - } - - return handler; - } - - public EntityDao findDao(String tableName) { - Class clazz = BeanManager.getInstance().getTableClass(tableName); - if (clazz != null) { - return findDao(clazz); - } - EntityDao handler = tableDaoMap.get(tableName); - - if (handler == null) { - synchronized (tableDaoMap) { - handler = new EntityDao<>(tableName, this); - tableDaoMap.put(tableName, handler); - } - } - - return handler; - } - - public String getDbSchema() { - if (dbSchema == null) { - synchronized (DbEngine.class) { - if (dbSchema == null) { - try { - final ResultSetExtractor rse = new ResultSetExtractor() { - @Override - public String extractData(ResultSet rs) throws SQLException { - if (rs.next()) return rs.getString(1); - throw new SQLException("未指定当前数据库,请检查您的链接!"); - } - }; - - dbSchema = query("SELECT database()", rse); - - } catch (Exception e) { - log.error("获取mysql的数据库失败", e); - return null; - } - } - } - } - return dbSchema; - } - - /** - * 根据PO对象的ID值更新其余所有字段 - * - * @param entity PO对象 - * @param PO对象类型 - * @return 更新数量 - */ - public int updateEntity(T entity) { - return updateEntity(entity, null, null); - } - - /** - * 使用ID字段更新单行数据 - * - * @param entity PO值对象,对象属性是需要更新的值 - * @param fields 需要更新额字段列表,逗号分隔 - * @param PO值对象类型 - * @return 更新数量 - */ - public int updateEntity(T entity, String fields) { - return updateEntity(entity, fields, null); - } - - /** - * 指定自定义条件更新对象 - * - * @param entity PO值对象,对象属性是需要更新的值和更新条件值 - * @param fields 需要更新额字段列表,逗号分隔 - * @param whereFields 更新条件字段列表,逗号分隔 - * @param PO值对象类型 - * @return 更新数量 - */ - public int updateEntity(T entity, String fields, String whereFields) { - EntityDao dao = findDao((Class) entity.getClass()); - return dao.updateEntity(entity, fields, whereFields); - } - - /** - * 用PO对象所有字段入单行数据 - * - * @param entity PO对象 - * @param PO对象类型 - * @return 更新数量 - */ - public int insertEntity(T entity) { - return insertEntity(entity, null); - } - - /** - * 插入单行数据 - * - * @param entity PO对象 - * @param fields 逗号分隔的字段列表 - * @param PO对象类型 - * @return 更新数量 - */ - public int insertEntity(T entity, String fields) { - EntityDao dao = findDao((Class) entity.getClass()); - return dao.insertEntity(entity, fields); - } - - /** - * 根据ID值删除单行数据 - * - * @param entity PO对象 - * @param PO对象类型 - * @return 删除数量 - */ - public int deleteEntity(T entity) { - EntityDao dao = findDao((Class) entity.getClass()); - return dao.deleteEntity(entity); - } - - /** - * 根据ID值删除单行数据 - * - * @param entityType PO对象类型 - * @param id 记录主建值 - * @param PO对象 - * @return 删除数量 - */ - public int deleteEntity(Class entityType, Long id) { - EntityDao dao = findDao(entityType); - return dao.deleteEntity(id); - } - - /** - * 根据ID值删除单行数据 - * - * @param entityType PO对象类型 - * @param whereSql Where条件SQL语句,以where开头 - * @param params 条件的值,可以多个 - * @param PO对象 - * @return 删除数量 - */ - public int deleteEntity(Class entityType, String whereSql, Object... params) { - EntityDao dao = findDao(entityType); - return dao.deleteEntity(whereSql, params); - } - - /** - * 读取实体对象ID值 - * - * @param entity - * @param - * @return - */ - public Long readEntityId(T entity) { - EntityDao dao = findDao((Class) entity.getClass()); - return dao.readId(entity); - } - - /** - * 查询单行数据,返回bean - */ - public T queryEntity(Class type, Long id) { - return queryEntity(type, id, null); - } - - public T queryEntity(Class type, Long id, String fields) { - return findDao(type).queryEntity(id, fields); - } - - /** - * 查询对象所有数据,返回列表 - */ - public List query(Class type) { - return query(type, null); - } - - /** - * 查询对象所有数据,返回列表 - */ - public List query(Class type, String fields) { - return findDao(type).query(fields); - } - - /** - * 传入where条件查询实体类别 - * - * @param type 实体类型类 - * @param sqlWhere sql的where语句部分,不包含from - * @param params 条件参数值 - * @param 实体类型 - * @return - */ - public List queryWhere(Class type, String sqlWhere, Object... params) { - return findDao(type).queryWhere(sqlWhere, params); - } - - /** - * 批量插入单行数据 - * - * @param entities PO对象列表 - * @param 实体类型 - * @return 更新数量 - */ - public int[] batchInsertEntity(List entities) { - if (entities == null || entities.isEmpty()) { - return null; - } - return findDao((Class) entities.get(0).getClass()).batchInsertEntity(entities, null); - } - - /** - * 批量插入单行数据 - * - * @param entities PO对象列表 - * @param fields 逗号分隔的字段列表 - * @param 实体类型 - * @return 更新数量 - */ - public int[] batchInsertEntity(List entities, String fields) { - if (entities == null || entities.isEmpty()) { - return null; - } - return findDao((Class) entities.get(0).getClass()).batchInsertEntity(entities, fields); - } - - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/EntityDao.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/EntityDao.java deleted file mode 100644 index 8318c2c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/EntityDao.java +++ /dev/null @@ -1,367 +0,0 @@ -package cc.smtweb.framework.core.db; - -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.db.dao.AbstractEntityDao; -import cc.smtweb.framework.core.db.dao.EntityColumn; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.jdbc.JdbcEngine; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.util.CommUtil; -import lombok.Getter; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -/** - * 提供数据对象Dao操作 - * - * @author xkliu - */ -public class EntityDao extends AbstractEntityDao { - @Getter - protected JdbcEngine jdbcEngine; - - public EntityDao(Class type, JdbcEngine jdbcEngine) { - super(type); - this.jdbcEngine = jdbcEngine; - } - - public EntityDao(String tableName, JdbcEngine jdbcEngine) { - super(tableName); - this.jdbcEngine = jdbcEngine; - } - - /** - * 获取数据库唯一id - * - * @return 返回ID值 - */ - public long nextId() { - return this.jdbcEngine.nextId(); - } - - /** - * 根据PO对象的ID值更新其余所有字段 - * - * @param entity PO对象 - * @return 更新数量 - */ - public int updateEntity(T entity) { - return updateEntity(entity, null, null); - } - - /** - * 使用ID字段更新单行数据 - * - * @param entity PO值对象,对象属性是需要更新的值 - * @param fields 需要更新额字段列表,逗号分隔 - * @return 更新数量 - */ - public int updateEntity(T entity, String fields) { - return updateEntity(entity, fields, null); - } - - public int updateEntityEx(T entity, String... exfields) { - if (exfields == null || exfields.length == 0) { - return updateEntity(entity, null, null); - } - Set excludeFields = new HashSet<>(exfields.length); - for (String f: exfields) { - excludeFields.add(f.toLowerCase()); - } - StringBuilder fields = new StringBuilder(512); - for (ModelField field: modelTable.getFields()) { - if (!excludeFields.contains(field.getName())) { - fields.append(",").append(field.getName()); - } - } - return updateEntity(entity, fields.substring(1), null); - } - - /** - * 指定自定义条件更新对象 - * - * @param entity PO值对象,对象属性是需要更新的值和更新条件值 - * @param fields 需要更新额字段列表,逗号分隔 - * @param whereFields 更新条件字段列表,逗号分隔 - * @return 更新数量 - */ - public int updateEntity(T entity, String fields, String whereFields) { - StringBuilder sb = new StringBuilder(); - Object[] params = this.handleUpdate(entity, sb, fields, whereFields); - - return jdbcEngine.update(sb.toString(), params); - } - - /** - * 用PO对象所有字段入单行数据 - * - * @param type PO对象字段范围的类,是entity的父类 - * @param entity PO对象 - * @return 更新数量 - */ - public int insertEntity(Class type, T entity) { - return insertEntity(type, entity, null); - } - - /** - * 用PO对象所有字段入单行数据 - * - * @param entity PO对象 - * @return 更新数量 - */ - public int insertEntity(T entity) { - return insertEntity(entity.getClass(), entity, null); - } - - /** - * 插入单行数据 - * - * @param entity PO对象 - * @param fields 逗号分隔的字段列表 - * @return 更新数量 - */ - public int insertEntity(T entity, String fields) { - return insertEntity(entity.getClass(), entity, fields); - } - - private int insertEntity(Class type, T entity, String fields) { - StringBuilder sb = new StringBuilder(); - - Object[] params = handleInsert(entity, sb, fields); - - return jdbcEngine.update(sb.toString(), params); - } - - /** - * 批量插入单行数据 - * - * @param entities PO对象列表 - * @return 更新数量 - */ - public int[] batchInsertEntity(List entities) { - return batchInsertEntity(entities, null); - } - - /** - * 批量插入单行数据 - * - * @param entities PO对象列表 - * @param fields 逗号分隔的字段列表 - * @return 更新数量 - */ - public int[] batchInsertEntity(List entities, String fields) { - StringBuilder sql = new StringBuilder(); - - sql.append("insert into ").append(modelTable.getSchemaTableName()).append("("); - - List listFields = adjustFields(fields, SwEnum.FieldType.CREATE_TIME.value, SwEnum.FieldType.LAST_TIME.value); - List insertColumns = new ArrayList<>(this.columns.size()); - - if (listFields == null) { - for (EntityColumn column : this.columns.values()) { - sql.append(column.getField().getName()).append(","); - insertColumns.add(column); - } - } else { - - for (String name : listFields) { - EntityColumn column = this.columns.get(name.trim()); - sql.append(column.getField().getName()).append(","); - insertColumns.add(column); - } - } - - sql.setCharAt(sql.length() - 1, ')'); - - // values(?,?) - sql.append(" values("); - for (int i = insertColumns.size(); i > 0; i--) { - sql.append("?,"); - } - sql.setCharAt(sql.length() - 1, ')'); - - // 参数列表 - List listParams = new ArrayList<>(entities.size()); - for (T obj : entities) { - List params = new ArrayList<>(this.columns.size()); - - for (EntityColumn column : this.columns.values()) { - params.add(column.readValue(obj)); - } - - listParams.add(params.toArray()); - } - - return jdbcEngine.batchUpdate(sql.toString(), listParams); - } - - - /** - * 根据ID值删除单行数据 - * - * @param entity PO对象 - * @return 删除数量 - */ - public int deleteEntity(T entity) { - StringBuilder sb = new StringBuilder(); - - Object[] params = handleDelete(entity, sb); - - return jdbcEngine.update(sb.toString(), params); - } - - /** - * 根据ID值删除单行数据 - * - * @param id 记录主建值 - * @return 删除数量 - */ - public int deleteEntity(Long id) { - StringBuilder sb = new StringBuilder(); - handleDelete(sb); - - return jdbcEngine.update(sb.toString(), id); - } - - /** - * 根据ID值删除单行数据 - * - * @param whereSql Where条件SQL语句,以where开头 - * @param params 条件的值,可以多个 - * @return 删除数量 - */ - public int deleteEntity(String whereSql, Object... params) { - StringBuilder sb = new StringBuilder("DELETE FROM "); - sb.append(modelTable.getSchemaTableName()).append(" ").append(whereSql); - - return jdbcEngine.update(sb.toString(), params); - } - - public int deleteEntity(List ids) { - return deleteEntity(" where " + modelTable.getIdField() + " in (" + CommUtil.getSqlInIds(ids) + ")"); - } - - private void setTableName(T bean) { - if (bean instanceof DefaultEntity) { - ((DefaultEntity) bean).setTableName(this.tableName); - } - } - - private void setTableName(List list) { - if (!list.isEmpty() && list.get(0) instanceof DefaultEntity) { - for (T bean: list) { - ((DefaultEntity) bean).setTableName(this.tableName); - } - } - } - - /** - * 查询单行数据,返回bean - */ - public T queryEntity(Long id) { - return queryEntity(id, null); - } - - public T queryEntity(Long id, String fields) { - StringBuilder sb = new StringBuilder(); - handleSelectOne(sb, fields); - - List list = jdbcEngine.query(sb.toString(), type, id); - - if (list != null && !list.isEmpty()) { - T bean = list.get(0); - setTableName(bean); - return bean; - } - - return null; - } - - /** - * 查询对象所有数据,返回列表 - */ - public List query() { - return query(null); - } - - /** - * 查询对象所有数据,返回列表 - */ - public Map queryNames(List ids) { - if (ids == null || ids.isEmpty()) return new HashMap<>(); - ModelField field = modelTable.findFieldByType(SwEnum.FieldType.NAME.value); - if (field == null) return new HashMap<>(); - - StringBuilder sb = new StringBuilder(); - handleSelect(sb, modelTable.getIdField() + "," + field.getName()); - sb.append("\nwhere " + modelTable.getIdField() + " in (" + CommUtil.getSqlInIds(ids) + ")"); - - return jdbcEngine.query(sb.toString(), rs -> { - Map map = new HashMap<>(); - while (rs.next()) { - map.put(rs.getString(1), rs.getString(2)); - } - return map; - }); - } - - /** - * 查询对象所有数据,返回列表 - */ - public List query(String fields) { - StringBuilder sb = new StringBuilder(); - handleSelect(sb, fields); - - List list = jdbcEngine.query(sb.toString(), type); - setTableName(list); - return list; - } - - /** - * 查询对象所有数据,返回列表 - */ - public List queryWhere(String sqlWhere, Object... params) { - StringBuilder sb = new StringBuilder(); - handleSelect(sb, null); - if (StringUtils.isNotEmpty(sqlWhere)) { - sb.append(" where ").append(sqlWhere); - } - - List list = jdbcEngine.query(sb.toString(), type, params); - setTableName(list); - return list; - } - - public List queryIdListWhere(String sqlWhere, Object... params) { - StringBuilder sb = new StringBuilder(); - handleSelect(sb, modelTable.getIdField()); - if (StringUtils.isNotEmpty(sqlWhere)) { - sb.append(" where ").append(sqlWhere); - } - - return jdbcEngine.queryLongList(sb.toString(), type, params); - } - - /** - * 检查表字段是否违反唯一索引 - * @param bean - * @param fields - */ - public void checkUnique(T bean, String... fields) { - if (fields.length == 0) return; - String ss = "", sTitle = ""; - List args = new ArrayList<>(fields.length + 1); - args.add(readId(bean)); - for (String f : fields) { - if (StringUtils.isEmpty(f)) continue; - ss += " and " + f + "=?"; - args.add(readValue(bean, f)); - sTitle += "+" + modelTable.findFieldTitle(f); - } - if (jdbcEngine.isExists("select 1 from " + modelTable.getSchemaTableName() + " where " + modelTable.getIdField() + "=? " + ss, args.toArray())) - throw new BizException(sTitle.substring(1) + " 不能重复!"); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java deleted file mode 100644 index f427081..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/EntityHelper.java +++ /dev/null @@ -1,193 +0,0 @@ -package cc.smtweb.framework.core.db; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelLinkName; -import cc.smtweb.framework.core.db.vo.ModelTable; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -/** - * Created by Akmm at 2022/5/6 15:43 - * 实体辅助类 - */ -public class EntityHelper { - //获取字段别名 - private static String getFieldAlias(Map mapFieldAlias, String field) { - return (mapFieldAlias != null && mapFieldAlias.containsKey(field)) ? mapFieldAlias.get(field) : field; - } - - /** - * 添加关联字段值 - * @param tableName - * @param bean - */ - public static void loadBeanLink(String tableName, SwMap bean, Map mapFieldAlias) { - //添加关联字段值 - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table == null) return; - List listLink = table.findLinkeNames(); - if (listLink.isEmpty()) return; - - //有缓存的,从缓存拿,无缓存的放Map,最后从数据库去拿 - Map> mapIds = new HashMap<>(); - - for (ModelLinkName l : listLink) { - final String fieldName = getFieldAlias(mapFieldAlias, l.getFieldName()); - String value = bean.readString(fieldName); - if (StringUtils.isEmpty(value)) continue; - String[] ids = StringUtils.split(value, ","); - if (l.getLinkTable().isNeedCache()) { - EntityDao dao = DbEngine.getInstance().findDao(l.getLinkTable().getName()); - AbstractCache cache = CacheManager.getIntance().getCache(l.getLinkTable().getName()); - String names = ""; - for (String sId : ids) { - Object b = cache.get(sId); - String sn = (String) dao.readValue(b, l.getLinkNameField()); - if (StringUtils.isNotEmpty(sn)) names += "," + sn; - } - bean.put(fieldName + "_text", names.length() > 1 ? names.substring(1) : ""); - } else { - List list = mapIds.computeIfAbsent(l.getLinkTable().getName(), k -> new ArrayList<>()); - Collections.addAll(list, ids); - } - } - - - if (mapIds.isEmpty()) return; - //数据库查询 - Map> mapValue = new HashMap<>(); - for (Map.Entry> entry : mapIds.entrySet()) { - EntityDao dao = DbEngine.getInstance().findDao(entry.getKey()); - mapValue.put(entry.getKey(), dao.queryNames(entry.getValue())); - } - //加值 - - for (ModelLinkName l : listLink) { - if (!mapValue.containsKey(l.getLinkTable().getName())) continue; - Map mapV = mapValue.get(l.getLinkTable().getName()); - - final String fieldName = getFieldAlias(mapFieldAlias, l.getFieldName()); - String value = bean.readString(fieldName); - if (StringUtils.isEmpty(value)) continue; - - String[] ids = StringUtils.split(value, ","); - String names = ""; - for (String sId : ids) { - String sn = mapV.get(sId); - if (StringUtils.isNotEmpty(sn)) names += "," + sn; - } - bean.put(fieldName + "_text", names.substring(1)); - } - } - - public static void loadBeanLink(String tableName, List listData, Map mapFieldAlias) { - //添加关联字段值 - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table == null) return; - List listLink = table.findLinkeNames(); - if (listLink.isEmpty()) return; - - //有缓存的,从缓存拿,无缓存的放Map,最后从数据库去拿 - Map> mapIds = new HashMap<>(); - for (SwMap row : listData) { - for (ModelLinkName l : listLink) { - final String fieldName = getFieldAlias(mapFieldAlias, l.getFieldName()); - String value = row.readString(fieldName); - if (StringUtils.isEmpty(value)) continue; - String[] ids = StringUtils.split(value, ","); - if (l.getLinkTable().isNeedCache()) { - EntityDao dao = DbEngine.getInstance().findDao(l.getLinkTable().getName()); - AbstractCache cache = CacheManager.getIntance().getCache(l.getLinkTable().getName()); - String names = ""; - for (String sId : ids) { - Object b = cache.get(sId); - String sn = (String) dao.readValue(b, l.getLinkNameField()); - if (StringUtils.isNotEmpty(sn)) names += "," + sn; - } - if (StringUtils.isNotEmpty(names)) { - row.put(fieldName + "_text", names.substring(1)); - } else { - row.put(fieldName + "_text", ""); - } - } else { - List list = mapIds.computeIfAbsent(l.getLinkTable().getName(), k -> new ArrayList<>()); - for (String id : ids) { - list.add(Long.parseLong(id)); - } - } - } - } - - if (mapIds.isEmpty()) return; - //数据库查询 - Map> mapValue = new HashMap<>(); - for (Map.Entry> entry : mapIds.entrySet()) { - EntityDao dao = DbEngine.getInstance().findDao(entry.getKey()); - mapValue.put(entry.getKey(), dao.queryNames(entry.getValue())); - } - //加值 - for (SwMap row : listData) { - for (ModelLinkName l : listLink) { - if (!mapValue.containsKey(l.getLinkTable().getName())) continue; - Map mapV = mapValue.get(l.getLinkTable().getName()); - - final String fieldName = getFieldAlias(mapFieldAlias, l.getFieldName()); - String value = row.readString(fieldName); - if (StringUtils.isEmpty(value)) continue; - - String[] ids = StringUtils.split(value, ","); - String names = ""; - for (String sId : ids) { - String sn = mapV.get(sId); - if (StringUtils.isNotEmpty(sn)) names += "," + sn; - } - row.put(fieldName + "_text", names.substring(1)); - } - } - } - - //检查表记录是否被引用 - public static void checkExists(long tableId, long id) { - ModelTable fkTable = ModelTableCache.getInstance().get(tableId); - if (fkTable == null) throw new BizException("待检查表(" + tableId + ")为空!"); - checkExists(fkTable, id); - } - public static void checkExists(String tableName, long id) { - ModelTable fkTable = ModelTableCache.getInstance().getByName(tableName); - if (fkTable == null) throw new BizException("待检查表(" + tableName + ")为空!"); - checkExists(fkTable, id); - } - - /** - * 检查记录是否被使用 - * @param fkTable - * @param id - */ - public static void checkExists(ModelTable fkTable, long id) { - Set list = ModelTableCache.getInstance().getByLink(fkTable.getId()); - if (list == null || list.isEmpty()) return; - for (ModelTable table: list) { - StringBuilder sql = new StringBuilder(256); - List args = new ArrayList<>(); - for (ModelField field: table.getFields()) { - if (field.getLink() == fkTable.getId()) { - sql.append(" or ").append(field.getName()).append("=?"); - args.add(id); - } - } - if (sql.length() == 0) continue; - if (DbEngine.getInstance().isExists("select 1 from " + table.getSchemaTableName() + " where " + sql.substring(4), args.toArray())) { - throw new BizException("该记录被表【" + table.getTitle() + "(" + table.getName() + ")】引用,不能删除!"); - } - } - } - - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/EntityCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/EntityCache.java deleted file mode 100644 index b95d305..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/EntityCache.java +++ /dev/null @@ -1,66 +0,0 @@ -package cc.smtweb.framework.core.db.cache; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelCache; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.controller.scan.BeanManager; -import cc.smtweb.framework.core.util.CommUtil; -import org.apache.commons.lang3.StringUtils; - -import java.util.List; - -/** - * Created by Akmm at 2022/2/19 17:19 - */ -public class EntityCache extends AbstractCache { - private String tableName; - - public EntityCache(String tableName) { - this.tableName = tableName; - Class clazz = (Class)BeanManager.getInstance().getTableClass(tableName); - if (clazz != null) { - this.pTypeClass = clazz; - } - - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - - ident = tableName; - title = table.getTitle(); - lazy = false; - - if (!table.isNeedCache() || CommUtil.isEmpty(table.getCaches())) return; - - for (ModelCache cache : table.getCaches()) { - final IGetBeanKey key = bean -> { - String ret = ""; - for (String s : StringUtils.split(cache.getFields(), ",")) { - if (StringUtils.isNotEmpty(s)) { - ret += SwConsts.SPLIT_CHAR + bean.getStr(s); - } - } - return ret.substring(1); - }; - if (cache.isMapType()) { - regMap(cache.getName(), key); - } else { - regList(cache.getName(), key); - } - } - } - - @Override - protected String getId(DefaultEntity bean) { - return String.valueOf(bean.getEntityId()); - } - - @Override - protected List loadAll() { - EntityDao dao = DbEngine.getInstance().findDao(tableName); - return dao.query(); - } - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java deleted file mode 100644 index 4029d60..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java +++ /dev/null @@ -1,46 +0,0 @@ -package cc.smtweb.framework.core.db.cache; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.vo.ModelDatabase; - -import java.util.List; - -/** - * Created by Akmm at 2022/1/12 18:34 - */ -@SwCache(ident = "ASP_MODEL_DATABASE", title = "数据库") -public class ModelDatabaseCache extends AbstractCache { - private final static String mk = "k"; - - public static ModelDatabaseCache getInstance() { - return CacheManager.getIntance().getCache(ModelDatabaseCache.class); - } - - public ModelDatabaseCache() { - regMap(mk, ModelDatabase::getName); - } - - @Override - protected String getId(ModelDatabase bean) { - return String.valueOf(bean.getId()); - } - - @Override - protected List loadAll() { - EntityDao dao = DbEngine.getInstance().findDao(ModelDatabase.class); - return dao.query(); - } - - public final ModelDatabase getByName(String key) { - return getByKey(mk, key); - } - - public final String getName(long id) { - ModelDatabase db = get(id); - return db != null ? db.getName() : ""; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelTableCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelTableCache.java deleted file mode 100644 index 703e606..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelTableCache.java +++ /dev/null @@ -1,123 +0,0 @@ -package cc.smtweb.framework.core.db.cache; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.ResultSetExtractor; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -/** - * Created by Akmm at 2022/1/12 18:34 - */ -@SwCache(ident = "ASP_MODEL_TABLE", title = "数据库表定义") -public class ModelTableCache extends AbstractCache { - private final static String mk = "k"; - private final static String md = "d"; - private final static String mc = "c"; - private final static String mk_link = "l"; - - public static ModelTableCache getInstance() { - return CacheManager.getIntance().getCache(ModelTableCache.class); - } - - public ModelTableCache() { - regMap(mk, k-> k.getName().toUpperCase()); - regList(md, k-> String.valueOf(k.getDbId())); - regList(mc, k-> String.valueOf(k.getMcId())); - regListEx(mk_link, k-> { - Set list = new HashSet<>(); - for (ModelField field: k.getFields()) { - if (field.getLink() > 0) list.add(String.valueOf(field.getLink())); - } - return list.toArray(new String[list.size()]); - }); -// regList(mf, k-> k.get); - } - - @Override - protected String getId(ModelTable bean) { - return String.valueOf(bean.getId()); - } - - @Override - protected List loadAll() { - return DbEngine.getInstance().query("SELECT\n" + - "t.tb_id,\n" + - "t.tb_prj_id,\n" + - "t.tb_mc_id,\n" + - "t.tb_db_id,\n" + - "t.tb_extends,\n" + - "t.tb_name,\n" + - "t.tb_title,\n" + - "t.tb_abbr,\n" + - "t.tb_type,\n" + - "t.tb_need_cache,\n" + - "t.tb_content,\n" + - "t.tb_create_uid,\n" + - "t.tb_update_uid,\n" + - "t.tb_create_at,\n" + - "t.tb_update_at\n" + - "from asp_model_table t\n", new ResultSetExtractor>() { - @Override - public List extractData(ResultSet rs) throws SQLException, DataAccessException { - List list = new ArrayList<>(); - while (rs.next()) { - ModelTable table = new ModelTable(); - list.add(table); - table.setId(rs.getLong("tb_id")); - table.setDbId(rs.getLong("tb_db_id")); - table.setPrjId(rs.getLong("tb_prj_id")); - table.setMcId(rs.getLong("tb_mc_id")); - table.setExtends(rs.getString("tb_extends")); - table.setName(rs.getString("tb_name").toUpperCase()); - table.setTitle(rs.getString("tb_title")); - table.setAbbr(rs.getString("tb_abbr")); - table.setType(rs.getInt("tb_type")); - table.setNeedCache(rs.getInt("tb_need_cache") == 1); - table.setCreateUid(rs.getLong("tb_create_uid")); - table.setUpdateUid(rs.getLong("tb_update_uid")); - table.setCreateAt(rs.getLong("tb_create_at")); - table.setUpdateAt(rs.getLong("tb_update_at")); - table.setContent(rs.getString("tb_content")); - } - return list; - } - }); - } - - public final ModelTable getByName(String key) { - return getByKey(mk, key.toUpperCase()); - } - public final Set getDbTables(long dbId) { - return getListByKey(md, String.valueOf(dbId)); - } - - public final Set getTablesByMc(long mcId) { - return getListByKey(mc, String.valueOf(mcId)); - } - - public final List getTablesByMc(long mcId, Comparator comparator) { - Set set = getListByKey(mc, String.valueOf(mcId)); - if (set == null || set.isEmpty()) return null; - List list = new ArrayList<>(set); - list.sort(comparator); - return list; - } - - public final String getTableName(long id) { - ModelTable bean = get(id); - return bean == null ? String.valueOf(id) : bean.getTitle(); - } - - //根据外键 - public final Set getByLink(long tableId) { - return getListByKey(mk_link, String.valueOf(tableId)); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/config/DbEngineConfiguration.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/config/DbEngineConfiguration.java deleted file mode 100644 index 774420e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/config/DbEngineConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -package cc.smtweb.framework.core.db.config; - -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.jdbc.IdGenerator; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; - -/** - * 默认数据源 - * @author xkliu - */ -@Configuration -public class DbEngineConfiguration { - @Value("${smtweb.db.type}") - private String dbType; -// @Bean -// public DataSource dataSource() { -// return DataSourceBuilder.create().build(); -// } -// -// @Bean -// public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) { -// return new NamedParameterJdbcTemplate(dataSource); -// } - - /** - * 产生数据库数据库访问对象 dbEngine - * @param namedJdbcTemplate Spring框架Jdbc,通过 spring.datasource 配置 - * @param idGenerator ID生成器对象,思想数据库ID生成 - * @return dbEngine对象 - */ - @Bean - @ConfigurationProperties(prefix = "smtweb.db.default") - public DbEngine dbEngine(NamedParameterJdbcTemplate namedJdbcTemplate, IdGenerator idGenerator) { - System.out.println("create dbEngine============="); - return new DbEngine(namedJdbcTemplate, idGenerator, dbType); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/config/YamlPropertyLoaderFactory.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/config/YamlPropertyLoaderFactory.java deleted file mode 100644 index 24c0c05..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/config/YamlPropertyLoaderFactory.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.smtweb.framework.core.db.config; - -import org.springframework.boot.env.YamlPropertySourceLoader; -import org.springframework.core.env.PropertySource; -import org.springframework.core.io.support.DefaultPropertySourceFactory; -import org.springframework.core.io.support.EncodedResource; - -import java.io.IOException; - -/** - * 实现yaml配置文件加载工厂,以使用@PropertySource注解加载指定yaml文件的配置 - */ -public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory { - @Override - public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException { - - if (null == resource) { - super.createPropertySource(name, resource); - } - return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource()).get(0); - } - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java deleted file mode 100644 index 45570e1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java +++ /dev/null @@ -1,399 +0,0 @@ -package cc.smtweb.framework.core.db.dao; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.exception.DbException; -import cc.smtweb.framework.core.util.DateUtil; -import cc.smtweb.framework.core.util.SpringUtil; -import cc.smtweb.framework.core.util.VariableUtil; -import org.apache.commons.lang3.StringUtils; -import org.springframework.util.ClassUtils; - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * 抽象的值对象数据库访问 - * - * @param 数据库值对象类型 - */ -public abstract class AbstractEntityDao { - protected ModelTable modelTable; - protected String tableName; - protected Map columns = new HashMap<>(); - protected Class type; - protected CacheManager cacheManager = SpringUtil.getBean(CacheManager.class); -// public AbstractEntityDao(String tableName) { -// this.tableName = tableName; -// } - - /** - * 通过值对象类型构造值对象数据库访问 - * - * @param type 值对象类型 - */ - public AbstractEntityDao(Class type) { - this.type = type; - // type.isAnnotationPresent(Table.class); - SwTable table = type.getAnnotation(SwTable.class); - Class superclass = type.getSuperclass(); - - if (table == null && superclass != null) { - table = superclass.getAnnotation(SwTable.class); - } - - if (table == null) { - throw new IllegalAccessError("not find annotation @SwTable"); - } - - tableName = table.value(); - modelTable = ModelTableCache.getInstance().getByName(tableName); - if (DefaultEntity.class.isAssignableFrom(type)) { - for (ModelField field : modelTable.getFields()) { - add(field, null, null); - } - } else { - for (ModelField field : modelTable.getFields()) { - String voFieldName = getVoFieldName(modelTable.getAbbr(), field.getName()); - // 处理get method - try { - PropertyDescriptor pd = new PropertyDescriptor(voFieldName, type); - // 获得get方法 - Method readMethod = pd.getReadMethod(); - Method writeMethod = pd.getWriteMethod(); - - if (readMethod != null && writeMethod != null) { - Class[] parameterTypes = writeMethod.getParameterTypes(); - if (parameterTypes.length == 1 && ClassUtils.isAssignable(parameterTypes[0], readMethod.getReturnType())) { - add(field, readMethod, writeMethod); - } - } - } catch (IntrospectionException ignore) { - } - } - } - } - - /** - * 通过值对象类型构造值对象数据库访问 - * - * @param tableName 表名 - */ - public AbstractEntityDao(String tableName) { - this.tableName = tableName; - this.type = (Class) DefaultEntity.class; - modelTable = cacheManager.getCache(ModelTableCache.class).getByName(tableName); - - for (ModelField field : modelTable.getFields()) { - add(field, null, null); - } - } - - /** - * 根据字段名,得到类中的字段属性名 - * - * @param tbAbbr 表缩写,一般是字段的前缀 - * @param fieldName 字段名 - * @return - */ - private String getVoFieldName(String tbAbbr, String fieldName) { - fieldName = fieldName.toLowerCase(); - tbAbbr = tbAbbr.toLowerCase() + "_"; - if (fieldName.startsWith(tbAbbr)) return VariableUtil.underlineToHump(fieldName.substring(tbAbbr.length())); - return VariableUtil.underlineToHump(fieldName); - } - - /** - * 添加值对象的属性访问方法何注解值 - * - * @param field 字段名 - * @param readMethod 读值对象属性方法 - * @param writeMethod 写值值对象属性方法 - */ - protected void add(ModelField field, Method readMethod, Method writeMethod) { - EntityColumn beanColumn = new EntityColumn(field, readMethod, writeMethod); - columns.put(field.getName(), beanColumn); - } - - protected void updateTime(T obj, int type) { - ModelField field = modelTable.findFieldByType(type); - if (field == null) return; - EntityColumn col = columns.get(field.getName()); - if (col != null) { - col.writeValue(obj, DateUtil.nowDateTimeLong()); - } - } - - /** - * 校验传入的字段,如没有创建时间和最后更改时间,则加上 - * - * @param fields - * @return - */ - protected List adjustFields(String fields, int... types) { - if (StringUtils.isEmpty(fields)) return null; - String[] fieldNames = fields.toLowerCase().split(","); - List listFields = new ArrayList<>(fieldNames.length + 2); - boolean[] includeTypes = new boolean[types.length]; - for (int i = 0, len = includeTypes.length; i < len; i++) { - includeTypes[i] = false; - } - - for (String name : fieldNames) { - EntityColumn column = this.columns.get(name.trim()); - for (int i = 0, len = types.length; i < len; i++) { - if (types[i]== column.getField().getFieldType()) { - includeTypes[i] = true; - } - } - listFields.add(name); - } - for (int i = 0, len = types.length; i < len; i++) { - if (!includeTypes[i]) { - ModelField field = modelTable.findFieldByType(types[i]); - if (field != null) listFields.add(field.getName()); - } - } - return listFields; - } - - /** - * 拼接插入SQL语句 - * - * @param obj 值对象 - * @param sql 记录sql的字符缓存 - * @param fields 逗号分割字段列表,设置为null表示使用所有字段 - * @return SQL参数列表 - */ - protected Object[] handleInsert(T obj, StringBuilder sql, String fields) { - List result; - List listFields = adjustFields(fields, SwEnum.FieldType.CREATE_TIME.value, SwEnum.FieldType.LAST_TIME.value); - sql.append("insert into ").append(modelTable.getSchemaTableName()).append("("); - - updateTime(obj, SwEnum.FieldType.CREATE_TIME.value); - updateTime(obj, SwEnum.FieldType.LAST_TIME.value); - - if (listFields == null) { - result = new ArrayList<>(this.columns.size()); - - for (EntityColumn column : this.columns.values()) { - result.add(column.readValue(obj)); - sql.append(column.getField().getName()).append(","); - } - } else { - result = new ArrayList<>(listFields.size()); - - for (String name : listFields) { - EntityColumn column = this.columns.get(name.trim()); - result.add(column.readValue(obj)); - sql.append(column.getField().getName()).append(","); - } - } - - sql.setCharAt(sql.length() - 1, ')'); - - // values(?,?) - sql.append(" values("); - for (int i = result.size(); i > 0; i--) { - sql.append("?,"); - } - sql.setCharAt(sql.length() - 1, ')'); - - return result.toArray(); - } - - /** - * 拼接更新SQL语句 - * - * @param obj 值对象 - * @param sql 记录sql的字符缓存 - * @param fields 逗号分割更新字段列表,设置为null表示使用所有字段 - * @param whereFields 逗号分割查询字段列表,设置为null表示使用ID字段作为查询条件 - * @return SQL参数列表 - */ - protected Object[] handleUpdate(T obj, StringBuilder sql, String fields, String whereFields) { - EntityColumn idColumn = findIdColumn(); - - List listFields = adjustFields(fields, SwEnum.FieldType.LAST_TIME.value); - updateTime(obj, SwEnum.FieldType.LAST_TIME.value); - - sql.append("update ").append(modelTable.getSchemaTableName()).append(" set "); - List result = new ArrayList<>(); - - if (listFields == null) { - for (EntityColumn column : this.columns.values()) { - if (idColumn != column) { - sql.append(column.getField().getName()).append("=?,"); - result.add(column.readValue(obj)); - } - } - sql.setCharAt(sql.length() - 1, ' '); - - // 默认使用Id字段条件 - result.add(idColumn.readValue(obj)); - - sql.append("where ").append(idColumn.getField().getName()).append("=?"); - } else { - - for (String name : listFields) { - name = name.trim(); - EntityColumn beanColumn = getBeanColumn(name); - - sql.append(name).append("=?,"); - result.add(beanColumn.readValue(obj)); - - } - - sql.setCharAt(sql.length() - 1, ' '); - - if (StringUtils.isNotBlank(whereFields)) { - sql.append("where "); - boolean first = true; - for (String name : whereFields.split(",")) { - name = name.trim(); - if (first) { - first = false; - } else { - sql.append(" and "); - } - - sql.append(name).append("=?"); - result.add(readValue(obj, name)); - } - } else { - // 默认使用Id字段条件 - result.add(idColumn.readValue(obj)); - sql.append("where ").append(idColumn.getField().getName()).append("=?"); - } - } - return result.toArray(); - } - - private EntityColumn findIdColumn() { - ModelField field = modelTable.findIdField(); - EntityColumn idColumn = field != null ? columns.get(field.getName()) : null; - if (idColumn == null) { - throw new DbException(tableName + " not define id column"); - } - - return idColumn; - } - - /** - * 拼接删除值对象语句 - * - * @param obj 值对象 - * @param sql 记录sql的字符缓存 - * @return SQL参数列表 - */ - protected Object[] handleDelete(T obj, StringBuilder sql) { - EntityColumn idColumn = findIdColumn(); - - sql.append("DELETE FROM ").append(modelTable.getSchemaTableName()).append(" WHERE ").append(idColumn.getField()).append("=?"); - - return new Object[]{idColumn.readValue(obj)}; - } - - /** - * 拼接删除值对象语句,条件由外部设置 - * - * @param sql 记录sql的字符缓存 - */ - protected void handleDelete(StringBuilder sql) { - EntityColumn idColumn = findIdColumn(); - sql.append("DELETE FROM ").append(modelTable.getSchemaTableName()).append(" WHERE ").append(idColumn.getField().getName()).append("=?"); - } - - public Object readValue(T obj, String fieldName) { - if (obj == null) return null; - EntityColumn beanColumn = getBeanColumn(fieldName); - - return beanColumn.readValue(obj); - } - - private EntityColumn getBeanColumn(String fieldName) { - EntityColumn beanColumn = this.columns.get(fieldName); - - if (beanColumn == null) { - throw new DbException("not define column:" + fieldName); - } - - return beanColumn; - } - - /** - * 拼接查询SQL语句 - * - * @param sql SQL字符缓存 - * @param fields 逗号分割的查询字段列表,传入null表示全部值对象字段 - */ - public void handleSelect(StringBuilder sql, String fields) { - sql.append("select "); - - if (fields != null) { - sql.append(fields).append(' '); - } else { - for (String fieldName : columns.keySet()) { - sql.append(fieldName).append(','); - } - sql.setCharAt(sql.length() - 1, ' '); - } - - sql.append("from ").append(modelTable.getSchemaTableName()); - } - - protected void handleSelectOne(StringBuilder sql, String fields) { - EntityColumn idColumn = findIdColumn(); - - sql.append("select "); - - if (fields != null) { - sql.append(fields).append(' '); - } else { - for (EntityColumn field : columns.values()) { - sql.append(field.getField().getName()).append(","); - } - sql.setCharAt(sql.length() - 1, ' '); - } - - sql.append("from ").append(modelTable.getSchemaTableName()).append(" where ").append(idColumn.getField().getName()).append("=?"); - } - - /** - * 读取ID值 - * - * @param entity - * @return - */ - public Long readId(T entity) { - EntityColumn idColumn = findIdColumn(); - - return (Long) idColumn.readValue(entity); - } - - public T createBean() { - try { - T bean = this.type.newInstance(); - if (bean instanceof DefaultEntity) { - DefaultEntity b = (DefaultEntity)bean; - b.init(); - b.setTableName(this.tableName); - } - return bean; - } catch (Exception e) { - throw new SwException(e); - } - } -} - diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumn.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumn.java deleted file mode 100644 index 3bc20ea..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumn.java +++ /dev/null @@ -1,66 +0,0 @@ -package cc.smtweb.framework.core.db.dao; - -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.exception.DbException; -import lombok.Getter; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * 值对象字段处理类 - * @author xkliu - */ -@Getter -public class EntityColumn { - private ModelField field; - private final Method readMethod; - private final Method writeMethod; - - /** - * 构建值对象字段 - * @param field 字段名 - * @param readMethod 读值方法 - * @param writeMethod 写值方法 - */ - public EntityColumn(ModelField field, Method readMethod, Method writeMethod) { - this.field = field; - this.readMethod = readMethod; - this.writeMethod = writeMethod; - } - - /** - * 从对象中读取字段对应的属性值 - * @param obj 值对象 - * @return 属性值 - */ - public Object readValue(Object obj) { - if (readMethod != null) { - try { - return readMethod.invoke(obj); - } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { - throw new DbException(e); - } - } else { - return ((DefaultEntity)obj).get(field.getName()); - } - } - - /** - * 写入值到对象字段对象属性 - * @param obj 值对象 - * @param value 属性值 - */ - public void writeValue(Object obj, Object value) { - if (readMethod != null) { - try { - writeMethod.invoke(obj, value); - } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { - throw new DbException(e); - } - } else { - ((DefaultEntity)obj).put(field.getName(), value); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumnForeign.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumnForeign.java deleted file mode 100644 index 49c4d7d..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/dao/EntityColumnForeign.java +++ /dev/null @@ -1,26 +0,0 @@ -package cc.smtweb.framework.core.db.dao; - -import lombok.Getter; - -/** - * 字段外键属性 - * @author admin - */ -@Getter -public class EntityColumnForeign { - private final String table; - private final String id; - private final String name; - - /** - * 构造字段外键属性 - * @param table 外键表名 - * @param id 外键ID字段名 - * @param name 外键名称字段名 - */ - public EntityColumnForeign(String table, String id, String name) { - this.table = table; - this.id = id; - this.name = name; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/BaseBean.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/BaseBean.java deleted file mode 100644 index b4de094..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/BaseBean.java +++ /dev/null @@ -1,103 +0,0 @@ -package cc.smtweb.framework.core.db.impl; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.util.JsonUtil; -import cc.smtweb.framework.core.util.NumberUtil; -import cc.smtweb.framework.core.util.jackson.BaseBeanSerializer; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -import java.io.Serializable; -import java.util.Map; - -/** - * Created by Akmm at 2016-02-23 9:31 - * bean基类,基于Map, - */ -@JsonSerialize(using = BaseBeanSerializer.class) -public class BaseBean implements Serializable { - protected SwMap data = new SwMap(); - - public SwMap getData() { - return data; - } - - public void setData(SwMap data) { - this.data = data; - } - - @Override - public BaseBean clone() throws CloneNotSupportedException { - BaseBean bean = (BaseBean) super.clone(); - bean.data = new SwMap(); - bean.getData().putAll(this.data); - return bean; - } - - public boolean isEmpty() { - return data.isEmpty(); - } - - public String getStr(String fieldName) { - return getStr(fieldName, ""); - } - - public String getStr(String fieldName, String defValue) { - Object o = data.get(fieldName); - return o != null ? o.toString() : defValue; - } - - public double getDouble(String fieldName) { - return getDouble(fieldName, 0.0); - } - - public double getDouble(String fieldName, double defValue) { - Object o = data.get(fieldName); - if (o == null) return defValue; - if (o instanceof Number) return ((Number) o).doubleValue(); - return NumberUtil.getDoubleIgnoreErr(o.toString()); - } - - public int getInt(String fieldName) { - Object o = data.get(fieldName); - if (o == null) return 0; - if (o instanceof Number) return ((Number) o).intValue(); - return NumberUtil.getIntIgnoreErr(o.toString()); - } - - public long getLong(String fieldName) { - Object o = data.get(fieldName); - if (o == null) return 0L; - if (o instanceof Number) return ((Number) o).longValue(); - return NumberUtil.getLongIgnoreErr(o.toString()); - } - - public boolean getBool(String fieldName) { - Object o = data.get(fieldName); - if (o == null) return false; - String v = o.toString(); - return "1".equals(v) || "t".equalsIgnoreCase(v) || "true".equalsIgnoreCase(v); - } - - public void put(String fieldName, Object value) { - this.data.put(fieldName, value); - } - - public void setBool(String fieldName, boolean value) { - this.data.put(fieldName, value ? 1 : 0); - } - - public Object get(String fieldName) { - return this.data.get(fieldName); - } - - public void readFromJson(String json) { - Map map = JsonUtil.parseMap(json); - if (map != null) { - data.putAll(map); - } - } - - public void readFromMap(SwMap map) { - data.putAll(map); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java deleted file mode 100644 index f73b50d..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java +++ /dev/null @@ -1,556 +0,0 @@ -package cc.smtweb.framework.core.db.impl; - -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelIndex; -import cc.smtweb.framework.core.db.vo.ModelTable; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.text.MessageFormat; -import java.util.*; - -/** - * Created with IntelliJ IDEA. - * User: AKhh - * Date: 12-12-21 下午2:41 - * 启动时检查数据库并自动建表、字段、索引; - */ -@Slf4j -@SuppressWarnings("UnusedDeclaration") -public class DatabaseUtil { - private static final int INDEX_NAME_MAX_LENGTH = 30; //索引名称长度; - private static final String MODULE = DatabaseUtil.class.getName(); - private IDatabaseInfo databaseInfo; - //是否需要根据实体定义清理数据库字段 - private boolean is_db_clean_field = false; - //是否需要根据实体定义清理数据库表 - private boolean is_db_clean_table = false; - - public DatabaseUtil(boolean is_db_clean_field, boolean is_db_clean_table) { - this.is_db_clean_field = is_db_clean_field; - this.is_db_clean_table = is_db_clean_table; - this.databaseInfo = new DefaultDatabaseInfoImpl(); - } - - /** - * 检测数据库结构和配置是否一致,根据配置增加表或字段信息; - */ - public void checkDb() { - UtilTime timer = new UtilTime(); - timer.setLog(true); - timer.timerString("Start - 开始获取连接的数据库的元信息!"); - this.databaseInfo.printDatabaseInfo(); - // get ALL tables from this database - Map tableNames = this.databaseInfo.getTables(); - //Set fkTableNames = (tableNames == null ? null : new HashSet(tableNames.values())); - //Set indexTableNames = (tableNames == null ? null : new HashSet(tableNames.values())); - if (tableNames == null) { - String message = "不能从数据库获取表名信息,将被跳过..."; - log.error(message, MODULE); - return; - } - timer.timerString("已从数据库获取所有的表名信息!"); - // get ALL column info, put into hashmap by table name - Map> colInfo = this.databaseInfo.getColumnInfo(tableNames); - if (colInfo == null) { - String message = "不能从数据库获取字段列信息,将被跳过..."; - log.error(message, MODULE); - return; - } - timer.timerString("已获取所有的数据库字段列信息。"); - //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - timer.timerString("开始检查表,列定义信息....................................."); - Collection ModelTableDefList = ModelTableCache.getInstance().getAll(); - Iterator ModelTableIter = ModelTableDefList.iterator(); - int curEnt = 0; - int totalEnt = ModelTableDefList.size(); - List entitiesAdded = new LinkedList<>(); // 数据库中没有的实体, 通过建表 - // 数据库中有表, 也有对应的实体 - Map entitiesExist = new HashMap<>(); - while (ModelTableIter.hasNext()) { - curEnt++; - ModelTable entity = ModelTableIter.next(); - String entMessage = "(" + timer.timeSinceLast() + "ms) Checking #" + curEnt + "/" + totalEnt + " Entity " + entity.getName(); - log.info(entMessage, MODULE); - String k = entity.getName(); //表名 - // -make sure all entities have a corresponding table - if (tableNames.containsKey(k)) { - IDatabaseInfo.TableCheckInfo table = tableNames.remove(k); - entitiesExist.put(table, entity); - if (colInfo != null) { - List delCols = new ArrayList<>(); - Map fieldColNames = new HashMap<>(); - for (int fnum = 0, len = entity.getFields().size(); fnum < len; fnum++) { - ModelField field = entity.getFields().get(fnum); - fieldColNames.put(field.getName().toUpperCase(), field); // XML读出来是小写,数据库读取来是大写. - } - List colList = colInfo.get(entity.getName()); - int numCols = 0; - if (colList != null) { - for (; numCols < colList.size(); numCols++) { - IDatabaseInfo.ColumnCheckInfo ccInfo = colList.get(numCols); - ccInfo.columnName = ccInfo.columnName.toUpperCase(); - // -list all columns that do not have a corresponding field - if (fieldColNames.containsKey(ccInfo.columnName)) { - ModelField field = fieldColNames.remove(ccInfo.columnName); - SwEnum.DataTypeBean modelFieldType = SwEnum.DataType.instance.getByValue(field.getDataType()); - if (modelFieldType != null) { - // make sure each corresponding column is of the correct type - if (!ccInfo.typeName.equalsIgnoreCase(modelFieldType.sqlType)) { - String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段类型不一致:::数据库:[" + ccInfo.typeName + "], " + - "实体定义:[" + modelFieldType.sqlType + "]!"; - log.error(message, MODULE); - } - if (modelFieldType.dataLength != 0 && ccInfo.columnSize != -1 && modelFieldType.dataLength != ccInfo.columnSize) { - String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段长度不一致:::数据库:[" + ccInfo.columnSize + "], " + - "实体定义:[" + modelFieldType.dataLength + "]!"; - log.debug(message, MODULE); - } - /*if (decimalDigits != -1 && decimalDigits != ccInfo.decimalDigits) { - String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 小数位数不一致:::数据库:[" + ccInfo.decimalDigits + "], " + - "实体定义:[" + decimalDigits + "]!"; - log.debug(message, MODULE); - }*/ - } else { - String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段类型定义错误[" + field.getDataType() + "]!"; - - log.error(message, MODULE); - } - } else { - String message = "表\"" + entity.getName() + "\"字段\"" + ccInfo.columnName + "\"没有定义!"; - log.debug(message, MODULE); - if (is_db_clean_field) { - delCols.add(ccInfo.columnName); - } - } - } - } - // -display message if number of table columns does not match number of entity fields - if (!is_db_clean_field) { - if (numCols != entity.getFields().size()) { - String message = "表[" + entity.getName() + "]定义了" + entity.getFields().size() + "个字段,但数据库有" + numCols + "个字段!"; - log.debug(message, MODULE); - } - } else if (delCols.size() > 0) { - String errMsg = dropColumn(entity, delCols); - String message; - if (errMsg != null && errMsg.length() > 0) { - message = "清理字段出错,表:\"" + entity.getName() + "\": " + errMsg; - log.error(message, MODULE); - } else { - message = "清理字段成功,表:\"" + entity.getName() + "\""; - log.debug(message, MODULE); - } - } - // -list all fields that do not have a corresponding column - for (String colName : fieldColNames.keySet()) { - ModelField field = fieldColNames.get(colName); - String message = "Field \"" + field.getName() + "\" of entity \"" + entity.getName() + "\" is missing its corresponding column \"" + field.getName() + "\""; - log.debug(message, MODULE); - // add the column - String errMsg = addColumn(entity, field); - if (errMsg != null && errMsg.length() > 0) { - message = "加字段出错,表:\"" + entity.getName() + "\".\"" + field.getName() + "\": " + errMsg; - log.error(message, MODULE); - } else { - message = "加字段成功,表:\"" + entity.getName() + "\".\"" + field.getName() + "\""; - log.debug(message, MODULE); - } - } - //修复主键 - if (StringUtils.isEmpty(table.pk)) { - String errMsg = addPk(entity); - String message; - if (errMsg != null && errMsg.length() > 0) { - message = "修复主键出错,表:\"" + entity.getName() + "\": " + errMsg; - log.error(message, MODULE); - } else { - message = "修复主键成功,表:\"" + entity.getName() + "\""; - log.debug(message, MODULE); - } - } - } - } else { - String message = "数据库没有找到表\"" + entity.getName() + "\""; - log.debug(message, MODULE); - // create the table - String errMsg = createTable(entity); - if (StringUtils.isNotEmpty(errMsg)) { - message = "建表\"" + entity.getName() + "\"出错: " + errMsg; - log.error(message, MODULE); - } else { - entitiesAdded.add(entity); - message = "建表成功\"" + entity.getName() + "\""; - log.debug(message, MODULE); - } - } - } - timer.timerString("After Individual Table/Column Check"); - // -list all tables that do not have a corresponding entity - Iterator tableNamesIter = tableNames.keySet().iterator(); - while (tableNamesIter != null && tableNamesIter.hasNext()) { - String tableName = tableNamesIter.next(); - if (!is_db_clean_table) { - String message = "表\"" + tableName + "\"没有实体定义文件!"; - log.debug(message, MODULE); - } else { - String message, errMsg = dropTable(tableNames.get(tableName).catalog, tableName); - if (StringUtils.isNotEmpty(errMsg)) { - message = "删除表\"" + tableName + "\"出错: " + errMsg; - log.error(message, MODULE); - } else { - message = "删除表成功\"" + tableName + "\""; - log.debug(message, MODULE); - } - } - } - - // for each newly added table, add declared indexes - for (ModelTable curEntity : entitiesAdded) { - String indErrMsg = this.createDeclaredIndices(curEntity); - if (indErrMsg != null && indErrMsg.length() > 0) { - String message = "建索引出错,表\"" + curEntity.getName() + "\": " + indErrMsg; - log.error(message, MODULE); - } else { - String message = "建索引成功,表 \"" + curEntity.getName() + "\""; - log.debug(message, MODULE); - } - } - // 补充索引 get ALL column info, put into hashmap by table name - Map>> tableIndexListMap = this.databaseInfo.getIndexInfo(entitiesExist.keySet(), true); - for (ModelTable entity : entitiesExist.values()) { - // 实体未定义索引. - if (entity.getIndexes().isEmpty()) - continue; - // get existing index map for this table - Map> exists_indexes = tableIndexListMap.get(entity.getName()); - Set setEnabled = new HashSet<>();//有效的索引 - for (ModelIndex mi: entity.getIndexes()) { - if (SwEnum.IndexType.PK.value.equalsIgnoreCase(mi.getType())) continue; - - Set dbfields = null; - String indexName = getDbIndexName(entity, mi); - if (exists_indexes != null) dbfields = exists_indexes.get(indexName); - setEnabled.add(mi.getName()); - if (!hasDiff(mi.getFields(), dbfields)) {//没有变化,不管 - continue; - } - if (dbfields != null) deleteDeclaredIndex(entity.getSchemaTableName(), indexName); - - // 建数据库已经有表的不存在的索引 - String indErrMsg = this.createDeclaredIndex(entity, mi); - if (indErrMsg != null && indErrMsg.length() > 0) { - String message = "建索引出错,表:\"" + entity.getName() + "\".\"" + mi.getName() + "\": " + indErrMsg; - log.error(message, MODULE); - } else { - String message = "Created declared index [" + mi.getName() + "] for entity \"" + entity.getName() + "\""; - log.debug(message, MODULE); - } - } - for (String indexName : exists_indexes.keySet()) { - if (!setEnabled.contains(indexName)) deleteDeclaredIndex(entity.getSchemaTableName(), indexName); - } - } - timer.timerString("数据库结构检测和同步完成!"); - } - - //顺序不一致,也要重建 - private boolean hasDiff(String fields1, Set fields2) { - if (StringUtils.isEmpty(fields1) || fields2 == null) return true; - String[] f1 = fields1.split(","); - if (fields1.length() != fields2.size()) return true; - int n = 0; - for (String s : fields2) { - if (!s.equalsIgnoreCase(f1[n].toLowerCase())) return true; - n++; - } - return false; - } - - /** - * 建表 - * - * @param entity ModelTable - * @return String 错误消息 - */ - public String createTable(ModelTable entity) { - if (entity == null) { - return "ModelTable was null and is required to create a table"; - } - -// entity.setCurCreated(true); - StringBuilder sqlBuf = new StringBuilder("CREATE TABLE "); - sqlBuf.append(entity.getSchemaTableName()); - sqlBuf.append(" ("); - for (ModelField field : entity.getFields()) { - SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType()); - - if (type == null) { - return "Field type [" + field.getDataType() + "] not found for field [" + field.getName() + "] of entity [" + entity.getName() + "], not creating table."; - } - - sqlBuf.append(field.getName()); - sqlBuf.append(" "); - sqlBuf.append(type.getSqlTypeCreate()); - - if (field.getName().equalsIgnoreCase(entity.getIdField())) { - sqlBuf.append(" NOT NULL , "); - } else { - if (!StringUtils.isEmpty(field.getDefaultValue())) { - sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'"); - } - sqlBuf.append(" , "); - } - } - String pkName = "PK_" + entity.getName(); - if (pkName.length() > INDEX_NAME_MAX_LENGTH) { - pkName = pkName.substring(0, INDEX_NAME_MAX_LENGTH); - } - sqlBuf.append("CONSTRAINT "); - sqlBuf.append(pkName); - sqlBuf.append(" PRIMARY KEY ("); - sqlBuf.append(entity.getIdField()); - sqlBuf.append("))"); - - try { - DbEngine.getInstance().update(sqlBuf.toString()); - } catch (Exception e) { - return e.getMessage(); - } - addTableComment(entity); - //加上字段注解: - for (ModelField field : entity.getFields()) { - addColumnComment(entity, field); - } - return null; - } - - public String addColumn(ModelTable entity, ModelField field) { - if (entity == null || field == null) { - return "ModelTable or ModelField where null, cannot add column"; - } - SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType()); - if (type == null) { - return "Field type not found for field [" + field.getName() + "] of entity [" + entity.getName() + "], not adding column."; - } - StringBuilder sqlBuf = new StringBuilder(128); - sqlBuf.append(MessageFormat.format("ALTER TABLE {0} ADD {1} {2}", entity.getSchemaTableName(), field.getName(), type.getSqlTypeCreate())); - if (!StringUtils.isEmpty(field.getDefaultValue())) { - sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'"); - } - log.debug("正在增加字段" + entity.getName() + "." + field.getName()); - try { - DbEngine.getInstance().update(sqlBuf.toString()); - } catch (Exception e) { - sqlBuf.setLength(0); - sqlBuf.append("ALTER TABLE ").append(entity.getSchemaTableName()).append(" ADD COLUMN ").append(field.getName()).append(" ").append(type.getSqlTypeCreate()); - if (StringUtils.isNotEmpty(field.getDefaultValue())) { - sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'"); - } - try { - DbEngine.getInstance().update(sqlBuf.toString()); - } catch (Exception e1) { - return e.getMessage(); - } - } - //加上字段注解: - addColumnComment(entity, field); - return null; - } - - public String addPk(ModelTable entity) { - if (entity == null) { - return "实体为null!"; - } - if (StringUtils.isEmpty(entity.getPkFieldName())) { - return "表" + entity.getName() + "没有定义主键!"; - } - String pkName = "PK_" + entity.getName(); - if (pkName.length() > INDEX_NAME_MAX_LENGTH) { - pkName = pkName.substring(0, INDEX_NAME_MAX_LENGTH); - } - StringBuilder sqlBuf = new StringBuilder(128); - sqlBuf.append("ALTER TABLE ").append(entity.getSchemaTableName()).append(" ADD CONSTRAINT ") - .append(pkName).append(" PRIMARY KEY (").append(entity.getIdField()).append(")"); - try { - DbEngine.getInstance().update(sqlBuf.toString()); - } catch (Exception e) { - return e.getMessage(); - } - return null; - } - - //删除表列 - public String dropColumn(ModelTable entity, List delCols) { - if (delCols.isEmpty()) return null; - StringBuilder sql = new StringBuilder(128); - sql.append("ALTER TABLE " + entity.getSchemaTableName()).append("\nDROP COLUMN("); - for (String col : delCols) { - sql.append(col).append(","); - } - - log.debug("正在删除表字段" + entity.getName()); - try { - DbEngine.getInstance().update(sql.substring(0, sql.length() - 1) + ")"); - } catch (Exception e) { - return e.getMessage(); - } - return null; - } - - //删除表 - public String dropTable(String catalog, String tableName) { - if (StringUtils.isNotEmpty(catalog)) tableName = catalog + "." + tableName; - log.debug("正在删除表" + tableName); - try { - DbEngine.getInstance().update("drop table " + tableName); - } catch (Exception e) { - return e.getMessage(); - } - return null; - } - - private String addTableComment(ModelTable entity) { - log.debug("正在增加表说明" + entity.getName()); - try { - DbEngine.getInstance().update("ALTER TABLE " + entity.getSchemaTableName() + " COMMENT '" + entity.getTitle() + "'"); - } catch (Exception e) { - return e.getMessage(); - } - return null; - } - - private String addColumnComment(ModelTable entity, ModelField field) { - log.debug("正在增加字段说明" + entity.getName() + "." + field.getName()); - // comment on column BASE_ENUM.DESCRIPTION is - SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType()); - if (type == null) return null; - try { - String defValue = StringUtils.isNotEmpty(field.getDefaultValue()) ? "'" + field.getDefaultValue() + "'" : ""; - String dvs = StringUtils.isNotEmpty(field.getDefaultValue()) ? " DEFAULT '" + field.getDefaultValue() + "'" : ""; - String sql = "ALTER TABLE " + entity.getSchemaTableName() + " MODIFY COLUMN " + field.getName() + " " + type.getSqlTypeCreate() + dvs + " COMMENT '" + field.getRemark() + "'"; - DbEngine.getInstance().update(sql); - } catch (Exception e) { - return e.getMessage(); - } - return null; - } - - /** - * 建立索引 - * - * @param entity 实体定义对象; - * @return 错误消息,处理正确会返回null - */ - public String createDeclaredIndices(ModelTable entity) { - if (entity == null) { - return "ModelTable was null and is required to create declared indices for a table"; - } - StringBuilder retMsgsBuffer = new StringBuilder(); - // go through the indexes to see if any need to be added - Iterator indexesIter = entity.getIndexes().iterator(); - for (ModelIndex modelIndex : entity.getIndexes()) { - String retMsg = createDeclaredIndex(entity, modelIndex); - if (retMsg != null && retMsg.length() > 0) { - if (retMsgsBuffer.length() > 0) { - retMsgsBuffer.append("\n"); - } - retMsgsBuffer.append(retMsg); - } - } - if (retMsgsBuffer.length() > 0) { - return retMsgsBuffer.toString(); - } else { - return null; - } - } - - private String createDeclaredIndex(ModelTable entity, ModelIndex modelIndex) { - log.debug("正在创建索引" + entity.getName() + "." + modelIndex.getName() + "....."); - String createIndexSql = makeIndexClause(entity, modelIndex); - if (StringUtils.isEmpty(createIndexSql)) return null; - try { - DbEngine.getInstance().update(createIndexSql); - } catch (Exception sqle) { - return "SQL Exception while executing the following:\n" + createIndexSql + "\nError was: " + sqle.toString(); - } - return null; - } - - /** - * 构造建立索引的脚本 - * - * @param entity 实体 - * @param modelIndex 索引定义; - * @return 脚本; - */ - private String makeIndexClause(ModelTable entity, ModelIndex modelIndex) { - if (SwEnum.IndexType.PK.value.equalsIgnoreCase(modelIndex.getType())) return null; - SwEnum.IndexTypeBean type = SwEnum.IndexType.instance.getByValue(modelIndex.getType()); - return "CREATE " + (SwEnum.IndexType.U.value.equalsIgnoreCase(modelIndex.getType()) ? SwEnum.IndexType.U.fullName : "") + - " INDEX " + getDbIndexName(entity, modelIndex) + - " ON " + entity.getSchemaTableName() + " (" + modelIndex.getFields() + ")"; - } - - /** - * 删除已经实体已经定义的索引 - * - * @param entity 实体 - * @return sql - */ - private String deleteDeclaredIndices(ModelTable entity) { - if (entity == null) { - return "ModelTable was null and is required to delete foreign keys indices for a table"; - } - StringBuilder retMsgsBuffer = new StringBuilder(); - // go through the relationships to see if any foreign keys need to be added - for (ModelIndex modelIndex : entity.getIndexes()) { - String retMsg = deleteDeclaredIndex(entity, modelIndex); - if (retMsg != null && retMsg.length() > 0) { - if (retMsgsBuffer.length() > 0) { - retMsgsBuffer.append("\n"); - } - retMsgsBuffer.append(retMsg); - } - } - if (retMsgsBuffer.length() > 0) { - return retMsgsBuffer.toString(); - } else { - return null; - } - } - - /** - * 删除已经定义的索引 - * - * @param entity 实体 - * @param modelIndex 索引; - * @return sql - */ - private String deleteDeclaredIndex(ModelTable entity, ModelIndex modelIndex) { - String deleteIndexSql = "DROP INDEX " + entity.getSchemaTableName() + "." + getDbIndexName(entity, modelIndex); - try { - DbEngine.getInstance().update(deleteIndexSql); - } catch (Exception sqle) { - return "SQL Exception while executing the following:\n" + deleteIndexSql + "\nError was: " + sqle.toString(); - } - return null; - } - - private String deleteDeclaredIndex(String tableName, String indexName) { - String deleteIndexSql = "DROP INDEX " + indexName + " ON " + tableName; - try { - DbEngine.getInstance().update(deleteIndexSql); - } catch (Exception sqle) { - return "SQL Exception while executing the following:\n" + deleteIndexSql + "\nError was: " + sqle.toString(); - } - return null; - } - - private String getDbIndexName(ModelTable entity, ModelIndex modelIndex) { - return entity.getAbbr() + "_" + modelIndex.getName(); - } -} \ No newline at end of file diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultDatabaseInfoImpl.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultDatabaseInfoImpl.java deleted file mode 100644 index 8e98425..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultDatabaseInfoImpl.java +++ /dev/null @@ -1,365 +0,0 @@ -package cc.smtweb.framework.core.db.impl; - -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.cache.ModelDatabaseCache; -import cc.smtweb.framework.core.db.vo.ModelDatabase; -import cc.smtweb.framework.core.util.SpringUtil; -import com.sun.org.apache.xpath.internal.operations.Mod; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.jdbc.support.JdbcUtils; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; -import java.util.function.Function; - -/** - * Created with IntelliJ IDEA. - * User: AKhh - * Date: 12-12-21 下午10:14 - * 获取连接的数据库相关信息,from ofbiz - */ -@Slf4j -public class DefaultDatabaseInfoImpl implements IDatabaseInfo { - private static final String MODULE = DefaultDatabaseInfoImpl.class.getName(); - private DbEngine dbEngine = SpringUtil.getBean(DbEngine.class); - - @SuppressWarnings("unchecked") - public void printDatabaseInfo() { - dbEngine.doConn(connection -> { - try { - DatabaseMetaData dbData = connection.getMetaData(); - // 数据库信息 - try { - log.debug("Database Product Name is " + dbData.getDatabaseProductName(), MODULE); - log.debug("Database Product Version is " + dbData.getDatabaseProductVersion(), MODULE); - } catch (SQLException sqle) { - log.debug("Unable to get Database name & version information", MODULE); - } - // JDBC Driver Info - try { - log.debug("Database Driver Name is " + dbData.getDriverName(), MODULE); - log.debug("Database Driver Version is " + dbData.getDriverVersion(), MODULE); - } catch (SQLException sqle) { - log.debug("Unable to get Driver name & version information", MODULE); - } - // Db/Driver support settings - try { - log.debug("Database Setting/Support Information (those with a * should be true):", MODULE); - log.debug("- supports transactions [" + dbData.supportsTransactions() + "]*", MODULE); - log.debug("- isolation None [" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE) + "]", MODULE); - log.debug("- isolation ReadCommitted [" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED) + "]", MODULE); - log.debug("- isolation ReadUncommitted[" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED) + "]", MODULE); - log.debug("- isolation RepeatableRead [" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ) + "]", MODULE); - log.debug("- isolation Serializable [" + dbData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE) + "]", MODULE); - log.debug("- is case sensitive [" + dbData.supportsMixedCaseIdentifiers() + "]", MODULE); - log.debug("- stores LowerCase [" + dbData.storesLowerCaseIdentifiers() + "]", MODULE); - log.debug("- stores MixedCase [" + dbData.storesMixedCaseIdentifiers() + "]", MODULE); - log.debug("- stores UpperCase [" + dbData.storesUpperCaseIdentifiers() + "]", MODULE); - log.debug("- max table name length [" + dbData.getMaxTableNameLength() + "]", MODULE); - log.debug("- max column name length [" + dbData.getMaxColumnNameLength() + "]", MODULE); - log.debug("- max schema name length [" + dbData.getMaxSchemaNameLength() + "]", MODULE); - log.debug("- concurrent connections [" + dbData.getMaxConnections() + "]", MODULE); - log.debug("- concurrent statements [" + dbData.getMaxStatements() + "]", MODULE); - log.debug("- ANSI SQL92 Entry [" + dbData.supportsANSI92EntryLevelSQL() + "]", MODULE); - log.debug("- ANSI SQL92 Itermediate [" + dbData.supportsANSI92IntermediateSQL() + "]", MODULE); - log.debug("- ANSI SQL92 Full [" + dbData.supportsANSI92FullSQL() + "]", MODULE); - log.debug("- ODBC SQL Grammar Core [" + dbData.supportsCoreSQLGrammar() + "]", MODULE); - log.debug("- ODBC SQL Grammar Extended[" + dbData.supportsExtendedSQLGrammar() + "]", MODULE); - log.debug("- ODBC SQL Grammar Minimum [" + dbData.supportsMinimumSQLGrammar() + "]", MODULE); - log.debug("- outer joins [" + dbData.supportsOuterJoins() + "]*", MODULE); - log.debug("- limited outer joins [" + dbData.supportsLimitedOuterJoins() + "]", MODULE); - log.debug("- full outer joins [" + dbData.supportsFullOuterJoins() + "]", MODULE); - log.debug("- group by [" + dbData.supportsGroupBy() + "]*", MODULE); - log.debug("- group by not in select [" + dbData.supportsGroupByUnrelated() + "]", MODULE); - log.debug("- column aliasing [" + dbData.supportsColumnAliasing() + "]", MODULE); - log.debug("- order by not in select [" + dbData.supportsOrderByUnrelated() + "]", MODULE); - // this doesn't work in HSQLDB, other databases? Debug.logInfo("- named parameters [" + dbData.supportsNamedParameters() + "]", MODULE); - log.debug("- alter table add column [" + dbData.supportsAlterTableWithAddColumn() + "]*", MODULE); - log.debug("- non-nullable column [" + dbData.supportsNonNullableColumns() + "]*", MODULE); - } catch (Exception e) { - log.error("Unable to get misc. support/setting information", e); - } - } catch (SQLException e) { - log.error(e.getMessage(), e); - } - return null; - }); - } - - //需要考虑分库的情况 - @SuppressWarnings("unchecked") - public Map getTables() { - final Map tables = new TreeMap<>(); - dbEngine.doConn(new Function() { - @Override - public Object apply(Connection connection) { - try { - DatabaseMetaData dbData = connection.getMetaData(); - if (dbData == null) { - return null; - } - System.out.println("获取数据库表信息..............................."); - boolean needsUpperCase = false; - try { - needsUpperCase = dbData.storesLowerCaseIdentifiers() || dbData.storesMixedCaseIdentifiers(); - } catch (SQLException sqle) { - String message = "Error getting identifier case information... Error was:" + sqle.toString(); - log.error(message, MODULE); - } - String lookupSchemaName = null; - if (dbData.supportsSchemasInTableDefinitions()) { - lookupSchemaName = dbData.getUserName(); - } - if (dbEngine.isMysql()) {//非oracle才需要 - String dbName = dbEngine.getDbSchema(); - Collection list = ModelDatabaseCache.getInstance().getAll(); - if (list != null && !list.isEmpty()) { - for (ModelDatabase db : list) { - getTableSet(dbData, dbName + "_" + db.getName(), needsUpperCase, lookupSchemaName); - } - } - //当前库都要去读 - getTableSet(dbData, dbName, needsUpperCase, lookupSchemaName); - } else { - //当前库都要去读 - getTableSet(dbData, null, needsUpperCase, lookupSchemaName); - } - } catch (SQLException e) { - log.error(e.getMessage(), e); - } - return null; - } - - private void getTableSet(DatabaseMetaData dbData, String catalog, boolean needsUpperCase, String lookupSchemaName) { - ResultSet tableSet = null; - try { - String[] types = {"TABLE"/*,"VIEW", "ALIAS", "SYNONYM"*/}; - tableSet = dbData.getTables(catalog, lookupSchemaName, null, types); - while (tableSet.next()) { - String tableName = tableSet.getString("TABLE_NAME"); - // for those databases which do not return the schema name with the table name (pgsql 7.3) - //boolean appendSchemaName = false; - if (needsUpperCase && tableName != null) { - tableName = tableName.toUpperCase(); - } - //if (appendSchemaName) { - // tableName = String.format("%s.%s", lookupSchemaName, tableName); - //} - String tableType = tableSet.getString("TABLE_TYPE"); - // only allow certain table types - if (tableType != null && - !"TABLE".equalsIgnoreCase(tableType) && - !"BASE TABLE".equalsIgnoreCase(tableType) && - !"VIEW".equalsIgnoreCase(tableType) && - !"ALIAS".equalsIgnoreCase(tableType) && - !"SYNONYM".equalsIgnoreCase(tableType)) { - continue; - } - try (ResultSet pkSet = dbData.getPrimaryKeys(catalog, lookupSchemaName, tableName)) { - String s = ""; - while (pkSet.next()) { - s += "," + pkSet.getString(4); - } - TableCheckInfo table = new TableCheckInfo(); - table.tableName = tableName; - table.catalog = catalog; - if (StringUtils.isNotEmpty(s)) { - table.pk = s.substring(1); - } - tables.put(tableName, table); - } - } - } catch (SQLException sqle) { - String message = "Error getting next table information... Error was:" + sqle.toString(); - log.error(message, MODULE); - } finally { - JdbcUtils.closeResultSet(tableSet); - } - } - }); - return tables; - } - - @SuppressWarnings("unchecked") - //获取列信息 - public Map> getColumnInfo(final Map dbTables) { - // if there are no tableNames, don't even try to get the columns - final Map> colInfo = new HashMap<>(); - if (dbTables.size() == 0) { - return colInfo; - } - dbEngine.doConn(new Function() { - @Override - public Object apply(Connection connection) { - try { - DatabaseMetaData dbData = connection.getMetaData(); - boolean needsUpperCase = false; - try { - needsUpperCase = dbData.storesLowerCaseIdentifiers() || dbData.storesMixedCaseIdentifiers(); - } catch (SQLException sqle) { - String message = "Error getting identifier case information... Error was:" + sqle.toString(); - log.error(message, MODULE); - } - - String lookupSchemaName = null; - if (dbData.supportsSchemasInTableDefinitions()) { - lookupSchemaName = dbData.getUserName(); - } - - if (dbEngine.isMysql()) {//非oracle才需要 - String dbName = dbEngine.getDbSchema(); - Collection list = ModelDatabaseCache.getInstance().getAll(); - if (list != null && !list.isEmpty()) { - for (ModelDatabase db : list) { - String dn = SwConsts.DEF_DB_NAME.equals(db.getName()) ? "" : ("_" + db.getName()); - getColumnInfo(dbData, dbName + dn, needsUpperCase, lookupSchemaName); - } - } - } - -// getColumnInfo(dbData, null, needsUpperCase, lookupSchemaName); - } catch (SQLException e) { - log.error(e.getMessage(), e); - } - return null; - } - - private void getColumnInfo(DatabaseMetaData dbData, String catalog, boolean needsUpperCase, String lookupSchemaName) { - ResultSet rsCols = null; - try { - rsCols = dbData.getColumns(catalog, lookupSchemaName, null, null); - while (rsCols.next()) { - ColumnCheckInfo ccInfo = new ColumnCheckInfo(); - - ccInfo.tableName = rsCols.getString("TABLE_NAME"); - // for those databases which do not return the schema name with the table name (pgsql 7.3) - //boolean appendSchemaName = false; - // AKzz : 不在表名前加用户名. - //if (ccInfo.tableName != null && lookupSchemaName != null && !ccInfo.tableName.startsWith(lookupSchemaName)) { - // appendSchemaName = true; - //} - if (needsUpperCase && ccInfo.tableName != null) { - ccInfo.tableName = ccInfo.tableName.toUpperCase(); - } - //if (appendSchemaName) { - // ccInfo.tableName = lookupSchemaName + "." + ccInfo.tableName; - //} - // ignore the column info if the table name is not in the list we are concerned with - if (!dbTables.containsKey(ccInfo.tableName)) { - continue; - } - ccInfo.columnName = rsCols.getString("COLUMN_NAME"); - if (needsUpperCase && ccInfo.columnName != null) { - ccInfo.columnName = ccInfo.columnName.toUpperCase(); - } - // NOTE: this may need a toUpperCase in some cases, keep an eye on it - ccInfo.typeName = rsCols.getString("TYPE_NAME"); - ccInfo.columnSize = rsCols.getInt("COLUMN_SIZE"); - ccInfo.decimalDigits = rsCols.getInt("DECIMAL_DIGITS"); - // NOTE: this may need a toUpperCase in some cases, keep an eye on it - ccInfo.isNullable = rsCols.getString("IS_NULLABLE"); - List tableColInfo = colInfo.get(ccInfo.tableName); - if (tableColInfo == null) { - tableColInfo = new ArrayList<>(); - colInfo.put(ccInfo.tableName, tableColInfo); - } - tableColInfo.add(ccInfo); - } - } catch (SQLException sqle) { - String message = "Error getting table fields information... Error was:" + sqle.toString(); - log.error(message, MODULE); - } finally { - JdbcUtils.closeResultSet(rsCols); - } - } - }); - return colInfo; - } - - @SuppressWarnings("unchecked") - //获取索引 - public Map>> getIndexInfo(final Collection tableNames, final boolean include_nounique) { - final Map>> indexInfo = new HashMap<>(); - if (!tableNames.isEmpty()) { - for (TableCheckInfo c : tableNames) { - indexInfo.put(c.tableName, new HashMap<>()); - } - dbEngine.doConn(connection -> { - try { - DatabaseMetaData dbData = connection.getMetaData(); - boolean needsUpperCase = false; - try { - needsUpperCase = dbData.storesLowerCaseIdentifiers() || dbData.storesMixedCaseIdentifiers(); - } catch (SQLException sqle) { - String message = "Error getting identifier case information... Error was:" + sqle.toString(); - log.error(message, MODULE); - } - -// int totalIndices = 0; - String lookupSchemaName = null; - if (dbData.supportsSchemasInTableDefinitions()) { - lookupSchemaName = dbData.getUserName(); - } - - for (TableCheckInfo curTableName : tableNames) { - ResultSet rsCols = null; - try { - // false for unique, we don't really use unique indexes - // true for approximate, don't really care if stats are up-to-date - rsCols = dbData.getIndexInfo(curTableName.catalog, lookupSchemaName, curTableName.tableName, !include_nounique, true); - while (rsCols != null && rsCols.next()) { - // NOTE: The code in this block may look funny, but it is designed so that the wrapping loop can be removed - // skip all index info for statistics - if (rsCols.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic) continue; - //HACK: for now skip all "unique" indexes since our foreign key indices are not unique, but the primary key ones are - //原来的方法: 只取了NON_UNIQUE == true的索引. - //if (!rsCols.getBoolean ("NON_UNIQUE")) continue; - boolean unique = rsCols.getBoolean("NON_UNIQUE"); - - //for (int x = 1; x<=rsCols.getMetaData().getColumnCount();x++){ - // System.out.println(rsCols.getMetaData().getColumnName(x) + " = " + rsCols.getString(x)); - //} - - //System.out.println("INDEX_NAME=" + rsCols.getString("INDEX_NAME") + " --- "+ "COLUMN_NAME=" + rsCols.getString("COLUMN_NAME") ); - - //改动, 可以取所有的索引. - if (include_nounique) { - // 要取nouniqune的 - } else { - // 不取nouniqune的, - if (!unique) continue; - } - String tableName = rsCols.getString("TABLE_NAME"); - if (needsUpperCase && tableName != null) { - tableName = tableName.toUpperCase(); - } - - String indexName = rsCols.getString("INDEX_NAME"); - if (needsUpperCase && indexName != null) { - indexName = indexName.toUpperCase(); - } - Map> tableIndexList = indexInfo.computeIfAbsent(tableName, k -> new HashMap<>()); - Set set = tableIndexList.computeIfAbsent(indexName, k -> new LinkedHashSet<>()); - // totalIndices++; - set.add(rsCols.getString("COLUMN_NAME")); - } - } catch (Exception e) { - log.debug("Error getting index info using lookupSchemaName " + lookupSchemaName, e); - } finally { - JdbcUtils.closeResultSet(rsCols); - } - } - } catch (SQLException e) { - log.error(e.getMessage(), e); - } - return null; - }); - } - return indexInfo; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultEntity.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultEntity.java deleted file mode 100644 index 7583b6b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DefaultEntity.java +++ /dev/null @@ -1,86 +0,0 @@ -package cc.smtweb.framework.core.db.impl; - -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.util.DateUtil; -import org.apache.commons.lang3.StringUtils; - -import java.io.Serializable; - -/** - * Created by Akmm at 14-1-2 上午11:19 - * 实体bean抽象类 - */ -public class DefaultEntity extends BaseBean implements Serializable, Cloneable { - //表名 - private final static String tableNameKey = "_def_table_name"; - private final static String statusKey = "_status"; - - public DefaultEntity() {} - - public DefaultEntity(String _def_table_name) { - this.put(tableNameKey,_def_table_name); - } - - public ModelTable getModelTable() { - return ModelTableCache.getInstance().getByName(getTableName()); - } - - public String getTableName() { - return getStr(tableNameKey); - } - public void setTableName(String tableName) { - put(tableNameKey, tableName); - } - - public void setIsNew(boolean isNew) { - put(statusKey, isNew); - } - - public boolean isNew() { - return getBool(statusKey) || getEntityId() <= 0L; - } - - public void removeStatus() { - data.remove(statusKey); - } - - //根据实体定义,设默认值 - public void init() { - ModelTable entity = getModelTable(); - if (entity == null) return; - String pkField = getPkFieldName(); - for (ModelField field : entity.getFields()) { - if (data.containsKey(field.getName())) continue;//有值了,不能动 - if (field.getName().equalsIgnoreCase(pkField)) continue;//是pk,不要初始化 - if (field.getFieldType() == SwEnum.FieldType.CREATE_TIME.value || field.getFieldType() == SwEnum.FieldType.LAST_TIME.value) { - put(field.getName(), DateUtil.nowDateTimeLong()); - } else { - String s = field.getDefaultValue(); - if (StringUtils.isNotEmpty(s)) put(field.getName(), s); - } - } - } - - /** 主键字段 */ - public String getPkFieldName() { - return getModelTable().getIdField(); - } - - public long getEntityId() { - return getLong(getPkFieldName()); - } - - public void setEntityId(long id) { - data.put(getPkFieldName(), id); - } - - @Override - public DefaultEntity clone() throws CloneNotSupportedException { - DefaultEntity bean = (DefaultEntity) super.clone(); - bean.getData().remove(getPkFieldName()); - return bean; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java deleted file mode 100644 index a912e2c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java +++ /dev/null @@ -1,37 +0,0 @@ -package cc.smtweb.framework.core.db.impl; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Created with IntelliJ IDEA. - * User: AKhh - * Date: 12-12-21 下午10:13 - * To change this template use File | Settings | File Templates. - */ -public interface IDatabaseInfo { - void printDatabaseInfo(); - - Map getTables(); - - Map> getColumnInfo(Map dbTables); - - Map>> getIndexInfo(Collection tableNames, boolean include_nounique); - - class TableCheckInfo { - public String tableName; - public String catalog; - public String pk; - } - - class ColumnCheckInfo { - public String tableName; - public String columnName; - public String typeName; - public int columnSize; - public int decimalDigits; - public String isNullable; // Y|N or "" = ie nobody knows - } -} \ No newline at end of file diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/UtilTime.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/UtilTime.java deleted file mode 100644 index 7863faf..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/UtilTime.java +++ /dev/null @@ -1,158 +0,0 @@ -package cc.smtweb.framework.core.db.impl; - -/** - * Created with IntelliJ IDEA. - * User: AKhh - * Date: 12-12-21 下午10:04 - * To change this template use File | Settings | File Templates. - */ -public class UtilTime { - long realStartTime; - long startTime; - long lastMessageTime; - String lastMessage = null; - boolean log = false; - - /** - * Default constructor. Starts the timer. - */ - public UtilTime() { - lastMessageTime = realStartTime = startTime = System.currentTimeMillis(); - lastMessage = "Begin"; - } - - /** - * Creates a string with information including the passed message, the last passed message and the time since the last call, and the time since the beginning - * - * @param message A message to put into the timer String - * @return A String with the timing information, the timer String - */ - public String timerString(String message) { - return timerString(message, this.getClass().getName()); - } - - /** - * Creates a string with information including the passed message, the last passed message and the time since the last call, and the time since the beginning - * - * @param message A message to put into the timer String - * @param module The debug/log module/thread to use, can be null for root module - * @return A String with the timing information, the timer String - */ - public String timerString(String message, String module) { - // time this call to avoid it interfering with the main timer - long tsStart = System.currentTimeMillis(); - - String retString = "[[" + message + "- total:" + secondsSinceStart() + - ",since last(" + ((lastMessage.length() > 20) ? (lastMessage.substring(0, 17) + "..."): lastMessage) + "):" + - secondsSinceLast() + "]]"; - - lastMessage = message; - if (log) { - System.out.println(retString); - } - // have lastMessageTime come as late as possible to just time what happens between calls - lastMessageTime = System.currentTimeMillis(); - // update startTime to disclude the time this call took - startTime += (lastMessageTime - tsStart); - return retString; - } - - /** - * Returns the number of seconds since the timer started - * - * @return The number of seconds since the timer started - */ - public double secondsSinceStart() { - return ((double) timeSinceStart()) / 1000.0; - } - - /** - * Returns the number of seconds since the last time timerString was called - * - * @return The number of seconds since the last time timerString was called - */ - public double secondsSinceLast() { - return ((double) timeSinceLast()) / 1000.0; - } - - /** - * Returns the number of milliseconds since the timer started - * - * @return The number of milliseconds since the timer started - */ - public long timeSinceStart() { - long currentTime = System.currentTimeMillis(); - - return currentTime - startTime; - } - - /** - * Returns the number of milliseconds since the last time timerString was called - * - * @return The number of milliseconds since the last time timerString was called - */ - public long timeSinceLast() { - long currentTime = System.currentTimeMillis(); - - return currentTime - lastMessageTime; - } - - /** - * Sets the value of the log member, denoting whether log output is off or not - * - * @param log The new value of log - */ - public void setLog(boolean log) { - this.log = log; - } - - /** - * Gets the value of the log member, denoting whether log output is off or not - * - * @return The value of log - */ - public boolean getLog() { - return log; - } - - /** - * Creates a string with information including the passed message, the time since the last call, - * and the time since the beginning. This version allows an integer level to be specified to - * improve readability of the output. - * - * @param level Integer specifying how many levels to indent the timer string so the output can be more easily read through nested method calls. - * @param message A message to put into the timer String - * @return A String with the timing information, the timer String - */ - public String timerString(int level, String message) { - StringBuffer retStringBuf = new StringBuffer(); - for (int i = 0; i < level; i++) { - retStringBuf.append("| "); - } - retStringBuf.append("("); - - String timeSinceStartStr = String.valueOf(timeSinceStart()); - - // int spacecount = 5 - timeSinceStartStr.length(); - // for (int i=0; i < spacecount; i++) { retStringBuf.append(' '); } - retStringBuf.append(timeSinceStartStr + ","); - - String timeSinceLastStr = String.valueOf(timeSinceLast()); - - // spacecount = 4 - timeSinceLastStr.length(); - // for (int i=0; i < spacecount; i++) { retStringBuf.append(' '); } - retStringBuf.append(timeSinceLastStr); - - retStringBuf.append(")"); - int spacecount = 12 + (2 * level) - retStringBuf.length(); - - for (int i = 0; i < spacecount; i++) { - retStringBuf.append(' '); - } - retStringBuf.append(message); - // lastMessageTime = (new Date()).getTime(); - lastMessageTime = System.currentTimeMillis(); - // lastMessage = message; - return retStringBuf.toString(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/AbsDbWorker.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/AbsDbWorker.java deleted file mode 100644 index fb87206..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/AbsDbWorker.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.smtweb.framework.core.db.jdbc; - -/** - * Created by Akmm at 14-2-15 下午1:51 - * 数据库事务操作方法类 - */ -public abstract class AbsDbWorker implements IDbWorker { - @Override - public void doAfterDbCommit() {} - - @Override - public void doAfterDbRollback(){} -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/BaseBeanPropertyRowMapper.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/BaseBeanPropertyRowMapper.java deleted file mode 100644 index 8c4607a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/BaseBeanPropertyRowMapper.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.smtweb.framework.core.db.jdbc; - -import cc.smtweb.framework.core.db.impl.BaseBean; -import org.springframework.beans.BeanUtils; -import org.springframework.jdbc.core.RowMapper; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; - -/** - * ORM映射处理器,实现spring jdbcTemplate的行集映射器 - * @author xkliu - */ -public class BaseBeanPropertyRowMapper implements RowMapper { - private Class mappedClass; - - public BaseBeanPropertyRowMapper(Class mappedClass) { - this.mappedClass = mappedClass; - } - - @Override - public T mapRow(ResultSet resultSet, int i) throws SQLException { - T mappedObject = BeanUtils.instantiateClass(this.mappedClass); - BaseBean map = (BaseBean) mappedObject; - - ResultSetMetaData rsmd = resultSet.getMetaData(); - int columnCount = rsmd.getColumnCount(); - - for(int index = 1; index <= columnCount; ++index) { - Object value = resultSet.getObject(index); - - if (value != null) { - map.put(rsmd.getColumnLabel(index), value); - } - } - - return mappedObject; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/IDbWorker.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/IDbWorker.java deleted file mode 100644 index f24c35a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/IDbWorker.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.smtweb.framework.core.db.jdbc; - -/** - * Created by Akmm at 14-2-3 下午4:52 - * 数据库事务操作方法类 - */ -public interface IDbWorker { - public void work(); - - //数据库提交完后的业务或缓存处理 - public void doAfterDbCommit(); - - //数据库回滚后的业务或缓存处理 - public void doAfterDbRollback(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/IdGenerator.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/IdGenerator.java deleted file mode 100644 index 4be311a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/IdGenerator.java +++ /dev/null @@ -1,134 +0,0 @@ -package cc.smtweb.framework.core.db.jdbc; - -/** - * 主键生成器。 - */ -//public class IdGenerator { -// private AtomicLong key; -// -// public IdGenerator() { -// this(0); -// } -// -// /** -// * -// * @param seed 集群服务id,用于集群产生的数据不重复(0~255) -// */ -// public IdGenerator(int seed) { -// long now = System.currentTimeMillis(); -// -// if(seed > 0xFF){ -// seed = 0xFF; -// } -// -// if(seed <= 0){ -// seed = 1; -// } -// -// key = new AtomicLong(now | (((long) seed) << 48)); -// } -// -// public long nextCode() { -// return key.incrementAndGet(); -// } -//} - -/** - * tweeter的snowflake - * time—42bits,精确到ms,那就意味着其可以表示长达(2^42-1)/(1000360024*365)=139.5年 - * (a) id构成: 42位的时间前缀 + 10位的节点标识 + 12位的sequence避免并发的数字(12位不够用时强制得到新的时间前缀) - * 注意这里进行了小改动: snowkflake是5位的datacenter加5位的机器id; 这里变成使用10位的机器id - * (b) 对系统时间的依赖性非常强,需关闭ntp的时间同步功能。当检测到ntp时间调整后,将会拒绝分配id - * @author xkliu - */ -public class IdGenerator { - /** - * 起始的时间戳 epoch 2017-1-1 - */ - private final static long EPOCH_STMP = 1483200000000L; - - /** - * 每一部分占用的位数 - */ - //序列号占用的位数 - private final static long SEQUENCE_BIT = 12; - //机器标识占用的位数 - private final static long MACHINE_BIT = 10; - - /** - * 每一部分的最大值 - */ - private final static long MAX_MACHINE_NUM = ~(-1L << MACHINE_BIT); - private final static long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT); - - /** - * 每一部分向左的位移 - */ - private final static long MACHINE_LEFT = SEQUENCE_BIT; - private final static long TIMESTMP_LEFT = SEQUENCE_BIT + MACHINE_BIT; - - // private long datacenterId; //数据中心 - // 机器标识 - private long machineIdShift; - // 序列号 - private long sequence = 0L; - // 上一次时间戳 - private long lastStmp = -1L; - - // 0 ~ 1023 - public IdGenerator(long machineId) { - if (machineId > MAX_MACHINE_NUM || machineId < 0) { - throw new IllegalArgumentException("machineId " + machineId + " can't be greater than " + MAX_MACHINE_NUM + " or less than 0"); - } - - this.machineIdShift = machineId << MACHINE_LEFT; - } - - /** - * 产生下一个ID - * - * @return ID值 - */ - public synchronized long nextId() { - long currStmp = getNewStamp(); - if (currStmp < lastStmp) { - throw new RuntimeException("Clock moved backwards. Refusing to generate id"); - } - - if (currStmp == lastStmp) { - //相同毫秒内,序列号自增 - sequence = (sequence + 1) & MAX_SEQUENCE; - //同一毫秒的序列数已经达到最大 - if (sequence == 0L) { - currStmp = getNextMill(); - } - } else { - //不同毫秒内,序列号置为0 - sequence = 0L; - } - - lastStmp = currStmp; - - // 时间戳部分 + 机器标识部分 + 序列号部分 - return (currStmp - EPOCH_STMP) << TIMESTMP_LEFT - | machineIdShift - | sequence; - } - - private long getNextMill() { - long mill = getNewStamp(); - while (mill <= lastStmp) { - mill = getNewStamp(); - } - return mill; - } - - private long getNewStamp() { - return System.currentTimeMillis(); - } - - // 根据ID值反向计算时间戳 - public static long queryTimestamp(long id) { - return (id >>> TIMESTMP_LEFT) + EPOCH_STMP; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java deleted file mode 100644 index ec46520..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcEngine.java +++ /dev/null @@ -1,508 +0,0 @@ -package cc.smtweb.framework.core.db.jdbc; - -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.impl.BaseBean; -import cc.smtweb.framework.core.exception.DbException; -import cc.smtweb.framework.core.util.JsonUtil; -import org.apache.commons.lang3.StringUtils; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.BeanPropertyRowMapper; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.ResultSetExtractor; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Supplier; - -/** - * JDBC访问类,包装了spring jdbcTemplate对象 - */ -public class JdbcEngine { - private final static String DB_TYPE_MYSQL = "mysql"; - - private Map mapThreadTrans = new ConcurrentHashMap<>(); - private JdbcTemplate jdbcTemplate; - private NamedParameterJdbcTemplate namedJdbcTemplate; - private DataSourceTransactionManager dataSourceTransactionManager; - private IdGenerator idGenerator; - - protected String type; - - public JdbcEngine(NamedParameterJdbcTemplate namedJdbcTemplate, IdGenerator idGenerator, String type) { - this.namedJdbcTemplate = namedJdbcTemplate; - this.jdbcTemplate = namedJdbcTemplate.getJdbcTemplate(); - this.dataSourceTransactionManager = new DataSourceTransactionManager(jdbcTemplate.getDataSource()); - this.idGenerator = idGenerator; - this.type = type; - } - - public boolean isMysql() { - return DB_TYPE_MYSQL.equalsIgnoreCase(type); - } - - /** - * 获取数据库唯一id - * - * @return 返回ID值 - */ - public long nextId() { - return this.idGenerator.nextId(); - } - - /** - * 查询单行数据 - * - * @param sql 查询SQL - * @param rowHandler ResultSet处理器 - * @param 返回得对象类型 - * @return 返回单个对象数据 - */ - public T queryEntity(String sql, final ResultSetExtractor rowHandler) { - return jdbcTemplate.query(sql, rowHandler); - } - - /** - * 查询单行数据 - * - * @param sql 查询SQL - * @param rowHandler ResultSet处理器 - * @param params SQL参数 - * @param 返回得对象类型 - * @return 返回单个对象数据 - */ - public T queryEntity(String sql, final ResultSetExtractor rowHandler, Object... params) { - return jdbcTemplate.query(sql, rowHandler, params); - } - - /** - * 通过回调函数查询SQL,返回列表或者对象数据 - */ - public T query(String sql, ResultSetExtractor rse, Object... params) { - return jdbcTemplate.query(sql, rse, params); - } - - /** - * 查询SQL,返回列表数据 - */ - public List query(String sql, RowMapper rowMapper) { - return jdbcTemplate.query(sql, rowMapper); - } - - /** - * 查询SQL,返回列表数据 - */ - public List query(String sql, RowMapper rowMapper, Object... params) { - return jdbcTemplate.query(sql, rowMapper, params); - } - - /** - * 执行更新SQL - */ - public int update(String sql) { - return jdbcTemplate.update(sql); - } - - /** - * 执行更新SQL - */ - public int update(String sql, Object... params) { - return jdbcTemplate.update(sql, params); - } - - /** - * 查询字符list - * - * @param sql 查询SQL - * @param params 查询SQL参数 - * @return 字符list - */ - public List queryStringList(String sql, Object... params) { - return jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getString(1), params); - } - - /** - * 查询字符set - * - * @param sql 查询SQL - * @param params 查询SQL参数 - * @return 字符set - */ - public Set queryStringSet(String sql, Object... params) { - return jdbcTemplate.query(sql, (resultSet) -> { - Set result = new HashSet<>(); - while (resultSet.next()) { - String value = resultSet.getString(1); - if (value != null) { - result.add(value); - } - } - - return result; - }, params); - } - - /** - * 查询字符 - * - * @param sql 查询SQL - * @param params 查询SQL参数 - * @return 字符 - */ - public String queryString(String sql, Object... params) { - List list = jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getString(1), params); - if (list != null && !list.isEmpty()) { - return list.get(0); - } - - return null; - } - - /** - * 查询值为JSON格式,转换为对象返回 - * - * @param sql 查询SQL - * @param clazz 对象类 - * @param params 查询SQL参数 - * @param 对象类型 - * @return JSON格式,转换为对象返回 - */ - public T queryJson(String sql, Class clazz, Object... params) { - List list = jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getString(1), params); - if (list != null && !list.isEmpty()) { - String s = list.get(0); - if (StringUtils.isNotBlank(s)) { - return JsonUtil.parse(s, clazz); - } else { - try { - return clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new DbException(e); - } - } - } - - return null; - } - - /** - * 查询Long对象 - * - * @param sql 查询SQL - * @param params 查询SQL参数 - * @return Long对象 - */ - public Long queryLong(String sql, Object... params) { - List list = jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getLong(1), params); - if (list != null && !list.isEmpty()) { - return list.get(0); - } - - return null; - } - - /** - * 查询List对象 - * - * @param sql 查询SQL - * @param params 查询SQL参数 - * @return List对象 - */ - public List queryLongList(String sql, Object... params) { - return jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getLong(1), params); - } - - /** - * 查询Set对象 - * - * @param sql 查询SQL - * @param params 查询SQL参数 - * @return Set对象 - */ - public Set queryLongSet(String sql, Object... params) { - return jdbcTemplate.query(sql, (resultSet) -> { - Set result = new HashSet<>(); - while (resultSet.next()) { - long value = resultSet.getLong(1); - if (!resultSet.wasNull()) { - result.add(value); - } - } - - return result; - }, params); - } - - /** - * 查询Integer对象 - * - * @param sql 查询SQL - * @param params 查询SQL参数 - * @return Integer对象 - */ - public Integer queryInt(String sql, Object... params) { - List list = jdbcTemplate.query(sql, (resultSet, i) -> resultSet.getInt(1), params); - if (list != null && !list.isEmpty()) { - return list.get(0); - } - - return null; - } - - /** - * 执行批量更新语句 - * - * @param sql SQL语句 - * @param params 数组参数列表 - * @return 执行结果数组 - */ - public int[] batchUpdate(String sql, List params) { - return jdbcTemplate.batchUpdate(sql, params); - } - - /** - * 启动事务,需要用try(DbTrans dbTrans=dbEngine.openTrans())来处理异常后自动回滚事务,如果手工提交事务DbTaans.commit() - * - * @return 事务对象 - */ - public JdbcTrans openTrans() { - return new JdbcTrans(this.dataSourceTransactionManager); - } - - /** - * 在回调函数中执行事务,返回的true就提交事务,否则回滚事务 - * - * @param extractor 回调方法 - * @return 事务是否成功,如果异常会也会事务回滚后再抛出异常 - */ - public boolean doTrans(Supplier extractor) { - try (JdbcTrans jdbcTrans = openTrans()) { - boolean result = extractor.get(); - if (result) { - jdbcTrans.commit(); - return true; - } - } - - return false; - } - - public void beginTrans() { - Thread t = Thread.currentThread(); - JdbcTrans jdbcTrans = mapThreadTrans.get(t); - if (jdbcTrans != null) { - jdbcTrans.inc(); - return; - } - mapThreadTrans.put(t, openTrans()); - } - - public void commit() throws SwException { - Thread t = Thread.currentThread(); - JdbcTrans tm = this.mapThreadTrans.get(t); - if (tm == null) throw new SwException("当前没有开启事务。"); - if (tm.canCommit()) { - tm.doEnd("commit"); - tm.commit(); - this.mapThreadTrans.remove(t); - } - } - - public void recTransLog() { - for (JdbcTrans tm: mapThreadTrans.values()) { - tm.doEnd("process"); - } - } - - public void rollback(Exception e) throws SwException { - Thread t = Thread.currentThread(); - JdbcTrans tm = mapThreadTrans.get(t); - if (tm == null) throw new SwException("当前没有开启事务。"); - if (tm.canCommit()) { - tm.doEnd("rollback"); - mapThreadTrans.remove(t); - tm.rollback(); - } - if (e != null) throw new SwException(e); - } - - public void doTrans(IDbWorker dbWorker) throws SwException { - beginTrans(); - try { - dbWorker.work(); - commit(); - } catch (Exception e) { - rollback(e); - dbWorker.doAfterDbRollback(); - throw new SwException(e); - } - dbWorker.doAfterDbCommit(); - } - - //独立事务 - public void doTransSingle(IDbWorker worker) throws Exception { - JdbcTrans jdbcTrans = openTrans(); - try { - worker.work(); - jdbcTrans.commit(); - } catch (Exception e) { - jdbcTrans.rollback(); - worker.doAfterDbRollback(); - throw e; - } - worker.doAfterDbCommit(); - } - - - /** - * 获取原始数据库连接执行命令 - * - * @return 数据库连接 - */ - public T doConn(Function extractor) { - DataSource ds = Objects.requireNonNull(this.jdbcTemplate.getDataSource()); - - try (Connection conn = ds.getConnection()) { - return extractor.apply(conn); - } catch (SQLException e) { - throw new DbException(e); - } - } - - /** - * 查询单行数据,返回bean - */ - public T queryEntity(String sql, Class type) { - List list = jdbcTemplate.query(sql, createRowMapper(type)); - - if (list != null && !list.isEmpty()) { - return list.get(0); - } - - return null; - } - - /** - * 查询单行数据,返回bean - */ - public T queryEntity(String sql, Class type, Object... params) { - List list = query(sql, createRowMapper(type), params); - - if (list != null && !list.isEmpty()) { - return list.get(0); - } - - return null; - } - - /** - * 通过回调函数查询SQL,返回列表或者对象数据 - */ - public T query(String sql, ResultSetExtractor rse) { - return jdbcTemplate.query(sql, rse); - } - - /** - * 查询SQL,返回列表数据 - */ - public List query(String sql, Class type) { - return jdbcTemplate.query(sql, createRowMapper(type)); - } - - /** - * 查询SQL,返回列表数据 - */ - public List query(String sql, Class type, Object... params) { - return jdbcTemplate.query(sql, createRowMapper(type), params); - } - - - /*================以下为具名参数方法================================================*/ - public int queryIntN(String sql, Map params) { - List list = namedJdbcTemplate.query(sql, params, (resultSet, i) -> resultSet.getInt(1)); - if (list != null && !list.isEmpty()) { - return list.get(0); - } - - return 0; - } - - public T queryEntityN(String sql, Map params, Class type) { - List list = queryN(sql, params, type); - - if (list != null && !list.isEmpty()) { - if (list.size() > 1) throw new SwException("您调用的查询单个对象的方法,结果却查出了多条!"); - return list.get(0); - } - - return null; - } - - public List queryN(String sql, Map params, Class type) { - return namedJdbcTemplate.query(sql, params, createRowMapper(type)); - } - - /** - * 执行更新SQL - */ - public int updateN(String sql, Map params) { - return namedJdbcTemplate.update(sql, params); - } - - public int[] batchUpdateN(String sql, List> params) { - return namedJdbcTemplate.batchUpdate(sql, (Map[])params.toArray()); - } - - /** - * 翻页查询 - */ - public List pagedQueryN(String sql, Class type, int start, int limit, Map params) { - return queryN(sql + " LIMIT " + start + "," + limit, params, type); - } - /*=================以上为具名参数方法==================================================*/ - public boolean isExists(String sql, Object... params) { - try { - Object v = jdbcTemplate.queryForObject(sql + " LIMIT 0, 1", Object.class, params); - return (v != null); - } catch (EmptyResultDataAccessException e) { - return false; - } - } - - private RowMapper createRowMapper(Class type) { - RowMapper rowMapper; - if (BaseBean.class.isAssignableFrom(type)) { - rowMapper = new BaseBeanPropertyRowMapper<>(type); - } else if (java.util.Map.class.isAssignableFrom(type)) { - if (SwMap.class.equals(type)) { - rowMapper = new SwMapPropertyRowMapper<>(type); - } else { - rowMapper = new MapPropertyRowMapper<>(type); - } - } else { - rowMapper = new BeanPropertyRowMapper<>(type); - } - return rowMapper; - } - - /** - * 翻页查询 - */ - public List pagedQuery(String sql, Class type, int start, int limit, Object... params) { - return jdbcTemplate.query(sql + " LIMIT " + start + "," + limit, createRowMapper(type), params); - } - - /** - * 翻页查询 - */ - public List pagedQuery(String sql, RowMapper rowMapper, int start, int limit, Object... params) { - return jdbcTemplate.query(sql + " LIMIT " + start + "," + limit, rowMapper, params); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcTrans.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcTrans.java deleted file mode 100644 index 31a6c33..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/JdbcTrans.java +++ /dev/null @@ -1,87 +0,0 @@ -package cc.smtweb.framework.core.db.jdbc; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.DefaultTransactionDefinition; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * JDBC事务处理类,可以在try中使用自动结束事务 - * - * @author xkliu - */ -public class JdbcTrans implements AutoCloseable { - - private Logger logger = LoggerFactory.getLogger("trans"); - protected long time = System.currentTimeMillis(); - protected String info = Thread.currentThread().getStackTrace()[6].getFileName() + "::::" + Thread.currentThread().getStackTrace()[6].getLineNumber(); - private AtomicInteger count = new AtomicInteger(1); - - public int getCount() { - return count.get(); - } - - public void inc() { - count.incrementAndGet(); - } - - public boolean canCommit() { - return count.decrementAndGet() == 0; - } - - public void doEnd(String ei) { - long t = System.currentTimeMillis() - time; - if (t > 10000L) { - logger.info(info + "::::::" + t + "::::::" + ei); - } - } - - private DataSourceTransactionManager transactionManager; - private TransactionStatus status; - - /** - * 构造事务执行 - * - * @param transactionManager spring事务管理对象 - */ - public JdbcTrans(DataSourceTransactionManager transactionManager) { - this.transactionManager = transactionManager; - // 事务定义类 - DefaultTransactionDefinition def = new DefaultTransactionDefinition(); - def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - // 返回事务对象 - this.status = transactionManager.getTransaction(def); - } - - /** - * 回滚事务 - */ - public void rollback() { - if (status != null) { - transactionManager.rollback(status); - status = null; - } - } - - /** - * 提交事务 - */ - public void commit() { - if (status != null) { - transactionManager.commit(status); - status = null; - } - } - - /** - * 实现自动关闭,回滚方式结束事务 - */ - @Override - public void close() { - this.rollback(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/MapPropertyRowMapper.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/MapPropertyRowMapper.java deleted file mode 100644 index c8ebc51..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/MapPropertyRowMapper.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.smtweb.framework.core.db.jdbc; - -import org.springframework.beans.BeanUtils; -import org.springframework.jdbc.core.RowMapper; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; - -/** - * ORM映射处理器,实现spring jdbcTemplate的行集映射器 - * @author xkliu - */ -public class MapPropertyRowMapper implements RowMapper { - private Class mappedClass; - - public MapPropertyRowMapper(Class mappedClass) { - this.mappedClass = mappedClass; - } - - @Override - public T mapRow(ResultSet resultSet, int i) throws SQLException { - T mappedObject = BeanUtils.instantiateClass(this.mappedClass); - java.util.Map map = (java.util.Map)mappedObject; - - ResultSetMetaData rsmd = resultSet.getMetaData(); - int columnCount = rsmd.getColumnCount(); - - for(int index = 1; index <= columnCount; ++index) { - Object value = resultSet.getObject(index); - - if (value != null) { - map.put(rsmd.getColumnLabel(index), value); - } - } - - return mappedObject; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/SwMapPropertyRowMapper.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/SwMapPropertyRowMapper.java deleted file mode 100644 index a5aad19..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/jdbc/SwMapPropertyRowMapper.java +++ /dev/null @@ -1,59 +0,0 @@ -package cc.smtweb.framework.core.db.jdbc; - -import cc.smtweb.framework.core.common.SwMap; -import org.springframework.jdbc.core.RowMapper; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; - -/** - * ORM映射处理器,实现spring jdbcTemplate的行集映射器,对下划线进行小驼峰命名转化 - * @author xkliu - */ -public class SwMapPropertyRowMapper implements RowMapper { - public SwMapPropertyRowMapper(Class mappedClass) { - } - - @Override - public T mapRow(ResultSet resultSet, int i) throws SQLException { - SwMap map = new SwMap(); - - ResultSetMetaData rsmd = resultSet.getMetaData(); - int columnCount = rsmd.getColumnCount(); - - for(int index = 1; index <= columnCount; ++index) { - Object value = resultSet.getObject(index); - - if (value != null) { - String columnLabel = rsmd.getColumnLabel(index); - map.put(columnLabel, value); //toCamelCase(columnLabel) - } - } - - return (T)map; - } - - private String toCamelCase(String columnLabel) { - int len = columnLabel.length(); - StringBuilder sb = new StringBuilder(len); - int lowCase = 1; - for (int i = 0; i < len; i++) { - char ch = columnLabel.charAt(i); - if (ch == '_') { - lowCase = 2; - } else { - if (lowCase == 1) { - ch = Character.toLowerCase(ch); - lowCase = 0; - } else if (lowCase == 2) { - ch = Character.toUpperCase(ch); - lowCase = 0; - } - sb.append(ch); - } - } - - return sb.toString(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractSelectSqlBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractSelectSqlBuilder.java deleted file mode 100644 index 9006790..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractSelectSqlBuilder.java +++ /dev/null @@ -1,129 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.jdbc.JdbcEngine; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; - -public class AbstractSelectSqlBuilder extends SqlBuilder { - private List orderBy; - - protected void makeFields(StringBuilder sb) { - } - - protected Object[] makeParams(StringBuilder sb) { - makeFields(sb); - - if (wheres != null) { - List params = new ArrayList<>(wheres.size()); - - if (wheres.size() > 0) { - String logicOp = " AND "; - boolean addLoginOp = false; - - for (int i = 0; i < wheres.size(); i++) { - SqlWhereValue whereValue = wheres.get(i); - - if (i == 0) { - sb.append(" WHERE "); - } - - if (whereValue.getName() == null) { - Object value = whereValue.getValue(); - - if ("(".equals(value)) { - if (i > 0) { - sb.append(logicOp); - } - addLoginOp = false; - } - - sb.append(value); - logicOp = whereValue.getOp(); - } else { - if (addLoginOp) { - sb.append(logicOp); - } else { - addLoginOp = true; - } - - sb.append(whereValue.getName()).append(whereValue.getOp()).append('?'); - params.add(whereValue.getValue()); - } - } - } - - if (orderBy != null) { - for (int i = 0; i < orderBy.size(); i++) { - if (i == 0) { - sb.append(" ORDER BY "); - } else { - sb.append(","); - } - - sb.append(orderBy.get(i)); - } - } - - return params.toArray(new Object[params.size()]); - } - - return null; - } - - @Override - public AbstractSelectSqlBuilder addOrderBy(String orderByField) { - if (this.orderBy == null) { - this.orderBy = new ArrayList<>(); - } - - this.orderBy.add(orderByField); - - return this; - } - - public List query(DbEngine dbEngine, Class clazz) { - return exec((sql, params) -> dbEngine.query(sql, clazz, params)); - } - - public T queryEntity(DbEngine dbEngine, Class clazz) { - return exec((sql, params) -> dbEngine.queryEntity(sql, clazz, params)); - -// StringBuilder sb = new StringBuilder("select "); -// -// Object[] params = makeParams(sb); -// -// return dbEngine.queryEntity(sb.toString(), clazz, params); - } - - public T exec(BiFunction execute) { - StringBuilder sb = new StringBuilder("select "); - - Object[] params = makeParams(sb); - - return execute.apply(sb.toString(), params); - } - - public List pagedQuery(DbEngine dbEngine, Class clazz, int start, int limit) { - return exec((sql, params) -> dbEngine.pagedQuery(sql, clazz, start, limit, params)); -// StringBuilder sb = new StringBuilder("select "); -// -// Object[] params = makeParams(sb); -// -// return dbEngine.pagedQuery(sb.toString(), clazz, start, limit, params); - } - - public int queryInt(JdbcEngine dbEngine) { - return exec(dbEngine::queryInt); - } - - public SqlJoinTable addJoinTable(String dbName, String tableName, String tableAlias) { - return null; - } - - public SqlJoinTable findJoinTable(String dbName, String tableName) { - return null; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractUpdateSqlBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractUpdateSqlBuilder.java deleted file mode 100644 index ebb4e53..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/AbstractUpdateSqlBuilder.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import cc.smtweb.framework.core.db.jdbc.JdbcEngine; - -public abstract class AbstractUpdateSqlBuilder extends SqlBuilder { - // 无效的更新值,用以占位表示不组装值到params对象里面 - public static final Object VALUE_INVALID = new SqlFieldValue("", ""); - - public boolean isEmpty() { - return fields.isEmpty(); - } - - public abstract int update(JdbcEngine dbEngine); - - public void updateMap(java.util.Map map) { - for (SqlFieldValue field: fields) { - map.put(field.getName(), field.getValue()); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/DeleteSqlBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/DeleteSqlBuilder.java deleted file mode 100644 index 4fdcc78..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/DeleteSqlBuilder.java +++ /dev/null @@ -1,33 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import cc.smtweb.framework.core.db.jdbc.JdbcEngine; - -public class DeleteSqlBuilder extends AbstractUpdateSqlBuilder { - private String tableName; - - DeleteSqlBuilder(String tableName) { - this.tableName = tableName; - } - - @Override - public int update(JdbcEngine dbEngine) { - int fieldSize = wheres.size(); - Object[] params = new Object[fieldSize]; - - StringBuilder sb = new StringBuilder("delete from "); - - sb.append(tableName).append(" where "); - - int index = 0; - for (SqlWhereValue whereValue: wheres) { - if (index > 0){ - sb.append(" and "); - } - sb.append(whereValue.getName()).append("=?"); - params[index] = whereValue.getValue(); - index++; - } - - return dbEngine.update(sb.toString(), params); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/DirectSelectSqlBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/DirectSelectSqlBuilder.java deleted file mode 100644 index 6986db6..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/DirectSelectSqlBuilder.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import java.util.function.BiFunction; - -public class DirectSelectSqlBuilder extends AbstractSelectSqlBuilder { - private String sql; - - DirectSelectSqlBuilder(String sql) { - this.sql = sql; - } - - @Override - public T exec(BiFunction execute) { - StringBuilder sb = new StringBuilder(sql); - - Object[] params = makeParams(sb); - - return execute.apply(sb.toString(), params); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/InsertSqlBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/InsertSqlBuilder.java deleted file mode 100644 index dfc1e3c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/InsertSqlBuilder.java +++ /dev/null @@ -1,38 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import cc.smtweb.framework.core.db.jdbc.JdbcEngine; - -public class InsertSqlBuilder extends AbstractUpdateSqlBuilder { - private String tableName; - - InsertSqlBuilder(String tableName) { - this.tableName = tableName; - } - - @Override - public int update(JdbcEngine dbEngine) { - int fieldSize = fields.size(); - Object[] params = new Object[fieldSize]; - - StringBuilder sb = new StringBuilder("insert into "); - sb.append(tableName).append('('); - - for (int i = 0; i < fieldSize; i++) { - SqlFieldValue field = fields.get(i); - sb.append(field.getName()).append(','); - params[i] = field.getValue(); - } - - sb.setCharAt(sb.length() - 1, ')'); - - sb.append(" values("); - - for (int i = 0; i < fieldSize; i++) { - sb.append("?,"); - } - - sb.setCharAt(sb.length() - 1, ')'); - - return dbEngine.update(sb.toString(), params); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SelectSqlBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SelectSqlBuilder.java deleted file mode 100644 index 2a83149..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SelectSqlBuilder.java +++ /dev/null @@ -1,95 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; - -public class SelectSqlBuilder extends AbstractSelectSqlBuilder { - private String tableName; - private List joinTables; - - SelectSqlBuilder(String tableName) { - this.tableName = tableName; - } - -// @Override -// public List query(DbEngine dbEngine, Class clazz) { -// StringBuilder sb = new StringBuilder("select "); -// -// Object[] params = makeParams(sb); -// -// if (params != null) { -// return dbEngine.query(sb.toString(), clazz, params); -// } else { -// return dbEngine.query(sb.toString(), clazz); -// } -// } - - @Override - protected void makeFields(StringBuilder sb) { - for (SqlFieldValue field: fields) { - sb.append(field.getName()).append(","); - } - - sb.setCharAt(sb.length() - 1, ' '); - sb.append("FROM ").append(tableName); - - if (joinTables != null) { - for (SqlJoinTable joinTable: joinTables) { - sb.append(joinTable.joinSql()).append(joinTable.getDbName()).append('.').append(joinTable.getTableName()) - .append(' ').append(joinTable.getTableAlias()).append(" ON("); - - boolean first = true; - for (SqlJoinField joinField: joinTable.getFields()) { - if (first) { - first = false; - } else { - sb.append(" AND "); - } - - sb.append(joinField.getKeyField()).append("=").append(joinField.getValueField()); - } - - sb.append(')'); - } - } - } - - @Override - public T exec(BiFunction execute) { - StringBuilder sb = new StringBuilder("select "); - - Object[] params = makeParams(sb); - - return execute.apply(sb.toString(), params); - } - - @Override - public SqlJoinTable addJoinTable(String dbName, String tableName, String tableAlias) { - if (joinTables == null) { - joinTables = new ArrayList<>(); - } - - SqlJoinTable joinTable = new SqlJoinTable(); - joinTable.setDbName(dbName); - joinTable.setTableName(tableName); - joinTable.setTableAlias(tableAlias); - - joinTables.add(joinTable); - - return joinTable; - } - - @Override - public SqlJoinTable findJoinTable(String dbName, String tableName) { - if (joinTables != null) { - for (SqlJoinTable table: joinTables) { - if (dbName.equals(table.getDbName()) && tableName.equals(table.getTableName())) { - return table; - } - } - } - - return null; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlBuilder.java deleted file mode 100644 index c4ef731..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlBuilder.java +++ /dev/null @@ -1,84 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import java.util.ArrayList; -import java.util.List; - -/** - * SQL语句建造器 - * @author admin - * @param 建造器类型 - */ -public abstract class SqlBuilder { - protected List fields = new ArrayList<>(); - protected List wheres; - - SqlBuilder() { - } - - public static InsertSqlBuilder createInsert(String tableName) { - return new InsertSqlBuilder(tableName); - } - public static UpdateSqlBuilder createUpdate(String tableName) { - return new UpdateSqlBuilder(tableName); - } - public static SelectSqlBuilder createSelect(String tableName) { - return new SelectSqlBuilder(tableName); - } - public static DeleteSqlBuilder createDelete(String tableName) { - return new DeleteSqlBuilder(tableName); - } - - public static InsertSqlBuilder createInsert(String dbName, String tableName) { - return new InsertSqlBuilder(dbName + "." + tableName); - } - - public static UpdateSqlBuilder createUpdate(String dbName, String tableName) { - return new UpdateSqlBuilder(dbName + "." + tableName); - } - - public static AbstractSelectSqlBuilder createSelect(String dbName, String tableName) { - return new SelectSqlBuilder(dbName + "." + tableName); - } - - public static AbstractSelectSqlBuilder createDirectSelect(String sql) { - return new DirectSelectSqlBuilder(sql); - } - - public static DeleteSqlBuilder createDelete(String dbName, String tableName) { - return new DeleteSqlBuilder(dbName + "." + tableName); - } - - public T add(String fieldName) { - fields.add(new SqlFieldValue(fieldName, null)); - return (T)this; - } - - public T add(String fieldName, Object fieldValue) { - fields.add(new SqlFieldValue(fieldName, fieldValue)); - return (T)this; - } - - public T addWhere(String fieldName, Object fieldValue, String op) { - if (wheres == null) { - wheres = new ArrayList<>(); - } - wheres.add(new SqlWhereValue(fieldName, fieldValue, op)); - return (T)this; - } - - public T addWhere(String fieldName, Object fieldValue) { - return addWhere(fieldName, fieldValue, "="); - } - - public T addWhereOrBegin() { - return addWhere(null, "(", " or "); - } - - public T addWhereOrEnd() { - return addWhere(null, ")", " and "); - } - - public T addOrderBy(String orderBy) { - return (T)this; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlFieldValue.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlFieldValue.java deleted file mode 100644 index 50ee584..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlFieldValue.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import lombok.Getter; - -@Getter -class SqlFieldValue { - private final String name; - private final Object value; - - public SqlFieldValue(String name, Object value) { - this.name = name; - this.value = value; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinField.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinField.java deleted file mode 100644 index e9ecfce..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinField.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import lombok.Getter; - -@Getter -public class SqlJoinField { - private String keyField; - private String valueField; - - public SqlJoinField(String keyField, String valueField) { - this.keyField = keyField; - this.valueField = valueField; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinTable.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinTable.java deleted file mode 100644 index a5bc154..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlJoinTable.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import lombok.Data; - -import java.util.ArrayList; -import java.util.List; - -/** - * SelectSqlBuilder使用的查询关联表 - * @author xkliu - */ -@Data -public class SqlJoinTable { - public static final int LEFT_JOIN = 1; - public static final int RIGHT_JOIN = 2; - public static final int INNER_JOIN = 3; - public static final int FULL_JOIN = 4; - - private int joinType = LEFT_JOIN; - private String dbName; - private String tableName; - private String tableAlias; - - private List fields = new ArrayList<>(); - - public void add(String keyField, String valueField) { - fields.add(new SqlJoinField(keyField, valueField)); - } - - public String joinSql() { - switch (joinType) { - default: - case LEFT_JOIN: return " LEFT JOIN "; - case RIGHT_JOIN: return " RIGHT JOIN "; - case INNER_JOIN: return " INNER JOIN "; - case FULL_JOIN: return " FULL JOIN "; - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlWhereValue.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlWhereValue.java deleted file mode 100644 index d3a9360..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/SqlWhereValue.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import lombok.Getter; - -class SqlWhereValue extends SqlFieldValue { - @Getter - private String op; - - public SqlWhereValue(String name, Object value, String op) { - super(name, value); - this.op = op; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/UpdateSqlBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/UpdateSqlBuilder.java deleted file mode 100644 index e7c638a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/sqlbuilder/UpdateSqlBuilder.java +++ /dev/null @@ -1,55 +0,0 @@ -package cc.smtweb.framework.core.db.sqlbuilder; - -import cc.smtweb.framework.core.db.jdbc.JdbcEngine; - -import java.util.ArrayList; -import java.util.List; - -public class UpdateSqlBuilder extends AbstractUpdateSqlBuilder { - private String tableName; - - UpdateSqlBuilder(String tableName) { - this.tableName = tableName; - } - - @Override - public int update(JdbcEngine dbEngine) { - int fieldSize = fields.size() + wheres.size(); - List params = new ArrayList<>(fieldSize); -// Object[] params = new Object[fieldSize]; - - StringBuilder sb = new StringBuilder("update "); - - sb.append(tableName).append(" set "); - -// int index = 0; - for (SqlFieldValue field: fields) { - if (field.getValue() == VALUE_INVALID) { - sb.append(field.getName()); - } else { - sb.append(field.getName()).append("=?,"); - params.add(field.getValue()); - } -// params[index] = field.getValue(); -// index++; - } - - sb.setCharAt(sb.length() - 1, ' '); - sb.append("where "); - - boolean first = true; - for (SqlWhereValue whereValue: wheres) { - if (first) { - first = false; - } else { - sb.append(" and "); - } - sb.append(whereValue.getName()).append("=?"); - params.add(whereValue.getValue()); -// params[index] -// index++; - } - - return dbEngine.update(sb.toString(), params.toArray()); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelCache.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelCache.java deleted file mode 100644 index edd4d1b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelCache.java +++ /dev/null @@ -1,28 +0,0 @@ -package cc.smtweb.framework.core.db.vo; - -import lombok.Data; - -/** - * 表缓存信息定义:{"name":"tn","title":"按表名","fields":"table_name","type":"M"} - * Created by Akmm at 2022/2/21 16:22 - */ -@Data -public class ModelCache { - //按map缓存 - public static String CACHE_TYPE_MAP = "M"; - //按list缓存 - public static String CACHE_TYPE_LIST = "L"; - - //缓存名,根据此名称去获取缓存信息 getByKey的参数 - private String name; - //缓存中文名,给人看的 - private String title; - //字段,多个字段,键值以下划线分隔 - private String fields; - //缓存类别:list/map - private String type; - - public boolean isMapType() { - return CACHE_TYPE_MAP.equalsIgnoreCase(type); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelCatalog.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelCatalog.java deleted file mode 100644 index b46e984..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelCatalog.java +++ /dev/null @@ -1,96 +0,0 @@ -package cc.smtweb.framework.core.db.vo; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/3/1 15:35 - */ -@SwTable("ASP_MODEL_CATALOG") -public class ModelCatalog extends DefaultEntity { - public static final String ENTITY_NAME = "ASP_MODEL_CATALOG"; - - public ModelCatalog() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("mc_id"); - } - - public void setId(long mcId) { - put("mc_id", mcId); - } - - public long getParentId() { - return getLong("mc_parent_id"); - } - - public void setParentId(long mcParentId) { - put("mc_parent_id", mcParentId); - } - - public String getLevelCode() { - return getStr("mc_level_code"); - } - - public void setLevelCode(String mcLevelCode) { - put("mc_level_code", mcLevelCode); - } - - public String getCode() { - return getStr("mc_code"); - } - - public void setCode(String mcCode) { - put("mc_code", mcCode); - } - - public String getName() { - return getStr("mc_name"); - } - - public void setName(String mcName) { - put("mc_name", mcName); - } - - public long getPrjId() { - return getLong("mc_prj_id"); - } - - public void setPrjId(long mcPrjId) { - put("mc_prj_id", mcPrjId); - } - - public long getCreateUid() { - return getLong("mc_create_uid"); - } - - public void setCreateUid(long mcCreateUid) { - put("mc_create_uid", mcCreateUid); - } - - public long getUpdateUid() { - return getLong("mc_update_uid"); - } - - public void setUpdateUid(long mcUpdateUid) { - put("mc_update_uid", mcUpdateUid); - } - - public long getCreateAt() { - return getLong("mc_create_at"); - } - - public void setCreateAt(long mcCreateAt) { - put("mc_create_at", mcCreateAt); - } - - public long getUpdateAt() { - return getLong("mc_update_at"); - } - - public void setUpdateAt(long mcUpdateAt) { - put("mc_update_at", mcUpdateAt); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelDatabase.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelDatabase.java deleted file mode 100644 index 112588d..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelDatabase.java +++ /dev/null @@ -1,95 +0,0 @@ -package cc.smtweb.framework.core.db.vo; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import lombok.Data; - -@Data -@SwTable(value = "ASP_MODEL_DATABASE") -public class ModelDatabase extends DefaultEntity { - public final static String ENTITY_NAME = "ASP_MODEL_DATABASE"; - - public ModelDatabase() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("db_id"); - } - - public void setId(long dbId) { - put("db_id", dbId); - } - - public long getPrjId() { - return getLong("db_prj_id"); - } - - public void setPrjId(long dbPrjId) { - put("db_prj_id", dbPrjId); - } - - public String getName() { - return getStr("db_name"); - } - - public void setName(String dbName) { - put("db_name", dbName); - } - - public String getTitle() { - return getStr("db_title"); - } - - public void setTitle(String dbTitle) { - put("db_title", dbTitle); - } - - public int getStatus() { - return getInt("db_status"); - } - - public void setStatus(int dbStatus) { - put("db_status", dbStatus); - } - - public int getVersion() { - return getInt("db_version"); - } - - public void setVersion(int dbVersion) { - put("db_version", dbVersion); - } - - public long getCreateUid() { - return getLong("db_create_uid"); - } - - public void setCreateUid(long dbCreateUid) { - put("db_create_uid", dbCreateUid); - } - - public long getUpdateUid() { - return getLong("db_update_uid"); - } - - public void setUpdateUid(long dbUpdateUid) { - put("db_update_uid", dbUpdateUid); - } - - public long getCreateAt() { - return getLong("db_create_at"); - } - - public void setCreateAt(long dbCreateAt) { - put("db_create_at", dbCreateAt); - } - - public long getUpdateAt() { - return getLong("db_update_at"); - } - - public void setUpdateAt(long dbUpdateAt) { - put("db_update_at", dbUpdateAt); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelField.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelField.java deleted file mode 100644 index 0263245..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelField.java +++ /dev/null @@ -1,41 +0,0 @@ -package cc.smtweb.framework.core.db.vo; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Data; - -/** - * 字段定义 - * {name:"字段名,如id",fieldType:"字段类型,如编码字段", dataType:"数据类型,如ID/CODE/NAME等", null:"0-空/1-非空", default: "默认值", title:"中文名",link:"外键关联表",editor:"控件类型:TEXT/TextArea/NUMBER/COMBO"} - */ -@Data -public class ModelField { - private String name; - private String title; - private String remark; - //字段类型,如编码字段,参见FieldTypeDef - private int fieldType; - /** - * 数据类型,参见DataType - */ - private String dataType; - /** - * '禁止为空' - */ - @JsonProperty("null") - private int notNull; - /** - * '默认值' - */ - @JsonProperty("default") - private String defaultValue; - //外键关联表 - private long link; - //控件类型:TEXT/TextArea/NUMBER/COMBO - private String editor; - @JsonIgnore - public boolean isNotNull() { - return notNull == 1; - } - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelIndex.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelIndex.java deleted file mode 100644 index 534b04c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelIndex.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.framework.core.db.vo; - -import lombok.Data; -import org.apache.commons.codec.digest.DigestUtils; - -/** - * 索引定义 {name:"索引名称,如idx_t1", fields:"字段,如f1,f2", type="索引类别:P-主键 I-一般索引 U-唯一索引"} - */ -@Data -public class ModelIndex { - public static final String TYPE_PRIMARY = "P"; - public static final String TYPE_INDEX = "I"; - public static final String TYPE_UNIQUE = "U"; - - private String type; - private String fields; - - public boolean isUnique() { - return TYPE_UNIQUE.equals(type); - } - - public String getName() { - return DigestUtils.md5Hex(fields).substring(0, 16); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelLinkName.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelLinkName.java deleted file mode 100644 index f55d0d9..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelLinkName.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.framework.core.db.vo; - -import lombok.Data; - -/** - * Created by Akmm at 2022/3/15 10:19 - * 表关联信息,关联表名称字段信息 - */ -@Data -public class ModelLinkName { - private String fieldName; - private ModelTable linkTable; - private String linkNameField; - - public ModelLinkName(String fieldName, ModelTable linkTable, String linkNameField) { - this.fieldName = fieldName; - this.linkTable = linkTable; - this.linkNameField = linkNameField; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelProject.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelProject.java deleted file mode 100644 index 33925e8..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelProject.java +++ /dev/null @@ -1,96 +0,0 @@ -package cc.smtweb.framework.core.db.vo; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/3/1 15:35 - */ -@SwTable("ASP_MODEL_PROJECT") -public class ModelProject extends DefaultEntity { - public static final String ENTITY_NAME = "ASP_MODEL_PROJECT"; - - public ModelProject() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("prj_id"); - } - - public void setId(long prjId) { - put("prj_id", prjId); - } - - public String getName() { - return getStr("prj_name"); - } - - public void setName(String prjName) { - put("prj_name", prjName); - } - - public String getModule() { - return getStr("prj_module"); - } - - public void setModule(String prj_module) { - put("prj_module", prj_module); - } - - public String getDepends() { - return getStr("prj_depends"); - } - - public void setDepends(String prjDepends) { - put("prj_depends", prjDepends); - } - - public String getDesc() { - return getStr("prj_desc"); - } - - public void setDesc(String prjDesc) { - put("prj_desc", prjDesc); - } - - public int getStatus() { - return getInt("prj_status"); - } - - public void setStatus(int prjStatus) { - put("prj_status", prjStatus); - } - - public long getCreateUid() { - return getLong("prj_create_uid"); - } - - public void setCreateUid(long prjCreateUid) { - put("prj_create_uid", prjCreateUid); - } - - public long getUpdateUid() { - return getLong("prj_update_uid"); - } - - public void setUpdateUid(long prjUpdateUid) { - put("prj_update_uid", prjUpdateUid); - } - - public long getCreateAt() { - return getLong("prj_create_at"); - } - - public void setCreateAt(long prjCreateAt) { - put("prj_create_at", prjCreateAt); - } - - public long getUpdateAt() { - return getLong("prj_update_at"); - } - - public void setUpdateAt(long prjUpdateAt) { - put("prj_update_at", prjUpdateAt); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelTable.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelTable.java deleted file mode 100644 index 8ffeea1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelTable.java +++ /dev/null @@ -1,282 +0,0 @@ -package cc.smtweb.framework.core.db.vo; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.cache.ModelDatabaseCache; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.util.JsonUtil; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; - -@SwTable(value = "ASP_MODEL_TABLE") -public class ModelTable extends DefaultEntity { - public final static String ENTITY_NAME = "ASP_MODEL_TABLE"; - - /*冗余*/ - private String idField; - - private List fields = new ArrayList<>(); - private List indexes = new ArrayList<>(); - private List caches = new ArrayList<>(); - - public ModelTable() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("tb_id"); - } - - public void setId(long tbId) { - put("tb_id", tbId); - } - - public long getPrjId() { - return getLong("tb_prj_id"); - } - - public void setPrjId(long tbPrjId) { - put("tb_prj_id", tbPrjId); - } - - public long getMcId() { - return getLong("tb_mc_id"); - } - - public void setMcId(long tbMcId) { - put("tb_mc_id", tbMcId); - } - - public long getDbId() { - return getLong("tb_db_id"); - } - - public void setDbId(long tbDbId) { - put("tb_db_id", tbDbId); - } - - public String getExtends() { - return getStr("tb_extends"); - } - - public void setExtends(String tbExtends) { - put("tb_extends", tbExtends); - } - - public String getName() { - return getStr("tb_name"); - } - - public void setName(String tbName) { - put("tb_name", tbName); - } - - public String getTitle() { - return getStr("tb_title"); - } - - public void setTitle(String tbTitle) { - put("tb_title", tbTitle); - } - - public String getAbbr() { - return getStr("tb_abbr"); - } - - public void setAbbr(String tbAbbr) { - put("tb_abbr", tbAbbr); - } - - public int getType() { - return getInt("tb_type"); - } - - public void setType(int tbType) { - put("tb_type", tbType); - } - - public boolean isNeedCache() { - return getBool("tb_need_cache"); - } - - public void setNeedCache(boolean tbNeedCache) { - setBool("tb_need_cache", tbNeedCache); - } - - public String getContent() { - return getStr("tb_content"); - } - - public long getCreateUid() { - return getLong("tb_create_uid"); - } - - public void setCreateUid(long tbCreateUid) { - put("tb_create_uid", tbCreateUid); - } - - public long getUpdateUid() { - return getLong("tb_update_uid"); - } - - public void setUpdateUid(long tbUpdateUid) { - put("tb_update_uid", tbUpdateUid); - } - - public long getCreateAt() { - return getLong("tb_create_at"); - } - - public void setCreateAt(long tbCreateAt) { - put("tb_create_at", tbCreateAt); - } - - public long getUpdateAt() { - return getLong("tb_update_at"); - } - - public void setUpdateAt(long tbUpdateAt) { - put("tb_update_at", tbUpdateAt); - } - - public String getIdField() { - return idField; - } - - public String getDbName() { - return ModelDatabaseCache.getInstance().getName(getDbId()); - } - - public List getFields() { - return fields; - } - - public List getIndexes() { - return indexes; - } - - public List getCaches() { - return caches; - } - - public ModelField findField(String fieldName) { - if (fieldName != null && fields != null) { - for (ModelField modelField : fields) { - if (fieldName.equals(modelField.getName())) { - return modelField; - } - } - } - - return null; - } - - public String findFieldTitle(String fieldName) { - ModelField field = findField(fieldName); - return field != null ? field.getTitle() : fieldName; - } - - public String fullName() { - return getDbName() + '.' + getName(); - } - - public void addIndex(ModelIndex modelIndex) { - indexes.add(modelIndex); - } - - public ModelIndex findIndexByName(String indexName) { - for (ModelIndex modelIndex : indexes) { - if (indexName.equals(modelIndex.getName())) { - return modelIndex; - } - } - - return null; - } - - public ModelIndex findPrimaryIndex() { - for (ModelIndex modelIndex : indexes) { - if (ModelIndex.TYPE_PRIMARY.equalsIgnoreCase(modelIndex.getType())) { - return modelIndex; - } - } - - return null; - } - - public ModelField findFieldByName(String name) { - if (name != null) { - for (ModelField value : fields) { - if (name.equalsIgnoreCase(value.getName())) { - return value; - } - } - } - - return null; - } - - public ModelField findFieldByType(int type) { - for (ModelField value : fields) { - if (type == value.getFieldType()) { - return value; - } - } - - return null; - } - - public ModelField findIdField() { - ModelIndex index = findPrimaryIndex(); - if (index != null) { - return findField(index.getFields()); - } - - return null; - } - - public List findLinkeNames() { - List list = new ArrayList<>(); - for (ModelField field : fields) { - if (field.getLink()<=0) { - continue; - } - ModelTable linkTable = ModelTableCache.getInstance().get(field.getLink()); - if (linkTable == null) { - continue; - } - ModelField linkNameField = linkTable.findFieldByType(SwEnum.FieldType.NAME.value); - if (linkNameField != null) { - list.add(new ModelLinkName(field.getName(), linkTable, linkNameField.getName())); - } - } - return list; - } - - public void setContent(String tableContent) { - put("tb_content", tableContent); - //读取表定义信息 - ModelTable bean = JsonUtil.parse(tableContent, ModelTable.class); - if (bean == null) { - return; - } - this.fields = bean.fields; - this.indexes = bean.indexes; - this.caches = bean.caches; - ModelIndex i = findPrimaryIndex(); - if (i != null) { - this.idField = i.getFields(); - } - } - - public String getSchemaTableName() { - String dbName = getDbName(); - if (StringUtils.isEmpty(dbName) || dbName.equals(SwConsts.DEF_DB_NAME)) return getName(); - return DbEngine.getInstance().getDbSchema() + "_" + dbName + "." + getName(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BindBeanException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BindBeanException.java deleted file mode 100644 index 0168e3a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BindBeanException.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.smtweb.framework.core.exception; - -/** - * bean绑定错误 - * @author kevin - * @since 2010-9-14 上午11:17:43 - * - */ -public class BindBeanException extends SwException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - private static String msg = "绑定bean异常:Context中已经存在这个bean: "; - - public BindBeanException() { - super(); - // TODO Auto-generated constructor stub - } - - public BindBeanException(String message, Throwable cause) { - super(message, cause); - // TODO Auto-generated constructor stub - } - - public BindBeanException(String message) { - - super(msg+message); - // TODO Auto-generated constructor stub - } - - public BindBeanException(Throwable cause) { - super(cause); - // TODO Auto-generated constructor stub - } - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BindParamException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BindParamException.java deleted file mode 100644 index 678c044..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BindParamException.java +++ /dev/null @@ -1,32 +0,0 @@ -package cc.smtweb.framework.core.exception; - -import java.text.ParseException; - -public class BindParamException extends SwException { - /** - * - */ - private static final long serialVersionUID = 1L; - private String paramName; - - public String getParamName() { - return paramName; - } - - public BindParamException(String message, String paramName) { - this(message, null, paramName); - } - - public BindParamException(Exception e, String paramName) { - this(e.getMessage(), e, paramName); - } - - public BindParamException(String message, Exception e, String paramName) { - super("[" + paramName + "]" + message, e); - this.paramName = paramName; - } - - public BindParamException(ParseException e) { - super(e); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BizException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BizException.java deleted file mode 100644 index 0fbb71a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/BizException.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.smtweb.framework.core.exception; - -/** - * 业务异常 - * @author kevin - * - */ -public class BizException extends RuntimeException { - /** - * - */ - private static final long serialVersionUID = 1L; - - public BizException() { - super(); - } - - public BizException(String message, Throwable cause) { - super(message, cause); - } - - public BizException(String message) { - super(message); - } - - public BizException(Throwable cause) { - super(cause.getMessage(), cause); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/DbException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/DbException.java deleted file mode 100644 index 5ca0635..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/DbException.java +++ /dev/null @@ -1,31 +0,0 @@ -package cc.smtweb.framework.core.exception; - -/** - * bean绑定错误 - * @author kevin - * @since 2010-9-14 上午11:17:43 - * - */ -public class DbException extends RuntimeException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public DbException() { - super(); - } - - public DbException(String message, Throwable cause) { - super(message, cause); - } - - public DbException(String message) { - super(message); - } - - public DbException(Throwable cause) { - super(cause.getMessage(), cause); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/ExceptionMessage.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/ExceptionMessage.java deleted file mode 100644 index 39ea4ec..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/ExceptionMessage.java +++ /dev/null @@ -1,102 +0,0 @@ -package cc.smtweb.framework.core.exception; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * 错误码 JDK version used: - * - * @author kevin - * @version v1.0 - */ -@Setter -@Getter -@ToString -public class ExceptionMessage { - private int code; - - private String msg; - - private ExceptionMessage(int code, String msg) { - this.code = code; - this.msg = msg; - } - - // 401 - public static ExceptionMessage NO_AUTH_ERROR = new ExceptionMessage(401, "登录失效!"); - - // 403 - public static ExceptionMessage FORBIDDEN_ERROR = new ExceptionMessage(403, "没有访问权限!"); - - // 404 - public static ExceptionMessage NOT_FOUND_ERROR = new ExceptionMessage(404, "没有找到需要资源!"); - - // 通用异常 - public static ExceptionMessage INNER_ERROR = new ExceptionMessage(100100, "内部服务错误,请稍后再试!"); - - // 参数错误 - public static ExceptionMessage PARAM_ERROR = new ExceptionMessage(100101, "参数校验失败!"); - - // 数据库访问异常 - public static ExceptionMessage DB_ERROR = new ExceptionMessage(100102, "数据库访问失败!"); - - // 外部网络访问异常 - public static ExceptionMessage NETWORK_ERROR = new ExceptionMessage(100103, "外部网络访问失败!"); - - // 字符转换异常 - public static ExceptionMessage UNSUPPORTED_ENCODING_ERROR = new ExceptionMessage(100104, "字符编码失败!"); - - // 没有登录 - public static ExceptionMessage NO_LOGIN_ERROR = new ExceptionMessage(100105, "用户没有登录!"); - - // 没有登录 - public static ExceptionMessage CAPTCHA_ERROR = new ExceptionMessage(100106, "验证码错误!"); - - // 用户不存在 - public static ExceptionMessage USER_ERROR = new ExceptionMessage(100107, "手机号或密码错误,请重新输入!"); - - // 用户被禁 - public static ExceptionMessage USER_FORBIDED = new ExceptionMessage(100108, "用户被禁!"); - - // 密码错误 - public static ExceptionMessage PASSWORD_ERROR = new ExceptionMessage(100109, "密码错误,请重新输入!"); - - // 文件上传失败 - public static ExceptionMessage FILE_UPLOAD_ERROR = new ExceptionMessage(100110, "文件上传失败!"); - - // 文件不存在 - public static ExceptionMessage FILE_NOT_EXIST = new ExceptionMessage(100111, "文件不存在!"); - - // 树形层级只有6级 - public static ExceptionMessage TREE_HIERARCHY_ERROR = new ExceptionMessage(100112, "树形层级过多!"); - - // 手机号被使用了 - public static ExceptionMessage PHONE_ERROR = new ExceptionMessage(100113, "手机号被使用了!"); - - // 手机号不存在 - public static ExceptionMessage PHONE_EXISTS_ERROR = new ExceptionMessage(100114, "手机号不存在!"); - - // 消息发送要延迟 - public static ExceptionMessage SM_SEND_NEED_DELAY = new ExceptionMessage(100115, "验证码有效时间"); - - // 身份不能确认 - public static ExceptionMessage IDENTITY_ERROR = new ExceptionMessage(100116, "请选择登录身份!"); - - // 身份不能确认 - public static ExceptionMessage USER_PERMISSION_CHANGE = new ExceptionMessage(100117, "权限变更,请选择退出重新登录!"); - - // 数据发生变更 - public static ExceptionMessage DATA_CHANGE_ERROR = new ExceptionMessage(100118, "数据发生变更,请刷新后重试!"); - - // 数据发生变更 - public static ExceptionMessage SM_SEND_ERROR = new ExceptionMessage(100119, "验证码发生失败!"); - - // 敏感词 - public static ExceptionMessage XSS_ERROR = new ExceptionMessage(100120, "含有敏感词,请检查。"); - - // 树形层级数量太多 - public static ExceptionMessage TREE_NUMBER_ERROR = new ExceptionMessage(100121, "树形该层节点过多!"); - - public static ExceptionMessage APP_ID_NOT_EXISTS = new ExceptionMessage(100122, "不存在的应用ID"); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/JsonParseException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/JsonParseException.java deleted file mode 100644 index 22fc5bf..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/JsonParseException.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.smtweb.framework.core.exception; - -public class JsonParseException extends SwException { - public JsonParseException(String s, Exception e) { - super(s, e); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/SwException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/SwException.java deleted file mode 100644 index 50306a5..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/exception/SwException.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.smtweb.framework.core.exception; - -import cc.smtweb.framework.core.exception.ExceptionMessage; - -/** - * 〈全局异常〉 - * - * @author kevin - * @since 1.0.0 - */ -public class SwException extends RuntimeException { - - private static final long serialVersionUID = 8096609992852791423L; - -// private ExceptionMessage cm; - - public SwException() { - } - - public SwException(String msg) { - super(msg); - } - - public SwException(int code, String msg) { - super(msg); - } - - public SwException(String msg, Throwable e) { - super(msg, e); - } - - public SwException(Throwable e) { - super(e.getMessage(), e); - } - - public SwException(ExceptionMessage cm) { - super(cm.getMsg()); - } - - public SwException(ExceptionMessage cm, Throwable e) { - super(cm.getMsg(), e); - } - - public SwException(ExceptionMessage cm, String msg) { - super(msg); - } - - -// public ExceptionMessage getCm() { -// return cm; -// } - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/ISchedulerWakeup.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/ISchedulerWakeup.java deleted file mode 100644 index 0cfd153..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/ISchedulerWakeup.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.smtweb.framework.core.mvc; - -/** - * 定时任务唤醒服务接口 - * @author xkliu - */ -public interface ISchedulerWakeup { - /** - * 唤醒定时任务立即执行 - * @param clazz 包含定时任务方法的类名 - * @param methodName 有定时任务注解的方法名 - * @return 是否唤醒请求成功 - */ - boolean wakeup(Class clazz, String methodName); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/SchedulerManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/SchedulerManager.java deleted file mode 100644 index 5baf5aa..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/SchedulerManager.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.smtweb.framework.core.mvc; - -import org.springframework.stereotype.Component; - -/** - * 定时器服务 - * @author xkliu - */ -@Component -public class SchedulerManager { - private ISchedulerWakeup schedulerWakeup; - - public void install(ISchedulerWakeup schedulerWakeup) { - this.schedulerWakeup = schedulerWakeup; - } - - /** - * 唤醒定时器立即执行 - * @param clazz 定时器类 - * @param methodName 有@SwScheduling注解的定时器方法名 - */ - public boolean wakeup(Class clazz, String methodName) { - if (this.schedulerWakeup != null) { - return schedulerWakeup.wakeup(clazz, methodName); - } - - return false; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/ControllerConfig.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/ControllerConfig.java deleted file mode 100644 index a36f7bd..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/ControllerConfig.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.smtweb.framework.core.mvc.config; - -import cc.smtweb.framework.core.mvc.controller.scan.IScanActionBuilder; -import lombok.Getter; - -@Getter -public class ControllerConfig { - /** 模块名称 */ - private final String module; - /** 控制器的包路径 */ - private final String packagePath; - - private IScanActionBuilder scanActionBuilder; - - public ControllerConfig(String module, String packagePath) { - this(module, packagePath, null); - } - - public ControllerConfig(String module, String packagePath, IScanActionBuilder scanActionBuilder) { - this.module = module; - this.packagePath = packagePath; - this.scanActionBuilder = scanActionBuilder; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/GlobalExceptionHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/GlobalExceptionHandler.java deleted file mode 100644 index 6737ab9..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/GlobalExceptionHandler.java +++ /dev/null @@ -1,88 +0,0 @@ -package cc.smtweb.framework.core.mvc.config; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.mvc.realm.exception.*; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.validation.ObjectError; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * 〈异常处理〉 - * - * @author kevin - * @since 1.0.0 - */ -@RestControllerAdvice -@Slf4j -public class GlobalExceptionHandler { -// private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class); -// -// /** -// * 〈校验的异常处理〉 -// */ -// @ExceptionHandler(value = {BindException.class}) -// @ResponseBody -// public Result handleBindException(BindException be) { -// return super.handleException(be); -// } -// - - @ExceptionHandler(AuthenticationException.class) - @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public R handleAuthenticationException(AuthenticationException e) { - return R.error("认证失败", e); - } - - @ExceptionHandler(UnauthenticatedException.class) - @ResponseStatus(HttpStatus.UNAUTHORIZED) - public R handleUnauthenticatedException(UnauthenticatedException e) { - return R.error("认证失败", e); - } - - @ExceptionHandler(UnknownAccountException.class) - @ResponseStatus(HttpStatus.UNAUTHORIZED) - public R handleUnknownAccountException(UnknownAccountException e) { - return R.error("用户名或密码错误", e); - } - - @ExceptionHandler(AuthorizationException.class) - @ResponseStatus(HttpStatus.FORBIDDEN) - public R handleAuthorizationException(AuthorizationException e) { - log.error("No permissions:" + e.getMessage()); - return R.error("没有权限", e); - } - - @ExceptionHandler(ForbiddenException.class) - @ResponseStatus(HttpStatus.FORBIDDEN) - public R handleAuthorizationException(ForbiddenException e) { - log.error("No permissions:" + e.getMessage()); - return R.error("没有权限", e); - } - - @ExceptionHandler(value = {Exception.class}) - @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public R handleException(Exception ex) { - Throwable e = ex; - if (ex instanceof java.lang.reflect.InvocationTargetException) { - e = ex.getCause(); - } - - log.error(e.getMessage(), e); - return R.error(e.getMessage(), e); - } - - @ExceptionHandler(MethodArgumentNotValidException.class) - public R handleException(MethodArgumentNotValidException ex) { - List errors = ex.getBindingResult().getAllErrors(); - List validationMsg = errors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList()); - // 不满足需求 一个一个提示 - return R.error(validationMsg.get(0)); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/SettingsEnvironmentPostProcessor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/SettingsEnvironmentPostProcessor.java deleted file mode 100644 index e31d3a9..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/SettingsEnvironmentPostProcessor.java +++ /dev/null @@ -1,58 +0,0 @@ -package cc.smtweb.framework.core.mvc.config; - -import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.PropertiesPropertySource; -import org.springframework.core.io.FileSystemResource; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -/** - * 〈读取外部配置文件〉 - * - * @author kevin - * @since 1.0.0 - */ -public class SettingsEnvironmentPostProcessor implements EnvironmentPostProcessor { - - @Override - public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, - SpringApplication springApplication) { - List files = this.getProperties(); - for (File file : files) { - if (file.exists()) { - YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); - FileSystemResource resource = new FileSystemResource(file); - yaml.setResources(resource); - if (yaml.getObject() != null) { - configurableEnvironment.getPropertySources() - .addLast(new PropertiesPropertySource(file.getName(), yaml.getObject())); - } - } - } - } - - /** - * <>获取所有资源配置文件 - */ - private List getProperties() { - List result = new ArrayList<>(); - String tomcatConf = System.getProperty("catalina.base") + File.separator + "conf" + File.separator; - File[] listFiles = new File(tomcatConf).listFiles(); - if (listFiles != null && listFiles.length > 0) { - for (File lf : listFiles) { - if (lf.isFile()) { - if (lf.getName().endsWith(".yaml")) { - result.add(lf); - } - } - } - } - return result; - } - -} \ No newline at end of file diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java deleted file mode 100644 index 11369d7..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/config/WebMvcConfig.java +++ /dev/null @@ -1,132 +0,0 @@ -package cc.smtweb.framework.core.mvc.config; - -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.db.jdbc.IdGenerator; -import cc.smtweb.framework.core.mvc.controller.ApiConfigBean; -import cc.smtweb.framework.core.mvc.controller.MethodAccessManager; -import cc.smtweb.framework.core.session.SessionManager; -import cc.smtweb.framework.core.session.UserSessionArgumentResolver; -import cc.smtweb.framework.core.util.JsonUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.http.MediaType; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import java.util.List; - -/** - * @author kevin - */ -@Configuration -@Slf4j -public class WebMvcConfig implements WebMvcConfigurer { - private static final String PATTERN_FILES = "/files/**"; - private static final String PATTERN_STATIC = "/static/**"; - - @Value("${smtweb.file.local-path}") - private String fileLocalPath; - - @Value("${smtweb.static.local-path:}") - private String staticLocalPath; - -// @Value("${smtweb.api.json-full:}") -// private String apiJsonFull; - - @Autowired - private ApiConfigBean apiConfigBean; - - private static final String TRUE_VALUE = "true"; - - @Autowired - private RedisManager redisManager; - - @Bean - public SessionManager sessionManager(RedisManager redisManager, IdGenerator idGenerator) { - return new SessionManager(redisManager, idGenerator); - } - - @Bean - public CacheManager cacheManager() { - return new CacheManager(); - } - - @Bean - public MethodAccessManager methodAccessManager(CacheManager cacheManager) { - return new MethodAccessManager(redisManager, cacheManager); - } - - @Override - public void addCorsMappings(CorsRegistry registry) { - // 2.4 以前使用 .allowedOrigins("*") - registry.addMapping("/**") - .allowedOriginPatterns("*") - .allowedMethods("*") - .maxAge(3600) - .allowCredentials(true); - } - - @Bean - @Primary - public HttpMessageConverters customConverters() { - MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); - if (apiConfigBean.isJsonFull()) { - // 输出所有空属性 - messageConverter.setObjectMapper(JsonUtil.API_OBJECT_MAPPER); - } else { - messageConverter.setObjectMapper(JsonUtil.OBJECT_MAPPER); - } - - // 将转换器添加到converters中 - return new HttpMessageConverters(messageConverter); - } - - @Override - public void addArgumentResolvers(List argumentResolvers) { - argumentResolvers.add(new UserSessionArgumentResolver()); - } - - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - // 静态资源文件 - if (!registry.hasMappingForPattern(PATTERN_STATIC)) { - if (StringUtils.isBlank(staticLocalPath)) { - registry.addResourceHandler(PATTERN_STATIC).addResourceLocations("classpath:/static/"); - } else if (staticLocalPath.endsWith("/")) { - // staticLocalPath 必须 / 结束 - registry.addResourceHandler(PATTERN_STATIC).addResourceLocations("classpath:/static/", - "file:" + staticLocalPath); - log.info("'/static/**' => file:" + staticLocalPath); - } else { - log.error("'smtweb.static.local-path' 必须用'/'结尾: " + staticLocalPath); - } - } else { - log.error("'/static/**' 已经被注册"); - } - - // 动态用户文件 - if (!registry.hasMappingForPattern(PATTERN_FILES)) { - registry.addResourceHandler(PATTERN_FILES).addResourceLocations("file:" + fileLocalPath); - log.info("'/files/**' => file:" + fileLocalPath); - } else { - log.error("'/files/**' 已经被注册"); - } - } - - // 所有返回接口Content-Type默认都返回application/json - @Override - public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { - configurer.defaultContentType(MediaType.APPLICATION_JSON); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiConfigBean.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiConfigBean.java deleted file mode 100644 index 2d69275..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiConfigBean.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -/** - * API相关配置参数 - * @author xkliu - */ -@Component -@ConfigurationProperties(prefix = "smtweb.api") -@Data -public class ApiConfigBean { - // JSON是否输出非空字段 - private boolean jsonFull; - // 是否支持大驼峰url匹配规则 - private boolean lowerCaseUrl; - // 是否支持大驼峰url匹配规则,默认都支持 little camel-case - private boolean bigCameCaseUrl; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiController.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiController.java deleted file mode 100644 index 4ee218c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/ApiController.java +++ /dev/null @@ -1,60 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.PreDestroy; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Map; - -/** - * API接口控制器,所有API的入口 - * @author xkliu - */ -@RestController -public class ApiController { - @Autowired - private MethodAccessManager methodAccessManager; - - /** - * 处理API的GET请求 - * @param params URL请求参数 - * @param request Http请求类 - * @param response Http应答类 - * @return 返回对象,一般在函数里面使用R - * @throws Exception API处理异常 - */ - @GetMapping(value = "/api/**", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}) - public Object commonGet(@RequestParam Map params, - HttpServletRequest request, HttpServletResponse response) throws Exception { - String apiUrl = request.getRequestURI().substring(5); - return methodAccessManager.invoke(apiUrl, params, null, request, response); - } - - /** - * 处理API的POST请求 - * @param params URL请求参数 - * @param body POST内容,JSON格式 - * @param request Http请求类 - * @param response Http应答类 - * @return 返回对象,一般在函数里面使用R - * @throws Exception API处理异常 - */ - @PostMapping(value = "/api/**", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}) - public Object commonPost(@RequestParam Map params, @RequestBody(required = false) String body, - HttpServletRequest request, HttpServletResponse response) throws Exception { - String apiUrl = request.getRequestURI().substring(5); - // 保证body在post的清空下不为null,用于区分get时吧参数组合成body - if (body == null) { - body = ""; - } - return methodAccessManager.invoke(apiUrl, params, body, request, response); - } - - @PreDestroy - public void fin() { - methodAccessManager.showdown(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/DefaultPageController.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/DefaultPageController.java deleted file mode 100644 index 1f2fa7d..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/DefaultPageController.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; - -/** - * 默认静态页面处理 - * @author xkliu - */ -@Controller -public class DefaultPageController { - /** - * 重定向默认静态页面 - * @return 静态页面重定向路径 - */ - @GetMapping("/") - public String index() { - return "forward:/static/index.html"; - } - - /** - * 重定向默认网站图标 - * @return 网站图标重定向路径 - */ - @GetMapping(value = "/favicon.ico") - public String favicon() { - return "forward:/static/favicon.ico"; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IActionManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IActionManager.java deleted file mode 100644 index 63ca1ca..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IActionManager.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller; - -import cc.smtweb.framework.core.mvc.controller.access.IMethodAccess; - -public interface IActionManager { - boolean api(String url, IMethodAccess methodAccess); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IBeanContext.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IBeanContext.java deleted file mode 100644 index 9746ee7..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IBeanContext.java +++ /dev/null @@ -1,8 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller; - -import org.springframework.beans.BeansException; - -public interface IBeanContext { - T getBean(String name, Class type) throws BeansException; - T getBean(Class type) throws BeansException; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IEditor.java deleted file mode 100644 index 8eff0d7..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/IEditor.java +++ /dev/null @@ -1,27 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -/** - * API参数解析器接口 - * @author xkliu - */ -public interface IEditor { - String USER_SESSION = "_SW_USER_SESSION"; - String USER_TOKEN = "_SW_TOKEN"; - String BODY_MAP = "_SW_BODY_MAP"; -// String BODY_BEAN = "_SW_BODY_BEAN"; - - /** - * 根据请求参数转为函数参数定义的类型的值 - * @param paramName 参数名 - * @param paramType 参数类型 - * @param context 全局bean对象上下文 - * @param params URL请求参数(query) - * @param body POST内容 - * @param request http请求 - * @return 转化后的值 - */ - Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/MethodAccessManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/MethodAccessManager.java deleted file mode 100644 index 67e99d1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/MethodAccessManager.java +++ /dev/null @@ -1,105 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller; - -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.cache.ISwCache; -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.mvc.SchedulerManager; -import cc.smtweb.framework.core.mvc.controller.access.IMethodAccess; -import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; -import cc.smtweb.framework.core.mvc.controller.scan.BeanManager; -import cc.smtweb.framework.core.mvc.realm.interceptor.PermInterceptor; -import cc.smtweb.framework.core.mvc.realm.service.PermChecker; -import cc.smtweb.framework.core.mvc.scheduler.SchedulerTaskManager; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Map; - -/** - * 服务方法调用管理,通过url进行API调用 - * @author xkliu - */ -@Slf4j -public class MethodAccessManager { - private Map controllers; - private IBeanContext beanContext; - private PermInterceptor permInterceptor; - private SchedulerTaskManager schedulerTaskManager; - private MethodAccess[] destroyMethods; - - @Getter - private CacheManager cacheManager; - - public MethodAccessManager(RedisManager redisManager, CacheManager cacheManager) { - permInterceptor = new PermInterceptor(redisManager); - this.cacheManager = cacheManager; - } - - // 执行控制器方法 - Object invoke(String url, Map params, String body, HttpServletRequest request, HttpServletResponse response) throws Exception { - // 调用普通方法 -// String url = module + "/" + service + "/" + method; - - IMethodAccess methodAccess = controllers.get(url); - - if (methodAccess != null) { - permInterceptor.preHandle(request, methodAccess.getPerm()); - - return methodAccess.invoke(beanContext, params, body, request); - } - - // TODO 调用默认方法 -// url = module + "/" + service + "/"; -// -// methodAccess = controllers.get(url); -// -// if (methodAccess != null) { -// permInterceptor.preHandle(request, methodAccess.getPerm()); -// -// request.setAttribute(PathParamEditor.ATTR_KEY, method); -// return methodAccess.invoke(beanContext, params, body, request, response); -// } - - return R.error(404, "not find api:" + url); - } - - public void init(BeanManager beanManager, ISwCache cache) { - this.beanContext = beanManager.getBeanContext(); - this.controllers = beanManager.getControllers(); - this.destroyMethods = beanManager.loadDestroyMethods(); - this.permInterceptor.setCache(cache); - - // 启动定时任务 - this.schedulerTaskManager = SchedulerTaskManager.build(beanContext, beanManager.getTasks()); - - if (this.schedulerTaskManager != null) { - // 设置用于外部服务调用 - SchedulerManager schedulerManager = this.beanContext.getBean(SchedulerManager.class); - if (schedulerManager != null) { - schedulerManager.install(this.schedulerTaskManager); - } else { - log.error("not find spring bean schedulerManager"); - } - } - } - - void showdown() { - // 强行关闭定时任务 - if (this.schedulerTaskManager != null) { - this.schedulerTaskManager.shutdown(); - } - - if (destroyMethods != null) { - for (MethodAccess methodAccess : destroyMethods) { - try { - methodAccess.invoke(beanContext); - } catch (Exception e) { - log.error(methodAccess.fullName(), e); - } - } - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/BindFieldAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/BindFieldAccess.java deleted file mode 100644 index 482b0df..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/BindFieldAccess.java +++ /dev/null @@ -1,27 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; - -import java.lang.reflect.Field; -import java.util.Map; - -public class BindFieldAccess extends FieldAccess { - private IEditor editor; - private final String beanName; - - public BindFieldAccess(IEditor editor, Field field, String beanName) { - super(field); - this.editor = editor; - this.beanName = beanName; - } - - @Override - protected Object getFieldValue(Object instance, IBeanContext context, Map params) { - if (editor != null) { - return editor.getParamValue(beanName, this.field.getType(), context, params, null, null); - } - - return null; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/ControllerAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/ControllerAccess.java deleted file mode 100644 index dc61fff..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/ControllerAccess.java +++ /dev/null @@ -1,69 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; -import java.util.Map; - -/** 控制器访问类 */ -@Slf4j -public class ControllerAccess implements IBeanAccess { - private final Class clazz; - private final List fieldList; - @Getter - private final boolean singleton; - @Getter - private Object singletonInstance; - - public ControllerAccess(Class clazz, List fieldList, boolean singleton) { - this.clazz = clazz; - this.fieldList = fieldList; - this.singleton = singleton; - } - - public String getFullName() { - return clazz.getName(); - } - - public Object getOrNewInstance(IBeanContext context, Map params) throws IllegalAccessException, InstantiationException { - if (singletonInstance != null) { - return singletonInstance; - } else { - Object result = clazz.newInstance(); - - writeBeanFields(result, context, params); - - return result; - } - } - - private void writeBeanFields(Object bean, IBeanContext context, Map params) { - for (FieldAccess fieldAccess: fieldList) { - boolean ret = fieldAccess.writeValue(bean, context, params); - if (!ret) { - log.error("write bean " + fieldAccess.getFullName(bean) - + " failure."); - } - } - } - - public Object initSingletonFields(IBeanContext context, Map params) { - if (singletonInstance != null) { - writeBeanFields(singletonInstance, context, params); - } - - return singletonInstance; - } - - public Class getBeanType() { - return clazz; - } - - public void newSingletonInstance() throws IllegalAccessException, InstantiationException { - if (isSingleton()) { - this.singletonInstance = clazz.newInstance(); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/FieldAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/FieldAccess.java deleted file mode 100644 index 392ec6e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/FieldAccess.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -import cc.smtweb.framework.core.exception.BindBeanException; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; - -import java.lang.reflect.Field; -import java.util.Map; - -public abstract class FieldAccess { - protected final Field field; - - public FieldAccess(Field field) { - this.field = field; - } - - protected abstract Object getFieldValue(Object instance, IBeanContext context, Map params); - - public boolean writeValue(Object instance, IBeanContext context, Map params) { - Object bean = getFieldValue(instance, context, params); - - if (bean != null) { - field.setAccessible(true); - - try { - field.set(instance, bean); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new BindBeanException("not set " + getFullName(instance) + " value", e); - } - - return true; - } - - return false; - } - - public String getFullName(Object instance) { - return instance.getClass().getName() + "." + field.getName(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IBeanAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IBeanAccess.java deleted file mode 100644 index 17c8fc3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IBeanAccess.java +++ /dev/null @@ -1,5 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -public interface IBeanAccess { - Object getSingletonInstance(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IMethodAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IMethodAccess.java deleted file mode 100644 index b070db5..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/IMethodAccess.java +++ /dev/null @@ -1,50 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -/** - * API方法访问接口 - * @author xkliu - */ -public interface IMethodAccess { - // 方法返回值Java类型 - Class getReturnType(); - - // @SwBody 注解Java类型 - Class getBodyType(); - - // @SwAttr 注解Java类型 - Class getAttrType(String paramName); - - /** - * 执行反射的API函数,一般时定时器等无参数环境调用 - * @param context 对象上下文 - * @return API函数返回值 - */ - Object invoke(IBeanContext context); - - /** - * 执行类方法,实现API调用 - * @param context 上下文对象,包括springboot服务类,@SwBean类 - * @param params url请求参数map - * @param body post请求的内容 - * @param request HTTP请求对象 - * @return 应答对象,一般是返回R转换为json返回 - */ - Object invoke(IBeanContext context, Map params, String body, HttpServletRequest request); - - /** - * 输出错误信息用,方法全名 - * @return 方法全名 - */ - String fullName(); - - /** - * API权限 - * @return 权限串 - */ - String getPerm(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodAccess.java deleted file mode 100644 index 3ec44b1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodAccess.java +++ /dev/null @@ -1,117 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.exception.BindBeanException; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.binder.ParamEditor; -import lombok.Getter; -import org.apache.commons.lang3.ObjectUtils; - -import javax.servlet.http.HttpServletRequest; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Map; - -/** - * API方法执行 - * - * @author xkliu - */ -public class MethodAccess implements IMethodAccess { - private final ControllerAccess controllerAccess; - private final Method method; - @Getter - private final String perm; - private final MethodParamAccess[] paramBinds; - - public MethodAccess(ControllerAccess controllerAccess, Method method, String perm, MethodParamAccess[] paramBinds) { - this.controllerAccess = controllerAccess; - this.method = method; - this.perm = perm; - this.paramBinds = paramBinds; - } - - @Override - public Class getReturnType() { - return this.method.getReturnType(); - } - - @Override - public Class getBodyType() { - for (MethodParamAccess methodParamAccess : paramBinds) { - if (methodParamAccess.getBindType() == ParamEditor.TYPE_BODY) { - return methodParamAccess.getParamType(); - } - } - - return null; - } - - @Override - public Class getAttrType(String paramName) { - for (MethodParamAccess methodParamAccess : paramBinds) { - if (methodParamAccess.getBindType() == ParamEditor.TYPE_ATTR && paramName.equals(methodParamAccess.getParamName())) { - return methodParamAccess.getParamType(); - } - } - - return null; - } - - @Override - public Object invoke(IBeanContext context) { - return invoke(context, null, null, null); - } - - @Override - public Object invoke(IBeanContext context, Map params, String body, HttpServletRequest request) { - // 通过请求数据转换函数参数值 - Object[] args = null; - - if (!ObjectUtils.isEmpty(paramBinds)) { - args = new Object[paramBinds.length]; - for (int i = 0; i < paramBinds.length; i++) { - MethodParamAccess param = paramBinds[i]; - try { - args[i] = param.getParamValue(context, params, body, request); - } catch (Exception e) { - throw new BindBeanException(String.format("%s error value: %s", param.getParamName(), param.toString()), e); - } - } - } - - // 获取服务实例,然后执行方法 - try { - Object instance = controllerAccess.getOrNewInstance(context, params); - return method.invoke(instance, args); - } catch (IllegalAccessException | InstantiationException e) { - throw new SwException(e); - } catch (InvocationTargetException e) { - throw new SwException(e.getCause()); - } catch (BizException e) { - return R.error(e.getMessage()); - } - } - - @Override - public String fullName() { - return controllerAccess.getFullName() + "." + method.getName(); - } - - public Class findParam(Class clazz) { - for (MethodParamAccess param : paramBinds) { - Class paramType = param.getParamType(); - if (clazz.equals(paramType)) { - return paramType; - } - } - - return null; - } - - public String controllerFullName() { - return this.controllerAccess.getFullName(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodParamAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodParamAccess.java deleted file mode 100644 index 800c24a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/MethodParamAccess.java +++ /dev/null @@ -1,42 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import lombok.Getter; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -/** - * API方法参数访问器 - * @author xkliu - */ -@Getter -public class MethodParamAccess { - private int bindType; - private final IEditor editor; - private final String paramName; - private final Class collectionType; - private final Class paramType; - - public MethodParamAccess(IEditor editor, String paramName, Class paramType, int bindType, Class collectionType) { - this.editor = editor; - this.paramName = paramName; - this.paramType = paramType; - this.bindType = bindType; - this.collectionType = collectionType; - } - - public Object getParamValue(IBeanContext context, Map params, String body, HttpServletRequest request) { - if (editor != null) { - return editor.getParamValue(paramName, paramType, context, params, body, request); - } - - return null; - } - - @Override - public String toString() { - return paramName + ":" + paramType.getSimpleName() + "-" + editor.getClass().getSimpleName(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/SchedulerMethodAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/SchedulerMethodAccess.java deleted file mode 100644 index 6104a6a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/SchedulerMethodAccess.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -import cc.smtweb.framework.core.annotation.SwScheduling; -import com.serotonin.timer.CronTimerTrigger; -import com.serotonin.timer.TimerTrigger; -import lombok.Getter; - -import java.text.ParseException; - -@Getter -public class SchedulerMethodAccess { - private final MethodAccess methodAccess; - private final SwScheduling swScheduling; - private final TimerTrigger timerTrigger; - - public SchedulerMethodAccess(MethodAccess methodAccess, SwScheduling swScheduling) throws ParseException { - this.timerTrigger = new CronTimerTrigger(swScheduling.value()); - this.methodAccess = methodAccess; - this.swScheduling = swScheduling; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/SingletonFieldAccess.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/SingletonFieldAccess.java deleted file mode 100644 index 88a5d7f..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/access/SingletonFieldAccess.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.access; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; - -import java.lang.reflect.Field; -import java.util.Map; - -public class SingletonFieldAccess extends FieldAccess { - private final Object fieldValue; - - public SingletonFieldAccess(Object fieldValue, Field field) { - super(field); - this.fieldValue = fieldValue; - } - - @Override - protected Object getFieldValue(Object instance, IBeanContext context, Map params) { - return fieldValue; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/BeanContext.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/BeanContext.java deleted file mode 100644 index 7510494..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/BeanContext.java +++ /dev/null @@ -1,47 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; - -import java.util.Map; - -public class BeanContext implements IBeanContext { - private final Map, Object> beanMap; - private final BeanFactory applicationContext; - - public BeanContext(Map, Object> beanMap, BeanFactory applicationContext) { - this.beanMap = beanMap; - this.applicationContext = applicationContext; - } - - @Override - public T getBean(String name, Class type) throws BeansException { - Object controllerAccess = beanMap.get(type); - - if (controllerAccess == null) { - return applicationContext.getBean(name, type); - } else { - return (T)controllerAccess; - } - } - - @Override - public T getBean(Class type) throws BeansException { - Object controllerAccess = beanMap.get(type); - - if (controllerAccess != null) { - return (T) controllerAccess; - } - - controllerAccess = applicationContext.getBean(type); - if (controllerAccess != null) { - return (T) controllerAccess; - } - - return null; - } - - public void init() { - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/CacheEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/CacheEditor.java deleted file mode 100644 index cc67d88..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/CacheEditor.java +++ /dev/null @@ -1,26 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder; - -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -public class CacheEditor implements IEditor { - private CacheManager cacheManager; - - public CacheEditor(CacheManager cacheManager) { - this.cacheManager = cacheManager; - } - - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - if (StringUtils.isNotBlank(paramName)) { - return cacheManager.getCache(paramName); - } else { - return cacheManager.getCache(paramType.getSimpleName()); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/ParamEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/ParamEditor.java deleted file mode 100644 index fcd56e3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/ParamEditor.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder; - -import cc.smtweb.framework.core.mvc.controller.IEditor; -import lombok.Setter; - -import java.util.HashMap; -import java.util.Map; - -public class ParamEditor { - public static final int TYPE_UNKNOWN = 0; - public static final int TYPE_FIELD = 1; - public static final int TYPE_PARAM = 2; - public static final int TYPE_BODY = 3; - public static final int TYPE_PATH = 4; - public static final int TYPE_HEADER = 5; - public static final int TYPE_COOKIE = 6; - public static final int TYPE_ATTR = 7; - - private final Map, IEditor> editors = new HashMap<>(); - - @Setter - private IEditor defaultEditor; - - ParamEditor(IEditor defaultEditor) { - this.defaultEditor = defaultEditor; - } - - public void add(Class clazz, IEditor editor) { - editors.put(clazz, editor); - } - - public IEditor find(Class paramType) { - IEditor result = editors.get(paramType); - if (result == null) { - result = defaultEditor; - } - - return result; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/WebDataBinder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/WebDataBinder.java deleted file mode 100644 index d11759e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/WebDataBinder.java +++ /dev/null @@ -1,225 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.common.SwIpAddr; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import cc.smtweb.framework.core.mvc.controller.binder.attr.BeanAttrEditor; -import cc.smtweb.framework.core.mvc.controller.binder.bean.*; -import cc.smtweb.framework.core.mvc.controller.binder.body.BeanBodyEditor; -import cc.smtweb.framework.core.mvc.controller.binder.body.StringBodyEditor; -import cc.smtweb.framework.core.mvc.controller.binder.body.SwMapBodyEditor; -import cc.smtweb.framework.core.mvc.controller.binder.param.*; -import cc.smtweb.framework.core.mvc.controller.binder.path.PathParamEditor; -import cc.smtweb.framework.core.mvc.scheduler.SchedulerPoint; -import cc.smtweb.framework.core.session.UserSession; -import lombok.extern.slf4j.Slf4j; - -import javax.servlet.http.HttpServletRequest; -import java.sql.Timestamp; - -@Slf4j -public class WebDataBinder { - private ParamEditor paramEditor = new ParamEditor(new BeanEditor()); - private ParamEditor bodyEditor = new ParamEditor(new BeanBodyEditor()); - private ParamEditor pathEditor = new ParamEditor(new PathParamEditor()); - private ParamEditor headerEditor = new ParamEditor(new NullEditor()); - private ParamEditor attributeEditor = new ParamEditor(new BeanAttrEditor()); - private IEditor cacheEditor; - - public WebDataBinder(IEditor cacheEditor) { - this.cacheEditor = cacheEditor; - initParamEditor(); - initBodyEditor(); - initHeaderEditor(); - } - -// public void addParamEditor(Class type, IEditor editor) { -// paramEditor.add(String.class, editor); -// } - - public IEditor findEditor(Class paramType, int bindType) { - IEditor result; - - switch (bindType) { - case ParamEditor.TYPE_UNKNOWN: - case ParamEditor.TYPE_PARAM: - case ParamEditor.TYPE_FIELD: - if (AbstractCache.class.isAssignableFrom(paramType)) { - result = cacheEditor; - } else { - result = paramEditor.find(paramType); - } - break; - case ParamEditor.TYPE_BODY: - // @SwBody - result = bodyEditor.find(paramType); - break; - case ParamEditor.TYPE_PATH: - result = pathEditor.find(paramType); - break; - case ParamEditor.TYPE_HEADER: - result = headerEditor.find(paramType); - break; - case ParamEditor.TYPE_ATTR: - result = attributeEditor.find(paramType); - break; - default: - throw new IllegalStateException("Unexpected type value: " + bindType); - } - - return result; - } - - private void initParamEditor() { - TimestampEditor timestampEditor = new TimestampEditor(ParamEditor.TYPE_PARAM); - paramEditor.add(String.class, new StringEditor(ParamEditor.TYPE_PARAM)); - paramEditor.add(Timestamp.class, timestampEditor); - paramEditor.add(java.util.Date.class, timestampEditor); - paramEditor.add(java.sql.Date.class, new DateEditor(ParamEditor.TYPE_PARAM)); - paramEditor.add(java.sql.Time.class, new TimeEditor(ParamEditor.TYPE_PARAM)); - - paramEditor.add(Byte.TYPE, new ByteEditor(ParamEditor.TYPE_PARAM,true)); - paramEditor.add(Long.TYPE, new LongEditor(ParamEditor.TYPE_PARAM, true)); - paramEditor.add(Double.TYPE, new DoubleEditor(ParamEditor.TYPE_PARAM, true)); - paramEditor.add(Float.TYPE, new FloatEditor(ParamEditor.TYPE_PARAM, true)); - paramEditor.add(Short.TYPE, new ShortEditor(ParamEditor.TYPE_PARAM, true)); - paramEditor.add(Integer.TYPE, new IntegerEditor(ParamEditor.TYPE_PARAM, true)); - paramEditor.add(Boolean.TYPE, new BooleanEditor(ParamEditor.TYPE_PARAM, true)); - paramEditor.add(Character.TYPE,new CharEditor(ParamEditor.TYPE_PARAM, true)); - - paramEditor.add(Byte.class, new ByteEditor(ParamEditor.TYPE_PARAM, false)); - paramEditor.add(Long.class, new LongEditor(ParamEditor.TYPE_PARAM, false)); - paramEditor.add(Double.class, new DoubleEditor(ParamEditor.TYPE_PARAM,false)); - paramEditor.add(Float.class, new FloatEditor(ParamEditor.TYPE_PARAM,false)); - paramEditor.add(Short.class, new ShortEditor(ParamEditor.TYPE_PARAM,false)); - paramEditor.add(Integer.class, new IntegerEditor(ParamEditor.TYPE_PARAM,false)); - paramEditor.add(Boolean.class, new BooleanEditor(ParamEditor.TYPE_PARAM,false)); - - paramEditor.add(HttpServletRequest.class, new HttpServletRequestEditor()); -// paramEditor.add(HttpServletResponse.class, new HttpServletResponseEditor()); - paramEditor.add(UserSession.class, new UserSessionEditor()); - paramEditor.add(SwIpAddr.class, new SwIpAddrEditor()); - paramEditor.add(SchedulerPoint.class, new BeanTypeEditor()); - } - - private void initBodyEditor() { - TimestampEditor timestampEditor = new TimestampEditor(ParamEditor.TYPE_BODY); - bodyEditor.add(String.class, new StringEditor(ParamEditor.TYPE_BODY)); - bodyEditor.add(Timestamp.class, timestampEditor); - bodyEditor.add(java.util.Date.class, timestampEditor); - bodyEditor.add(java.sql.Date.class, new DateEditor(ParamEditor.TYPE_BODY)); - bodyEditor.add(java.sql.Time.class, new TimeEditor(ParamEditor.TYPE_BODY)); - - bodyEditor.add(Byte.TYPE, new ByteEditor(ParamEditor.TYPE_BODY,true)); - bodyEditor.add(Long.TYPE, new LongEditor(ParamEditor.TYPE_BODY, true)); - bodyEditor.add(Double.TYPE, new DoubleEditor(ParamEditor.TYPE_BODY, true)); - bodyEditor.add(Float.TYPE, new FloatEditor(ParamEditor.TYPE_BODY, true)); - bodyEditor.add(Short.TYPE, new ShortEditor(ParamEditor.TYPE_BODY, true)); - bodyEditor.add(Integer.TYPE, new IntegerEditor(ParamEditor.TYPE_BODY, true)); - bodyEditor.add(Boolean.TYPE, new BooleanEditor(ParamEditor.TYPE_BODY, true)); - bodyEditor.add(Character.TYPE,new CharEditor(ParamEditor.TYPE_BODY, true)); - - bodyEditor.add(Byte.class, new ByteEditor(ParamEditor.TYPE_BODY, false)); - bodyEditor.add(Long.class, new LongEditor(ParamEditor.TYPE_BODY, false)); - bodyEditor.add(Double.class, new DoubleEditor(ParamEditor.TYPE_BODY,false)); - bodyEditor.add(Float.class, new FloatEditor(ParamEditor.TYPE_BODY,false)); - bodyEditor.add(Short.class, new ShortEditor(ParamEditor.TYPE_BODY,false)); - bodyEditor.add(Integer.class, new IntegerEditor(ParamEditor.TYPE_BODY,false)); - bodyEditor.add(Boolean.class, new BooleanEditor(ParamEditor.TYPE_BODY,false)); - - bodyEditor.add(String.class, new StringBodyEditor()); - bodyEditor.add(SwMap.class, new SwMapBodyEditor()); - } - - private void initHeaderEditor() { - TimestampEditor timestampEditor = new TimestampEditor(ParamEditor.TYPE_HEADER); - headerEditor.add(String.class, new StringEditor(ParamEditor.TYPE_HEADER)); - headerEditor.add(Timestamp.class, timestampEditor); - headerEditor.add(java.util.Date.class, timestampEditor); - headerEditor.add(java.sql.Date.class, new DateEditor(ParamEditor.TYPE_HEADER)); - headerEditor.add(java.sql.Time.class, new TimeEditor(ParamEditor.TYPE_HEADER)); - - headerEditor.add(Byte.TYPE, new ByteEditor(ParamEditor.TYPE_HEADER,true)); - headerEditor.add(Long.TYPE, new LongEditor(ParamEditor.TYPE_HEADER, true)); - headerEditor.add(Double.TYPE, new DoubleEditor(ParamEditor.TYPE_HEADER, true)); - headerEditor.add(Float.TYPE, new FloatEditor(ParamEditor.TYPE_HEADER, true)); - headerEditor.add(Short.TYPE, new ShortEditor(ParamEditor.TYPE_HEADER, true)); - headerEditor.add(Integer.TYPE, new IntegerEditor(ParamEditor.TYPE_HEADER, true)); - headerEditor.add(Boolean.TYPE, new BooleanEditor(ParamEditor.TYPE_HEADER, true)); - headerEditor.add(Character.TYPE,new CharEditor(ParamEditor.TYPE_HEADER, true)); - - headerEditor.add(Byte.class, new ByteEditor(ParamEditor.TYPE_HEADER, false)); - headerEditor.add(Long.class, new LongEditor(ParamEditor.TYPE_HEADER, false)); - headerEditor.add(Double.class, new DoubleEditor(ParamEditor.TYPE_HEADER,false)); - headerEditor.add(Float.class, new FloatEditor(ParamEditor.TYPE_HEADER,false)); - headerEditor.add(Short.class, new ShortEditor(ParamEditor.TYPE_HEADER,false)); - headerEditor.add(Integer.class, new IntegerEditor(ParamEditor.TYPE_HEADER,false)); - headerEditor.add(Boolean.class, new BooleanEditor(ParamEditor.TYPE_HEADER,false)); - } - - public void bindParam(Class type, IEditor editor) { - paramEditor.add(type, editor); - } - - public void bindBody(Class type, IEditor editor) { - bodyEditor.add(type, editor); - } - - /** - * 绑定自定义参数读取器 - * @param bindType 绑定类型ParamEditor.TYPE_XXX - * @param type 参数类型 - * @param editor 参数读取器 - */ - public void bind(int bindType, Class type, IEditor editor) { - switch (bindType) { - case ParamEditor.TYPE_PARAM: - paramEditor.add(type, editor); - break; - case ParamEditor.TYPE_BODY: - // @SwBody - bodyEditor.add(type, editor); - break; - case ParamEditor.TYPE_PATH: - pathEditor.add(type, editor); - break; - case ParamEditor.TYPE_HEADER: - headerEditor.add(type, editor);; - break; - case ParamEditor.TYPE_ATTR: - attributeEditor.add(type, editor); - break; - default: - throw new IllegalStateException("Unexpected type value: " + bindType); - } - } - - /** - * 绑定默认自定义参数读取器 - * @param bindType 绑定类型ParamEditor.TYPE_XXX - * @param editor 默认参数读取器 - */ - public void bindDefault(int bindType, IEditor editor) { - switch (bindType) { - case ParamEditor.TYPE_PARAM: - paramEditor.setDefaultEditor(editor); - break; - case ParamEditor.TYPE_BODY: - // @SwBody - bodyEditor.setDefaultEditor(editor); - break; - case ParamEditor.TYPE_PATH: - pathEditor.setDefaultEditor(editor); - break; - case ParamEditor.TYPE_HEADER: - headerEditor.setDefaultEditor(editor);; - break; - case ParamEditor.TYPE_ATTR: - attributeEditor.setDefaultEditor(editor); - break; - default: - throw new IllegalStateException("Unexpected type value: " + bindType); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/attr/AbstractAttrEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/attr/AbstractAttrEditor.java deleted file mode 100644 index e28d213..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/attr/AbstractAttrEditor.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.attr; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -/** - * API函数@SwBody参数的转换处理,POST请求直接转换Json内容为Bean对象,GET请求转换Map请求参数为Bean对 - * @author xkliu - */ -public abstract class AbstractAttrEditor implements IEditor { - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - return getValue(paramName, paramType, request); - } - - public abstract Object getValue(String paramName, Class paramType, HttpServletRequest request); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/attr/BeanAttrEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/attr/BeanAttrEditor.java deleted file mode 100644 index fc6058f..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/attr/BeanAttrEditor.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.attr; - -import javax.servlet.http.HttpServletRequest; - -/** - * API函数@SwBody参数的转换处理,POST请求直接转换Json内容为Bean对象,GET请求转换Map请求参数为Bean对 - * @author xkliu - */ -public class BeanAttrEditor extends AbstractAttrEditor { - @Override - public Object getValue(String paramName, Class paramType, HttpServletRequest request) { - return request.getAttribute(paramName); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/AbstractContextEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/AbstractContextEditor.java deleted file mode 100644 index 1187721..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/AbstractContextEditor.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.bean; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -public abstract class AbstractContextEditor implements IEditor { - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - return getValue(paramName, paramType, context); - } - - protected abstract Object getValue(String paramName, Class paramType, IBeanContext context); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/BeanEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/BeanEditor.java deleted file mode 100644 index 399673a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/BeanEditor.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.bean; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import org.apache.commons.lang3.StringUtils; - -public class BeanEditor extends AbstractContextEditor { - @Override - public Object getValue(String paramName, Class paramType, IBeanContext context) { - if (StringUtils.isBlank(paramName)) { - return context.getBean(paramType); - } else { - return context.getBean(paramName, paramType); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/HttpServletRequestEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/HttpServletRequestEditor.java deleted file mode 100644 index 3cdbfa2..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/HttpServletRequestEditor.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.bean; - -import cc.smtweb.framework.core.mvc.controller.binder.param.AbstractRequestEditor; - -import javax.servlet.http.HttpServletRequest; - -public class HttpServletRequestEditor extends AbstractRequestEditor { - @Override - public Object getValue(HttpServletRequest request) { - return request; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/NullEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/NullEditor.java deleted file mode 100644 index c791f97..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/NullEditor.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.bean; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -public class NullEditor implements IEditor { - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - return null; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/SwIpAddrEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/SwIpAddrEditor.java deleted file mode 100644 index 8329f39..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/SwIpAddrEditor.java +++ /dev/null @@ -1,34 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.bean; - -import cc.smtweb.framework.core.mvc.controller.binder.param.AbstractRequestEditor; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; - -/*** - * 获取客户端IP地址;这里通过了Nginx获取;X-Real-IP - */ -public class SwIpAddrEditor extends AbstractRequestEditor { - @Override - public Object getValue(HttpServletRequest request) { - String ip = request.getHeader("X-Real-IP"); - - if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("X-Forwarded-For"); - } - - if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("Proxy-Client-IP"); - } - - if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("WL-Proxy-Client-IP"); - } - - if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { - ip = request.getRemoteAddr(); - } - - return ip; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/UserSessionEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/UserSessionEditor.java deleted file mode 100644 index 3478ebb..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/bean/UserSessionEditor.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.bean; - -import cc.smtweb.framework.core.mvc.controller.binder.param.AbstractRequestEditor; -import cc.smtweb.framework.core.session.SessionUtil; - -import javax.servlet.http.HttpServletRequest; - -public class UserSessionEditor extends AbstractRequestEditor { - @Override - public Object getValue(HttpServletRequest request) { - return SessionUtil.getSession(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/BeanBodyEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/BeanBodyEditor.java deleted file mode 100644 index e950924..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/BeanBodyEditor.java +++ /dev/null @@ -1,82 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.body; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.exception.BindBeanException; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import cc.smtweb.framework.core.util.JsonUtil; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -/** - * API函数@SwBody参数的转换处理,POST请求直接转换Json内容为Bean对象,GET请求转换Map请求参数为Bean对 - * @author xkliu - */ -public class BeanBodyEditor implements IEditor { - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - if (paramName != null) { - Object map = request.getAttribute(BODY_MAP); - if (map != null) { - return getFieldValue((SwMap) map, paramName, paramType); - } - } - - if (body != null) { - return getPostValue(paramName, paramType, body, request); - } else { - return getGetValue(paramName, paramType, params); - } - } - - private Object getGetValue(String paramName, Class paramType, Map params) { - if (paramName == null) { - return JsonUtil.parse(params, paramType); - } - - // Json字符进行类型转化 - Object result = params.get(paramName); - if (result == null) { - return null; - } - - if (paramType.isAssignableFrom(result.getClass())) { - return result; - } - - throw new BindBeanException("传入的 @SwBody(" + paramName + ") " + paramType.getName() + "类型不一致! " + result.getClass().getName()); - } - - private Object getPostValue(String paramName, Class paramType, String body, HttpServletRequest request) { - if (body == null || StringUtils.isBlank(body)) { - return null; - } - - if (paramName == null) { - return JsonUtil.parse(body, paramType); - } else { - SwMap map = JsonUtil.parse(body, SwMap.class); - if (map != null) { - request.setAttribute(BODY_MAP, map); - return getFieldValue(map, paramName, paramType); - } - - return null; - } - } - - private Object getFieldValue(SwMap result, String paramName, Class paramType) { - Object value = result.get(paramName); - if (value == null) { - return null; - } - - if (value instanceof Map) { - return BeanUtil.toBean((Map)value, paramType); - } - - throw new BindBeanException("传入的 @SwBody(" + paramName + ") 值非Object类型! " + value.getClass().getName()); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/BeanUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/BeanUtil.java deleted file mode 100644 index 641492a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/BeanUtil.java +++ /dev/null @@ -1,160 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.body; - -import cc.smtweb.framework.core.common.SwMap; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.FatalBeanException; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -import java.beans.PropertyDescriptor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.sql.Timestamp; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -public class BeanUtil { - private static final Set> simpleType = new HashSet<>(); - - static { - simpleType.add(String.class); - simpleType.add(Timestamp.class); - simpleType.add(java.util.Date.class); - simpleType.add(java.sql.Date.class); - simpleType.add(java.sql.Time.class); - - simpleType.add(Byte.TYPE); - simpleType.add(Long.TYPE); - simpleType.add(Double.TYPE); - simpleType.add(Float.TYPE); - simpleType.add(Short.TYPE); - simpleType.add(Integer.TYPE); - simpleType.add(Boolean.TYPE); - simpleType.add(Character.TYPE); - - simpleType.add(Byte.class); - simpleType.add(Long.class); - simpleType.add(Double.class); - simpleType.add(Float.class); - simpleType.add(Short.class); - simpleType.add(Integer.class); - simpleType.add(Boolean.class); - } - - private BeanUtil() {} - - public static Object toBean(Map source, Class clazz) { - Object target = null; - try { - target = clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new FatalBeanException( - "Could not copy property '" + clazz.getName() + "' from source to target", e); - } - mapToBean(source, target); - return target; - } - - private static void mapToBean(Map source, Object target) { - mapToBean(source, target, true); - } - - private static void mapToBean(Map source, Object target, boolean root) throws BeansException { - Assert.notNull(source, "Source must not be null"); - Assert.notNull(target, "Target must not be null"); - - Class actualEditable = target.getClass(); -// if (editable != null) { -// if (!editable.isInstance(target)) { -// throw new IllegalArgumentException("Target class [" + target.getClass().getName() + -// "] not assignable to Editable class [" + editable.getName() + "]"); -// } -// actualEditable = editable; -// } - PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable); - - for (PropertyDescriptor targetPd : targetPds) { - Method writeMethod = targetPd.getWriteMethod(); - Object value = source.get(targetPd.getName()); - - if (value == null) { - Class parameterType = writeMethod.getParameterTypes()[0]; - - if (ClassUtils.isAssignable(parameterType, value.getClass())) { - writeBeanValue(target, targetPd, writeMethod, value); - } else { - if (root && value instanceof Map) { - Object propValue; - try { - propValue = parameterType.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new FatalBeanException( - "Could not copy property '" + targetPd.getName() + "' from source to target", e); - } - - mapToBean((Map) value, propValue, false); - writeBeanValue(target, targetPd, writeMethod, propValue); - } - } - } - } - } - - private static void writeBeanValue(Object target, PropertyDescriptor targetPd, Method writeMethod, Object value) { - try { - if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { - writeMethod.setAccessible(true); - } - writeMethod.invoke(target, value); - } catch (Throwable ex) { - throw new FatalBeanException( - "Could not copy property '" + targetPd.getName() + "' from source to target", ex); - } - } - - public static void beanToMap(Object source, SwMap target) throws BeansException { - beanToMap(source, target, true); - } - - public static void beanToMap(Object source, SwMap target, boolean root) throws BeansException { - Assert.notNull(source, "Source must not be null"); - Assert.notNull(target, "Target must not be null"); - PropertyDescriptor[] sourcePds = BeanUtils.getPropertyDescriptors(source.getClass()); - - for (PropertyDescriptor sourcePd: sourcePds) { -// PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getKey()); -// if (sourcePd != null) { - Method readMethod = sourcePd.getReadMethod(); - if (readMethod != null) { - try { - if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { - readMethod.setAccessible(true); - } - Object value = readMethod.invoke(source); - target.put(sourcePd.getName(), root ? toMapValue(value) : value); - } - catch (Throwable ex) { - throw new FatalBeanException( - "Could not copy property '" + sourcePd.getName() + "' from source to target", ex); - } - } -// } - } - } - - private static Object toMapValue(Object value) { - if (value != null && isBeanType(value.getClass())) { - SwMap mapValue = new SwMap(); - beanToMap(value, mapValue, false); - return mapValue; - } - - return value; - } - - private static boolean isBeanType(Class type) { - return !simpleType.contains(type); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/StringBodyEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/StringBodyEditor.java deleted file mode 100644 index 9de8a32..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/StringBodyEditor.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.body; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -/** - * API函数@SwBody参数的转换处理,直接获取POST请求文本内容 - * @author xkliu - */ -public class StringBodyEditor implements IEditor { - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - return body; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java deleted file mode 100644 index ca550c6..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java +++ /dev/null @@ -1,69 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.body; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.exception.BindBeanException; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import cc.smtweb.framework.core.util.JsonUtil; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -/** - * API函数@SwBody参数的转换处理,POST请求直接转换Json内容为Bean对象,GET请求转换Map请求参数为Bean对 - * @author xkliu - */ -public class SwMapBodyEditor implements IEditor { - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - Object map = request.getAttribute(BODY_MAP); - if (map != null) { - return getFieldValue((SwMap)map, paramName); - } - - if (body != null) { - return getPostValue(paramName, paramType, body, request); - } else { - return getGetValue(paramName, paramType, params, request); - } - } - - private Object getGetValue(String paramName, Class paramType, Map params, HttpServletRequest request) { - SwMap result = JsonUtil.parse(params, SwMap.class); - request.setAttribute(BODY_MAP, result); - return getFieldValue(result, paramName); - } - - private Object getPostValue(String paramName, Class paramType, String body, HttpServletRequest request) { - if (body == null || StringUtils.isBlank(body)) { - return null; - } - - SwMap result = JsonUtil.parse(body, SwMap.class); - request.setAttribute(BODY_MAP, result); - return getFieldValue(result, paramName); - } - - private Object getFieldValue(SwMap result, String paramName) { - if (paramName != null) { - Object value = result.get(paramName); - if (value == null) { - return null; - } - - if (value instanceof Map) { - SwMap map = new SwMap(); - ((Map) value).forEach((k, v) -> { - map.put(k.toString(), v); - }); - return map; - } - - throw new BindBeanException("传入的 @SwBody(" + paramName + ") 值非MAP类型! " + value.getClass().getName()); - } - - return result; - } - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractNumberEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractNumberEditor.java deleted file mode 100644 index 24d2feb..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractNumberEditor.java +++ /dev/null @@ -1,46 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import org.apache.commons.lang3.StringUtils; - - -/** - * 字符串到Number类型的转换 - * - * @author kevin - * - */ -public abstract class AbstractNumberEditor extends AbstractParameterEditor { - protected boolean automicType; - - public AbstractNumberEditor(int paramEditType, boolean automicType) { - super(paramEditType); - this.automicType = automicType; - } - - @Override - protected Object parseText(Object value) { - Object result = null; - - if (value == null) { - return automicType ? defaultValue() : null; - } - - if (value instanceof Number) { - return convert((Number)value); - } - - String text = value.toString(); - - if (StringUtils.isNotBlank(text)) { - result = getValue(text); - } else { - result = automicType ? defaultValue() : null; - } - - return result; - } - - protected abstract Object convert(Number value); - protected abstract Object getValue(String text); - protected abstract Object defaultValue(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractParameterEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractParameterEditor.java deleted file mode 100644 index db51dba..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractParameterEditor.java +++ /dev/null @@ -1,109 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import cc.smtweb.framework.core.mvc.controller.binder.ParamEditor; -import cc.smtweb.framework.core.util.JsonUtil; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; - -/** - * 字符串参数到对象的转换; - * @author xkliu - */ -public abstract class AbstractParameterEditor implements IEditor { - private static final IEditorValue paramValue = (paramName, params, body, request) -> params.get(paramName); - private static final IEditorValue headerValue = (paramName, params, body, request) -> request.getHeader(paramName); - private static final IEditorValue bodyValue = (paramName, params, body, request) -> { - if (body == null) { - if (paramName != null) { - return params.get(paramName); - } - } else { - SwMap map = (SwMap) request.getAttribute(BODY_MAP); - if (map != null) { - return map.get(paramName); - } - - map = JsonUtil.parse(body, SwMap.class); - if (map != null) { - request.setAttribute(BODY_MAP, map); - return map.get(paramName); - } - } - - return null; - }; - - private final IEditorValue editorValue; - -// AbstractParameterEditor() { -// editorValue = paramValue; -// } - - AbstractParameterEditor(int paramEditorType) { - switch (paramEditorType) { - case ParamEditor.TYPE_HEADER: - editorValue = headerValue; - break; - case ParamEditor.TYPE_PARAM: - editorValue = paramValue; - break; - case ParamEditor.TYPE_BODY: - editorValue = bodyValue; - break; - default: - throw new UnsupportedOperationException("not implement type: " + paramEditorType); - } - } - - protected static Date parseDateTime(String text) throws ParseException { - DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - df.setLenient(false); - - return df.parse(text); - } - - protected static Date parseShortDateTime(String text) throws ParseException { - DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); - df.setLenient(false); - - return df.parse(text); - } - - protected static Date parseDate(String text) throws ParseException { - DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); - df.setLenient(false); - - return df.parse(text); - } - - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - if (StringUtils.isBlank(paramName)) { - return null; - } - - return parseText(editorValue.getValue(paramName, params, body, request)); - } - - protected abstract Object parseText(Object text); -} - -interface IEditorValue { - /** - * 获取参数值 - * @param paramName 参数名 - * @param params HTTP请求参数集合 - * @param request HTTP请求对象 - * @return 参数值 - */ - Object getValue(String paramName, Map params, String body, HttpServletRequest request); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractRequestEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractRequestEditor.java deleted file mode 100644 index eb17731..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/AbstractRequestEditor.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -public abstract class AbstractRequestEditor implements IEditor { - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - return getValue(request); - } - - protected abstract Object getValue(HttpServletRequest request); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BeanTypeEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BeanTypeEditor.java deleted file mode 100644 index b96da02..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BeanTypeEditor.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.IEditor; - -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - -public class BeanTypeEditor implements IEditor { - @Override - public Object getParamValue(String paramName, Class paramType, IBeanContext context, Map params, String body, HttpServletRequest request) { - return params.get(paramType.getName()); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BooleanEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BooleanEditor.java deleted file mode 100644 index 30572c0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/BooleanEditor.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import org.apache.commons.lang3.StringUtils; - -public class BooleanEditor extends AbstractParameterEditor { - private final boolean automicType; - - public BooleanEditor(int header, boolean automicType) { - super(header); - this.automicType = automicType; - } - - @Override - public Object parseText(Object text) { - if (text == null) { - return automicType ? Boolean.FALSE : null; - } - - if (text instanceof Boolean) { - return text; - } - - String s = text.toString(); - if (StringUtils.isBlank(s)) { - return automicType ? Boolean.FALSE : null; - } - - return Boolean.valueOf(s); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ByteEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ByteEditor.java deleted file mode 100644 index fd3a27e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ByteEditor.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -public class ByteEditor extends AbstractNumberEditor { - private static final Byte BYTE_ZERO = 0; - - public ByteEditor(int header, boolean automicType) { - super(header, automicType); - } - - @Override - protected Object convert(Number value) { - return value.byteValue(); - } - - @Override - protected Object getValue(String text) { - return Byte.valueOf(text); - } - - @Override - protected Object defaultValue() { - return BYTE_ZERO; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/CharEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/CharEditor.java deleted file mode 100644 index a723b20..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/CharEditor.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import org.apache.commons.lang3.StringUtils; - - -public class CharEditor extends AbstractParameterEditor { - private static final char CHAR_ZERO = '\u0000'; - private final boolean automicType; - - public CharEditor(int header, boolean automicType) { - super(header); - this.automicType = automicType; - } - - @Override - protected Object parseText(Object value) { - if (value == null) { - return automicType ? CHAR_ZERO : null; - } - - String text = value.toString(); - - if(StringUtils.isBlank(text)){ - return automicType ? CHAR_ZERO : null; - } - - return text.charAt(0); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DateEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DateEditor.java deleted file mode 100644 index 8f49da3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DateEditor.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import cc.smtweb.framework.core.exception.BindParamException; -import org.apache.commons.lang3.StringUtils; - -import java.text.ParseException; -import java.util.Date; - -public class DateEditor extends AbstractParameterEditor { - public DateEditor(int header) { - super(header); - } - - @Override - protected Object parseText(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Date) { - return new java.sql.Date(((Date) value).getTime()); - } - - String text = value.toString(); - if (StringUtils.isBlank(text)) { - return null; - } - - Object result = null; - - if (StringUtils.isNotBlank(text)) { - text = text.trim(); - - if ("null".equals(text)) { - return null; - } else { - int pos = text.indexOf(' '); - if (pos > 0) { - text = text.substring(0, pos); - } - - try { - result = new java.sql.Date(parseDate(text).getTime()); - } catch (ParseException e) { - throw new BindParamException(e); - } - } - - } - - return result; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DoubleEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DoubleEditor.java deleted file mode 100644 index 8b8d7d9..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/DoubleEditor.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - - -public class DoubleEditor extends AbstractNumberEditor { - private static final Double DOUBLE_ZERO = 0.0d; - - public DoubleEditor(int header, boolean automicType) { - super(header, automicType); - } - - @Override - protected Object convert(Number value) { - return value.doubleValue(); - } - - @Override - protected Object getValue(String text) { - return Double.valueOf(text); - } - - @Override - protected Object defaultValue() { - return DOUBLE_ZERO; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/FloatEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/FloatEditor.java deleted file mode 100644 index c6cfe12..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/FloatEditor.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - - -public class FloatEditor extends AbstractNumberEditor { - private static final Float FLOAT_ZERO = 0.0f; - - public FloatEditor(int header, boolean automicType) { - super(header, automicType); - } - - @Override - protected Object convert(Number value) { - return value.floatValue(); - } - - @Override - protected Object getValue(String text) { - return Float.valueOf(text); - } - - @Override - protected Object defaultValue() { - return FLOAT_ZERO; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/IntegerEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/IntegerEditor.java deleted file mode 100644 index e3666e2..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/IntegerEditor.java +++ /dev/null @@ -1,24 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -public class IntegerEditor extends AbstractNumberEditor { - private static final Integer INT_ZERO = 0; - - public IntegerEditor(int header, boolean automicType) { - super(header, automicType); - } - - @Override - protected Object convert(Number value) { - return value.intValue(); - } - - @Override - protected Object getValue(String text) { - return Integer.valueOf(text); - } - - @Override - protected Object defaultValue() { - return INT_ZERO; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/LongEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/LongEditor.java deleted file mode 100644 index 359cc0b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/LongEditor.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - - -public class LongEditor extends AbstractNumberEditor { - private static final Long LONG_ZERO = 0L; - - public LongEditor(int header, boolean automicType) { - super(header, automicType); - } - - @Override - protected Object convert(Number value) { - return value.longValue(); - } - - @Override - protected Object getValue(String text) { - return Long.valueOf(text); - } - - @Override - protected Object defaultValue() { - return LONG_ZERO; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ShortEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ShortEditor.java deleted file mode 100644 index 5587c17..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/ShortEditor.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - - -public class ShortEditor extends AbstractNumberEditor { - private static final Short SHORT_ZERO = 0; - - public ShortEditor(int header, boolean automicType) { - super(header, automicType); - } - - @Override - protected Object convert(Number value) { - return value.shortValue(); - } - - @Override - protected Object getValue(String text) { - return Short.valueOf(text); - } - - @Override - protected Object defaultValue() { - return SHORT_ZERO; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/StringEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/StringEditor.java deleted file mode 100644 index c6f7e69..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/StringEditor.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - - -public class StringEditor extends AbstractParameterEditor { - public StringEditor(int header) { - super(header); - } - - @Override - protected Object parseText(Object text) { - if (text == null) { - return text; - } - - return text.toString(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimeEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimeEditor.java deleted file mode 100644 index 5377898..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimeEditor.java +++ /dev/null @@ -1,35 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import cc.smtweb.framework.core.exception.BindParamException; -import org.apache.commons.lang3.StringUtils; - -import java.text.ParseException; -import java.util.Date; - -public class TimeEditor extends AbstractParameterEditor { - public TimeEditor(int header) { - super(header); - } - - @Override - public Object parseText(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Date) { - return new java.sql.Time(((Date) value).getTime()); - } - - String text = value.toString(); - if (StringUtils.isBlank(text)) { - return null; - } - - try { - return new java.sql.Time(parseDateTime(text).getTime()); - } catch (ParseException e) { - throw new BindParamException(e); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimestampEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimestampEditor.java deleted file mode 100644 index 44141bf..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/param/TimestampEditor.java +++ /dev/null @@ -1,57 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.param; - -import cc.smtweb.framework.core.exception.BindParamException; -import org.apache.commons.lang3.StringUtils; - -import java.sql.Timestamp; -import java.text.ParseException; -import java.util.Date; - -public class TimestampEditor extends AbstractParameterEditor { - public TimestampEditor(int header) { - super(header); - } - - @Override - public Object parseText(Object value) throws IllegalArgumentException { - if (value == null) { - return null; - } - - if (value instanceof Date) { - return new Timestamp(((Date) value).getTime()); - } - - String text = value.toString(); - if (StringUtils.isBlank(text)) { - return null; - } - - text = text.trim(); - - if ("null".equals(text)) { - return null; - } - - Timestamp result = null; - - try { - int pos = text.indexOf(':'); - if (pos < 0 && text.indexOf("-") < 0) { - result = new Timestamp(Long.parseLong(text)); - } else if (text.length() > 10) { - if (text.indexOf(':', pos + 1) > pos) { - result = new Timestamp(parseDateTime(text).getTime()); - } else { - result = new Timestamp(parseDateTime(text).getTime()); - } - } else { - result = new Timestamp(parseDateTime(text).getTime()); - } - } catch (ParseException ex) { - throw new BindParamException(ex); - } - - return result; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/path/PathParamEditor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/path/PathParamEditor.java deleted file mode 100644 index cb42ef7..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/path/PathParamEditor.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.binder.path; - -import cc.smtweb.framework.core.mvc.controller.binder.param.AbstractRequestEditor; - -import javax.servlet.http.HttpServletRequest; - -public class PathParamEditor extends AbstractRequestEditor { - public final static String ATTR_KEY = "SMTWEB_PATH"; - - @Override - public Object getValue(HttpServletRequest request) { - return request.getAttribute(ATTR_KEY); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ApplicationScanner.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ApplicationScanner.java deleted file mode 100644 index 34ac3e3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ApplicationScanner.java +++ /dev/null @@ -1,73 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.cache.ISwCache; -import cc.smtweb.framework.core.mvc.config.ControllerConfig; -import cc.smtweb.framework.core.mvc.controller.ApiConfigBean; -import cc.smtweb.framework.core.mvc.controller.MethodAccessManager; -import cc.smtweb.framework.core.mvc.controller.binder.CacheEditor; -import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.ConfigurableApplicationContext; - -import java.util.ArrayList; -import java.util.List; - -/** - * 微服务API扫描,扫描生成api接口实现放入methodAccessManager - * - * @author xkliu - */ -@Slf4j -public class ApplicationScanner { - public static void scan(ConfigurableApplicationContext applicationContext) throws Exception { - MethodAccessManager methodAccessManager = applicationContext.getBean(MethodAccessManager.class); - BeanManager beanManager = BeanManager.getInstance(); - beanManager.install(applicationContext); - - String[] names = applicationContext.getBeanNamesForType(ControllerConfig.class); - if (names != null) { - WebDataBinder webDataBinder = new WebDataBinder(new CacheEditor(methodAccessManager.getCacheManager())); - ApiConfigBean apiConfig = applicationContext.getBean(ApiConfigBean.class); - List controllerConfigs = new ArrayList<>(); - - ScanContext scanContext = new ScanContext(beanManager, webDataBinder); - - for (String name : names) { - ControllerConfig controllerConfig = applicationContext.getBean(name, ControllerConfig.class); - controllerConfigs.add(controllerConfig); - - // 先注册自定义注解解析器 - IScanActionBuilder scanActionBuilder = controllerConfig.getScanActionBuilder(); - if (scanActionBuilder != null) { - scanContext.addScanAction(scanActionBuilder.build(applicationContext, webDataBinder)); - } - } - - for (ControllerConfig controllerConfig : controllerConfigs) { - scanContext.setModule(controllerConfig.getModule()); - log.info("[/api/{}/*]start scan {}", controllerConfig.getModule(), controllerConfig.getPackagePath()); - - // 扫描 Service 类 - PackageScanner packageScanner = new PackageScanner( - new ClassParser(new UrlMaker(apiConfig, controllerConfig.getModule()), scanContext)); - packageScanner.scan(controllerConfig.getPackagePath()); - } - - // 单例进行实例化,并设置实例的field(@SwParam),关联扩展的action(@SwAction)到方法执行器 - beanManager.init(); - - log.info("[smt] scan ok."); - } - - // 处理权限管理和启动定时任务 - AbstractCache realmCache = CacheManager.getIntance().getCache(ISwCache.REALM_CACHE); - - if (realmCache == null) { - log.error("not find RealmCache"); - } - - methodAccessManager.init(beanManager, realmCache); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/BeanManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/BeanManager.java deleted file mode 100644 index 20adc64..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/BeanManager.java +++ /dev/null @@ -1,161 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import cc.smtweb.framework.core.mvc.controller.IActionManager; -import cc.smtweb.framework.core.mvc.controller.access.ControllerAccess; -import cc.smtweb.framework.core.mvc.controller.access.IMethodAccess; -import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; -import cc.smtweb.framework.core.mvc.controller.access.SchedulerMethodAccess; -import cc.smtweb.framework.core.mvc.controller.binder.BeanContext; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.ApplicationContext; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Slf4j -public class BeanManager implements IActionManager { - private ApplicationContext applicationContext; - private List beans = new ArrayList<>(); - private Map, Object> beanMap = new HashMap<>(); - private List singletonServices = new ArrayList<>(); - @Getter - private Map controllers = new HashMap<>(); - @Getter - private BeanContext beanContext; - @Getter - private List tasks = new ArrayList<>(); - - private List constructMethods = new ArrayList<>(); - private List destroyMethods = new ArrayList<>(); - private List beanMethods = new ArrayList<>(); - - private Map> mapTableClass = new HashMap<>(); - - private static BeanManager instance = null; - static { - instance = new BeanManager(); - } - - public static BeanManager getInstance() { - return instance; - } - - private BeanManager() { - } - - public void install(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - beanContext = new BeanContext(beanMap, applicationContext); - } - - public void init() throws Exception { - // 读取DbEngine,用以初始化 EntityDao - beanContext.init(); - - // 自动设置@SwBean注解对象的@SwParam注解属性 - for (ControllerAccess controllerAccess: beans) { - Object bean = controllerAccess.getSingletonInstance(); - addBeanMap(controllerAccess.getBeanType(), bean); - } - - // 映射单例Bean字段值 - for (ControllerAccess controllerAccess: beans) { - controllerAccess.initSingletonFields(beanContext, null); - } - - for (IMethodAccess methodAccess: beanMethods) { - Object bean = methodAccess.invoke(beanContext); - addBeanMap(methodAccess.getReturnType(), bean); - log.debug("[smt]init bean:" + methodAccess.getReturnType() + " by " + methodAccess.fullName()); - } - - // 映射单例控制器字段值 - for (ControllerAccess controllerAccess: singletonServices) { - controllerAccess.initSingletonFields(beanContext, null); - } - - // 执行初始化方法 - constructMethods.sort((a, b) -> a.order - b.order); - - for (OrderMethodAccess orderMethodAccess: constructMethods) { - IMethodAccess methodAccess = orderMethodAccess.methodAccess; - methodAccess.invoke(beanContext); - } - } - - private void addBeanMap(Class beanType, Object bean) { - if (bean != null) { - beanMap.put(beanType, bean); - } - } - - IMethodAccess putIfAbsent(String url, IMethodAccess methodAccess) { - return controllers.putIfAbsent(url, methodAccess); - } - - void addBean(ControllerAccess controllerAccess) { - this.beans.add(controllerAccess); - } - - void addSingletonController(ControllerAccess controllerAccess) { - this.singletonServices.add(controllerAccess); - } - - void addTask(SchedulerMethodAccess schedulerMethodAccess) { - this.tasks.add(schedulerMethodAccess); - } - - void addConstruct(int order, MethodAccess methodAccess) { - constructMethods.add(new OrderMethodAccess(order, methodAccess)); - } - - void addDestroy(int order, MethodAccess methodAccess) { - destroyMethods.add(new OrderMethodAccess(order, methodAccess)); - } - - public MethodAccess[] loadDestroyMethods() { - if (destroyMethods.isEmpty()) { - return null; - } - - destroyMethods.sort((a, b) -> b.order - a.order); - - int size = destroyMethods.size(); - MethodAccess[] result = new MethodAccess[size]; - for (int i = 0; i < size; i++) { - result[i] = destroyMethods.get(i).methodAccess; - } - - return result; - } - - void addBeanMethod(IMethodAccess methodAccess) { - this.beanMethods.add(methodAccess); - } - - @Override - public boolean api(String url, IMethodAccess methodAccess) { - return this.putIfAbsent(url, methodAccess) == null; - } - - public void addTableClass(String tableName, Class clzz) { - mapTableClass.put(tableName, clzz); - } - - public Class getTableClass(String tableName) { - return mapTableClass.get(tableName); - } - - private static class OrderMethodAccess { - private final int order; - private final MethodAccess methodAccess; - - OrderMethodAccess(int order, MethodAccess methodAccess) { - this.order = order; - this.methodAccess = methodAccess; - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ClassParser.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ClassParser.java deleted file mode 100644 index 84db2a4..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ClassParser.java +++ /dev/null @@ -1,173 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import cc.smtweb.framework.core.annotation.*; -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import cc.smtweb.framework.core.mvc.controller.access.BindFieldAccess; -import cc.smtweb.framework.core.mvc.controller.access.ControllerAccess; -import cc.smtweb.framework.core.mvc.controller.access.FieldAccess; -import cc.smtweb.framework.core.mvc.controller.access.SingletonFieldAccess; -import cc.smtweb.framework.core.mvc.controller.binder.ParamEditor; -import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections.collection.SynchronizedCollection; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -@Slf4j -public class ClassParser { - private BeanManager beanManager; - private UrlMaker urlMaker; - private WebDataBinder webDataBinder; - private ScanContext scanContext; - private Field singletonField; - private boolean singleton; - // private List cacheList; - private MethodParser methodParser; - private List> threadSafeTypes = new ArrayList<>(); - private DbEngine dbEngine; - - public ClassParser(UrlMaker urlMaker, ScanContext scanContext) { - this.urlMaker = urlMaker; - this.scanContext = scanContext; - this.beanManager = scanContext.getBeanManager(); -// this.cacheList = cacheList; - this.webDataBinder = scanContext.getWebDataBinder(); - this.methodParser = new MethodParser(urlMaker, scanContext); - this.dbEngine = beanManager.getBeanContext().getBean(DbEngine.class); - - threadSafeTypes.add(AtomicBoolean.class); - threadSafeTypes.add(AtomicInteger.class); - threadSafeTypes.add(AtomicLong.class); - threadSafeTypes.add(SynchronizedCollection.class); - threadSafeTypes.add(ConcurrentMap.class); - } - - public void parse(String dirName, Class clazz) throws InstantiationException, IllegalAccessException, ParseException { - SwBean swBean = clazz.getAnnotation(SwBean.class); - - // TODO ISwCache.class.isAssignableFrom(clazz) - if (swBean != null) { - ControllerAccess controllerAccess = buildControllerAccess(clazz, swBean.alwaysCreate()); - if (controllerAccess.isSingleton()) { - controllerAccess.newSingletonInstance(); - log.debug("[smt]init bean: " + clazz.getName()); - beanManager.addBean(controllerAccess); - - methodParser.parse(clazz, controllerAccess, false); - } else { - log.error(clazz.getName() + " must be singleton, can not use field: " + singletonField.getName()); - } - return; - } - - SwService swService = clazz.getAnnotation(SwService.class); - if (swService != null) { - urlMaker.setServiceUrl(swService.value()); - log.debug("[smt]init service: " + clazz.getName()); - //Service类,非单例,以免多线程并发相互干扰 - ControllerAccess controllerAccess = buildControllerAccess(clazz, false); - if (controllerAccess.isSingleton()) { - controllerAccess.newSingletonInstance(); - beanManager.addSingletonController(controllerAccess); - } - - // 处理url路径 - methodParser.parse(clazz, controllerAccess, true); - return; - } - - SwCache swCache = clazz.getAnnotation(SwCache.class); - if (swCache != null) { - CacheManager cacheManager = CacheManager.getIntance(); - cacheManager.install((AbstractCache) clazz.newInstance()); - return; - } - - SwTable swTable = clazz.getAnnotation(SwTable.class); - if (swTable != null) { - beanManager.addTableClass(swTable.value(), clazz); - } - } - - private ControllerAccess buildControllerAccess(Class clazz, boolean alwaysCreate) { - List fieldList = new ArrayList<>(); - singleton = true; - singletonField = null; - // 扫描本类和父类的 field - Class parentClazz = clazz; - - // !parentClazz.equals(stopClazz) - while (parentClazz != null && !parentClazz.isInterface()) { - parseFields(parentClazz, fieldList); - parentClazz = parentClazz.getSuperclass(); - } - - return new ControllerAccess(clazz, fieldList, alwaysCreate || singleton); - } - - private void parseFields(Class clazz, List fieldList) { - Field[] fields = clazz.getDeclaredFields(); - for (Field field : fields) { - FieldAccess fieldAccess = parseField(field); - - if (fieldAccess != null) { - fieldList.add(fieldAccess); - } - } - } - - private FieldAccess parseField(Field field) { - // 得到属性上的注解 - SwParam swParam = field.getAnnotation(SwParam.class); - - if (swParam != null) { - if (Object.class.equals(swParam.type())) { - IEditor editor = webDataBinder.findEditor(field.getType(), ParamEditor.TYPE_FIELD); - return new BindFieldAccess(editor, field, swParam.value()); - } else { - EntityDao entityDao = dbEngine.findDao(swParam.type()); - return new SingletonFieldAccess(entityDao, field); - } - } else { - if (singleton) { - if (!isConstance(field) && !isThreadSafe(field)) { - // 记录首个发现的线程不安全字段 - singletonField = field; - singleton = false; - } - } - } - - return null; - } - - private static boolean isConstance(Field field) { - int fieldModifiers = field.getModifiers(); - return Modifier.isStatic(fieldModifiers) && Modifier.isFinal(fieldModifiers); - } - - private boolean isThreadSafe(Field field) { - Class fieldType = field.getDeclaringClass(); - for (Class type : threadSafeTypes) { - if (type.isAssignableFrom(fieldType)) { - return true; - } - } - - return false; - } - -} - diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanAction.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanAction.java deleted file mode 100644 index 798fc2e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import cc.smtweb.framework.core.mvc.controller.IActionManager; -import cc.smtweb.framework.core.mvc.controller.access.IMethodAccess; - -/** - * 实现自定义@SwAction的拦截器,需要配合@SwAction继承注解配置到函数上使用 - * @author kevin - */ -public interface IScanAction { - Class actionType(); - /** - * 一种@SwAction子类型只能声明一个SwActionPointcut - * @param module 模块名称 - * @param actionManager action管理器,用以注册API服务 - */ - void load(IActionManager actionManager, String module, T anno, IMethodAccess methodAccess); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanActionBuilder.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanActionBuilder.java deleted file mode 100644 index dcb9529..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/IScanActionBuilder.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; -import org.springframework.context.ConfigurableApplicationContext; - -/** - * 实现自定义@SwAction的拦截器,需要配合@SwAction继承注解配置到函数上使用 - * @author kevin - */ -public interface IScanActionBuilder { - IScanAction build(ConfigurableApplicationContext applicationContext, WebDataBinder webDataBinder); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/MethodParser.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/MethodParser.java deleted file mode 100644 index 37664f2..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/MethodParser.java +++ /dev/null @@ -1,159 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import cc.smtweb.framework.core.annotation.*; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import cc.smtweb.framework.core.mvc.controller.access.ControllerAccess; -import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; -import cc.smtweb.framework.core.mvc.controller.access.MethodParamAccess; -import cc.smtweb.framework.core.mvc.controller.binder.ParamEditor; -import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ObjectUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.core.ResolvableType; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.text.ParseException; -import java.util.List; - -@Slf4j -public class MethodParser { - private final UrlMaker urlMaker; - private final BeanManager controllers; - private final WebDataBinder webDataBinder; - private ScanContext scanContext; -// private ControllerAccess controllerAccess; - - public MethodParser(UrlMaker urlMaker, ScanContext scanContext) { - this.urlMaker = urlMaker; - this.controllers = scanContext.getBeanManager(); - this.webDataBinder = scanContext.getWebDataBinder(); - this.scanContext = scanContext; - } - - public void parse(Class clazz, ControllerAccess controllerAccess, boolean isApi) throws ParseException { -// this.controllerAccess = controllerAccess; - // 服务的默认权限 - String classPerm = ""; - SwPerm swPerm = clazz.getAnnotation(SwPerm.class); - if (swPerm != null) { - classPerm = swPerm.value(); - } - - // 扫描方法注解 - for (Method m : clazz.getMethods()) { - int modifier = m.getModifiers(); - - // && (R.class.isAssignableFrom(m.getReturnType())) - if (Modifier.isPublic(modifier) && !Modifier.isStatic(modifier) && !Object.class.equals(m.getDeclaringClass())) { - MethodAccess methodAccess = parseMethod(controllerAccess, m, classPerm); - - if (scanContext.dealMethod(m, methodAccess)) { - if (isApi) { - urlMaker.addApi(clazz, m, methodAccess, controllers); - } - } - -// SwScheduling scheduling = m.getAnnotation(SwScheduling.class); -// SwConstruct construct = m.getAnnotation(SwConstruct.class); -// SwDestroy destroy = m.getAnnotation(SwDestroy.class); -// SwBean bean = m.getAnnotation(SwBean.class); -// SwAction action = m.getAnnotation(SwAction.class); -// -// if (scheduling != null) { -// // 定时任务用seed值限定 -// log.debug(" add timer task: " + clazz.getSimpleName() + "." + m.getName()); -// controllers.addTask(new SchedulerMethodAccess(methodAccess, scheduling)); -// } else if(construct != null) { -// controllers.addConstruct(construct.order(), methodAccess); -// } else if(destroy != null) { -// controllers.addDestroy(destroy.order(), methodAccess); -// } else if(bean != null) { -// controllers.addBeanMethod(methodAccess); -// } else if(action != null) { -// controllers.addAction(action, methodAccess); -// } else if (isApi) { -// urlMaker.addApi(clazz, m, methodAccess, controllers); -// } - } - } - } - - private MethodAccess parseMethod(ControllerAccess controllerAccess, Method method, String defaultPerm) { - Class[] paramTypes = method.getParameterTypes(); - Annotation[][] paramAnnotations = method.getParameterAnnotations(); - - MethodParamAccess[] paramBinds = new MethodParamAccess[paramTypes.length]; - - for (int i = 0; i < paramTypes.length; i++) { - Class paramType = paramTypes[i]; - String paramName = null; - int bindType = ParamEditor.TYPE_UNKNOWN; - if (!ObjectUtils.isEmpty(paramAnnotations[i])) { - for (Annotation annotation: paramAnnotations[i]) { - // isAssignableFrom - Class annotationType = annotation.annotationType(); - if (SwParam.class.equals(annotationType)) { - bindType = ParamEditor.TYPE_PARAM; - String value = ((SwParam) annotation).value(); - if (StringUtils.isNotBlank(value)) { - paramName = value; - } - break; - } else if (SwPathParam.class.equals(annotationType)) { - bindType = ParamEditor.TYPE_PATH; - break; - } else if (SwHeaderParam.class.equals(annotationType)) { - bindType = ParamEditor.TYPE_HEADER; - String value = ((SwHeaderParam) annotation).value(); - if (StringUtils.isNotBlank(value)) { - paramName = value; - } - break; - } else if (SwBody.class.equals(annotationType)) { - bindType = ParamEditor.TYPE_BODY; - String value = ((SwBody) annotation).value(); - if (StringUtils.isNotBlank(value)) { - paramName = value; - } - break; - } else if (SwAttr.class.equals(annotationType)) { - bindType = ParamEditor.TYPE_ATTR; - String value = ((SwAttr) annotation).value(); - if (StringUtils.isNotBlank(value)) { - paramName = value; - } - break; - } - } - } - - IEditor editor = webDataBinder.findEditor(paramType, bindType); - - if (List.class.isAssignableFrom(paramType)) { - // List bind类型使用泛型声明的对象 - ResolvableType resolvableType = ResolvableType.forMethodParameter(method, i); - paramType = resolvableType.getGeneric(0).getRawClass(); - paramBinds[i] = new MethodParamAccess(editor, paramName, resolvableType.getGeneric(0).getRawClass(), bindType, paramType); - } else { - paramBinds[i] = new MethodParamAccess(editor, paramName, paramType, bindType, null); - } - - if (editor == null) { - log.error("not bind type:" + controllerAccess.getFullName() + "." + method.getName()); - } - } - - // 得到权限注解 - String perm = defaultPerm; - SwPerm swPerm = method.getAnnotation(SwPerm.class); - if (swPerm != null) { - perm = swPerm.value(); - } - - return new MethodAccess(controllerAccess, method, perm, paramBinds); - } - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/PackageScanner.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/PackageScanner.java deleted file mode 100644 index d0bfe8b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/PackageScanner.java +++ /dev/null @@ -1,180 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import lombok.extern.slf4j.Slf4j; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Modifier; -import java.net.JarURLConnection; -import java.net.URL; -import java.net.URLDecoder; -import java.util.Enumeration; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -@Slf4j -public class PackageScanner { - private ClassParser classParser; - - public PackageScanner(ClassParser classParser) { - this.classParser = classParser; - } - - /** - * 1. 遍历所有目录 2. 处理注解类,进行适配类匹配 3. 放入路径映射map - * - * @throws IOException - */ - public void scan(String packagePath) throws IOException { -// log.info("[smt]start scan " + packagePath); - directorize(packagePath, true); -// log.info("[smt]end scan " + packagePath); - } - - /** - * 扫描目录下的注解类 - * - * @param packageName 目录对象 - * @param recursive 是否递归扫描包 - */ - private void directorize(String packageName, boolean recursive) - throws IOException { - String packageDirName = packageName.replace('.', '/'); - - Enumeration dirs = Thread.currentThread().getContextClassLoader() - .getResources(packageDirName); - - // 循环迭代下去 - while (dirs.hasMoreElements()) { - // 获取下一个元素 - URL url = dirs.nextElement(); - // 得到协议的名称 - String protocol = url.getProtocol(); - // 如果是以文件的形式保存在服务器上 - if ("file".equals(protocol)) { -// log.debug("scan action in file"); - // 获取包的物理路径 - String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); - // 以文件的方式扫描整个包下的文件 并添加到集合中 - findAndAddClassesInPackageByFile(packageName, "", filePath, - recursive); - // 执行属性设置 -// for (FieldAutowriter field : fieldList) { -// boolean ret = field.writeValue(this.context); -// if (ret) { -// log.debug("write bean " + field.getName() -// + " success."); -// } else { -// log.error("write bean " + field.getName() -// + " failure."); -// } -// } - } else if ("jar".equals(protocol)) { - // 如果是jar包文件 - // 定义一个JarFile - try { - // 获取jar - JarFile jar = ((JarURLConnection) url.openConnection()) - .getJarFile(); - // 从此jar包 得到一个枚举类 - Enumeration entries = jar.entries(); - // 同样的进行循环迭代 - while (entries.hasMoreElements()) { - // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件 - JarEntry entry = entries.nextElement(); - String name = entry.getName(); - // 如果是以/开头的 - if (name.charAt(0) == '/') { - // 获取后面的字符串 - name = name.substring(1); - } - // 如果前半部分和定义的包名相同 - if (name.startsWith(packageDirName)) { - int idx = name.lastIndexOf('/'); - // 如果以"/"结尾 是一个包 - if (idx != -1) { - // 获取包名 把"/"替换成"." - packageName = name.substring(0, idx).replace( - '/', '.'); - } - // 如果可以迭代下去 并且是一个包 - if ((idx != -1) || recursive) { - // 如果是一个.class文件 而且不是目录 - if (!entry.isDirectory()) { - parseFile( - packageName, "", - name.substring(packageName.length() + 1)); - } - } - } - } - } catch (IOException e) { - log.error("scan jar error", e); - // log.error("在扫描用户定义视图时从jar包获取文件出错"); - // e.printStackTrace(); - } - } - } - } - - /** - * 以文件的形式来获取包下的所有Class - * - * @param packageName - * @param packagePath - * @param recursive - */ - public void findAndAddClassesInPackageByFile(String packageName, String dirName, - String packagePath, final boolean recursive) { - // 获取此包的目录 建立一个File - File dir = new File(packagePath); - // 如果不存在或者 也不是目录就直接返回 - if (!dir.exists() || !dir.isDirectory()) { - // log.warn("用户定义包名 " + packageName + " 下没有任何文件"); - return; - } - - // 如果存在 就获取包下的所有文件 包括目录 - // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件) - File[] dirFiles = dir.listFiles(file -> { - String fileName = file.getName(); - return (recursive && file.isDirectory()) - || fileName.endsWith(".class"); - }); - - // 循环所有文件 - if (dirFiles != null) { - for (File file : dirFiles) { - // 如果是目录 则继续扫描 - if (file.isDirectory()) { - findAndAddClassesInPackageByFile(packageName + "." + file.getName(), - file.getName(), file.getAbsolutePath(), recursive); - } else { - parseFile(packageName, dirName, file.getName()); - } - } - } - } - - private void parseFile(String packageName, String dirName, String fileName) { - if (fileName.endsWith(".class")) { - // 去掉后面的".class" 获取真正的类名 - String className = fileName.substring(0, fileName.length() - 6); - - className = packageName + '.' + className; - - try { - Class clazz = Class.forName(className); - - int modifiers = clazz.getModifiers(); - - if (Modifier.isPublic(modifiers) && !Modifier.isAbstract(modifiers)) { - classParser.parse(dirName, clazz); - } - } catch (Exception e) { - log.error("init class error " + className, e); - throw new RuntimeException(e); - } - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ScanContext.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ScanContext.java deleted file mode 100644 index b20338c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/ScanContext.java +++ /dev/null @@ -1,115 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import cc.smtweb.framework.core.annotation.SwBean; -import cc.smtweb.framework.core.annotation.SwConstruct; -import cc.smtweb.framework.core.annotation.SwDestroy; -import cc.smtweb.framework.core.annotation.SwScheduling; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; -import cc.smtweb.framework.core.mvc.controller.access.SchedulerMethodAccess; -import cc.smtweb.framework.core.mvc.controller.binder.WebDataBinder; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.text.ParseException; -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiFunction; - -@Getter -@Slf4j -public class ScanContext { - private final BeanManager beanManager; - private final WebDataBinder webDataBinder; -// private Map, List> actions = new HashMap<>(); - private Map, BiFunction> dealMethodAnnotation = new HashMap<>(); - @Setter - private String module; - - public ScanContext(BeanManager beanManager, WebDataBinder webDataBinder) { - this.beanManager = beanManager; - this.webDataBinder = webDataBinder; -// if (scheduling != null) { -// // 定时任务用seed值限定 -// log.debug(" add timer task: " + clazz.getSimpleName() + "." + m.getName()); -// controllers.addTask(new SchedulerMethodAccess(methodAccess, scheduling)); -// } else if(construct != null) { -// controllers.addConstruct(construct.order(), methodAccess); -// } else if(destroy != null) { -// controllers.addDestroy(destroy.order(), methodAccess); -// } else if(bean != null) { -// controllers.addBeanMethod(methodAccess); -// } else if(action != null) { -// controllers.addAction(action, methodAccess); -// } else if (isApi) { -// urlMaker.addApi(clazz, m, methodAccess, controllers); -// } - dealMethodAnnotation.put(SwScheduling.class, (a, methodAccess) -> { - try { - // 定时任务用seed值限定 - beanManager.addTask(new SchedulerMethodAccess(methodAccess, ((SwScheduling)a))); - log.debug(" add timer task: " + methodAccess.fullName()); - } catch (ParseException e) { - throw new SwException(e); - } - - return false; - }); - - dealMethodAnnotation.put(SwConstruct.class, (a, methodAccess) -> { - beanManager.addConstruct(((SwConstruct)a).order(), methodAccess); - return false; - }); - - dealMethodAnnotation.put(SwDestroy.class, (a, methodAccess) -> { - beanManager.addDestroy(((SwDestroy)a).order(), methodAccess); - return false; - }); - - dealMethodAnnotation.put(SwBean.class, (a, methodAccess) -> { - beanManager.addBeanMethod(methodAccess); - return false; - }); -// -// dealMethodAnnotation.put(SwAction.class, (a, methodAccess) -> { -// return true; -// }); -// -// dealMethodAnnotation.put(SwPerm.class, (a, methodAccess) -> { -// return true; -// }); - } - - public void addScanAction(IScanAction apiLoader) { - Object old = dealMethodAnnotation.putIfAbsent(apiLoader.actionType(), (a, methodAccess) -> { - apiLoader.load(beanManager, module, a, methodAccess); - return false; - }); - - if (old != null) { - log.error("已经存在动作解析器:" + apiLoader.actionType()); - } - } - - public boolean dealMethod(Method m, MethodAccess methodAccess) { - boolean result = true; - Annotation[] annos = m.getDeclaredAnnotations(); - if (annos != null) { - for (Annotation anno: annos) { - BiFunction func = dealMethodAnnotation.get(anno.annotationType()); - if (func != null) { - boolean ret = func.apply(anno, methodAccess); - if (!ret) { - result = false; - break; - } - } - } - } - - return result; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/UrlMaker.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/UrlMaker.java deleted file mode 100644 index 7aa6aa9..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/controller/scan/UrlMaker.java +++ /dev/null @@ -1,95 +0,0 @@ -package cc.smtweb.framework.core.mvc.controller.scan; - -import cc.smtweb.framework.core.annotation.SwAction; -import cc.smtweb.framework.core.mvc.controller.ApiConfigBean; -import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.lang.reflect.Method; - -/** - * URL构造器,用于API的访问路径构造 - * @author xkliu - */ -@Slf4j -class UrlMaker { - private static final String SERVICE_SUFFIX = "Service"; - - private final ApiConfigBean apiConfig; - @Getter - private final String module; - private String serviceUrl; - - UrlMaker(ApiConfigBean apiConfig, String module) { - this.apiConfig = apiConfig; - this.module = module; - } - - private String getServiceName(Class clazz) { - String simpleName = clazz.getSimpleName(); - if (simpleName.endsWith(SERVICE_SUFFIX)) { - simpleName = simpleName.substring(0, simpleName.length() - SERVICE_SUFFIX.length()); - } - - return simpleName; - } - - /** - * 添加API映射到BeanManager,API的url先取SwApi配置的值,然后取SwService配置的值+“/”+方法名,最后使用默认规则: “服务名” / "方法名" - * url都以模块名开头,避免应用模块服务名称重复 - * @param clazz 服务类 - * @param method 执行方法,用于映射API - * @param methodAccess 方法实际执行 - * @param controllers 控制器管理容器 - */ - void addApi(Class clazz, Method method, MethodAccess methodAccess, BeanManager controllers) { - String serviceName = getServiceName(clazz); - String methodName = method.getName(); - String urlPrefix = module + "/"; - SwAction swAction = method.getAnnotation(SwAction.class); - - if (swAction != null && StringUtils.isNotBlank(swAction.value())) { - // SwApi设置了URL - mappingApi(methodAccess, controllers, urlPrefix + swAction.value()); - } else if (this.serviceUrl != null) { - // SwService设置了URL - mappingApi(methodAccess, controllers, urlPrefix + this.serviceUrl + "/" + methodName); - } else { - // 小驼峰路径 - String littleCamelCaseUrl = urlPrefix + toLittleCamelName(serviceName) + "/" + methodName; - - if (mappingApi(methodAccess, controllers, littleCamelCaseUrl)) { - // 大驼峰路径,类原名 - if (apiConfig.isBigCameCaseUrl()) { - mappingApi(methodAccess, controllers, urlPrefix + serviceName + "/" + methodName); - } - - // 小写服务名路径 - if (apiConfig.isLowerCaseUrl()) { - mappingApi(methodAccess, controllers, urlPrefix + serviceName.toLowerCase() + "/" + methodName); - } - } - } - } - - private String toLittleCamelName(String serviceName) { - return Character.toLowerCase(serviceName.charAt(0)) - + serviceName.substring(1); - } - - private boolean mappingApi(MethodAccess methodAccess, BeanManager controllers, String url) { - if (controllers.putIfAbsent(url, methodAccess) != null) { - log.error("url is repeat: " + url + ", " + methodAccess.controllerFullName()); - return false; - } - - log.debug("[smt]init: " + url + ", " + methodAccess.controllerFullName()); - return true; - } - - void setServiceUrl(String value) { - this.serviceUrl = StringUtils.trimToNull(value); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/IRealmLoader.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/IRealmLoader.java deleted file mode 100644 index 5d5a490..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/IRealmLoader.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm; - -import cc.smtweb.framework.core.session.UserSession; - -import java.util.Set; - -/** - * @author kevin - * 用户权限加载器 - */ -public interface IRealmLoader { - /** - * 读取用户权限集合 - * @param userSession 用户会话 - * @return 权限集合 - */ - Set getPermits(UserSession userSession); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthenticationException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthenticationException.java deleted file mode 100644 index 3a65419..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthenticationException.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.exception; - -public class AuthenticationException extends AuthorizationException { - public AuthenticationException(String s) { - super(s); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthorizationException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthorizationException.java deleted file mode 100644 index 423cbbd..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/AuthorizationException.java +++ /dev/null @@ -1,9 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.exception; - -import cc.smtweb.framework.core.exception.SwException; - -public class AuthorizationException extends SwException { - public AuthorizationException(String s) { - super(s); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/ForbiddenException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/ForbiddenException.java deleted file mode 100644 index 2aa0cdd..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/ForbiddenException.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.exception; - -public class ForbiddenException extends AuthorizationException { - public ForbiddenException(String s) { - super(s); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnauthenticatedException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnauthenticatedException.java deleted file mode 100644 index 52ea554..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnauthenticatedException.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.exception; - -public class UnauthenticatedException extends AuthorizationException { - public UnauthenticatedException(String s) { - super(s); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnknownAccountException.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnknownAccountException.java deleted file mode 100644 index 3ac1681..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/exception/UnknownAccountException.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.exception; - -public class UnknownAccountException extends AuthorizationException { - public UnknownAccountException(String s) { - super(s); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AbstractPermInterceptor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AbstractPermInterceptor.java deleted file mode 100644 index 73e4c3c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AbstractPermInterceptor.java +++ /dev/null @@ -1,109 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.interceptor; - -import cc.smtweb.framework.core.annotation.SwPerm; -import cc.smtweb.framework.core.cache.ISwCache; -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import cc.smtweb.framework.core.mvc.realm.exception.ForbiddenException; -import cc.smtweb.framework.core.mvc.realm.exception.UnauthenticatedException; -import cc.smtweb.framework.core.mvc.realm.service.PermCheckItem; -import cc.smtweb.framework.core.mvc.realm.service.PermChecker; -import cc.smtweb.framework.core.session.SessionUtil; -import cc.smtweb.framework.core.session.UserSession; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; - -public class AbstractPermInterceptor { - private final RedisManager redisManager; - private ISwCache cacheService; - - public AbstractPermInterceptor(RedisManager redisManager) { - this.redisManager = redisManager; - } - - public void setCache(ISwCache cacheService) { - this.cacheService = cacheService; - } - - protected boolean handle(HttpServletRequest request, String permissionValue) { - // 如果注解为null, 说明不需要拦截, 直接放过 - if (StringUtils.isEmpty(permissionValue) || SwPerm.NONE.equals(permissionValue)) { - return true; - } - - // redis读取session,判断是否登录 - String token = SessionUtil.readToken(request); - if (StringUtils.isBlank(token)) { - throw new UnauthenticatedException("not find Auth-Token in header"); - } - - UserSession us = redisManager.get(token, UserSession.class); - if (us == null) { - throw new UnauthenticatedException("not find UserSession by token: " + token); - } - - request.setAttribute(IEditor.USER_TOKEN, token); - request.setAttribute(IEditor.USER_SESSION, us); - - // 如果标记了权限注解,则判断权限 - if (checkPermission(permissionValue, us)) { - // 更新Token redis TTL - redisManager.expire(token, RedisManager.SESSION_EXPIRE_SEC); - return true; - } else { - throw new ForbiddenException("user not permission: " + permissionValue); - } - } - - /** - * 权限检查 - */ - private boolean checkPermission(String permissionValue, UserSession us) { - if (StringUtils.isBlank(permissionValue)) { - return true; - } - - // 从本地缓存或数据库中获取该用户的权限信息 - PermChecker permissionSet = cacheService.get(us.getUserId()); - -// if (MapUtils.isEmpty(permissionSet)) { -// throw new ForbiddenException("empty permission"); -// } - - PermCheckItem permChecker = permissionSet.get(permissionValue); - - if (permChecker != null) { - return true; - } - - while (true) { - permissionValue = getParentPermValue(permissionValue); - - if (permissionValue != null) { - permChecker = permissionSet.get(permissionValue); - if (permChecker != null && permChecker.isPerfixMath()) { - return true; - } - } else { - break; - } - } - - return false; - } - - private static String getParentPermValue(String permissionValue) { - if (permissionValue.length() > 0) { - - int pos = permissionValue.lastIndexOf(':'); - if (pos > 0) { - return permissionValue.substring(0, pos); - } - - return ""; - } - - return null; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AuthorizationInterceptor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AuthorizationInterceptor.java deleted file mode 100644 index 47a24d5..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/AuthorizationInterceptor.java +++ /dev/null @@ -1,42 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.interceptor; - -import cc.smtweb.framework.core.annotation.SwPerm; -import cc.smtweb.framework.core.cache.redis.RedisManager; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.HandlerInterceptor; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * 暂时未使用,spring的拦截器方式判断权限 - */ -public class AuthorizationInterceptor extends AbstractPermInterceptor implements HandlerInterceptor { - - public AuthorizationInterceptor(RedisManager redisManager) { - super(redisManager); - } - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { - if (handler instanceof HandlerMethod) { - HandlerMethod handlerMethod = (HandlerMethod) handler; - // 获取方法上的注解 - SwPerm requiredSwPerm = handlerMethod.getMethod().getAnnotation(SwPerm.class); - // 如果方法上的注解为空 则获取类的注解 - if (requiredSwPerm == null) { - requiredSwPerm = handlerMethod.getMethod().getDeclaringClass().getAnnotation(SwPerm.class); - } - - String requiredValue = null; - if (requiredSwPerm != null) { - requiredValue = requiredSwPerm.value(); - } - - return super.handle(request, requiredValue); - } - - return true; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/PermInterceptor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/PermInterceptor.java deleted file mode 100644 index dcf9184..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/interceptor/PermInterceptor.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.interceptor; - -import cc.smtweb.framework.core.cache.redis.RedisManager; - -import javax.servlet.http.HttpServletRequest; - -/** - * 权限拦截器,在API请求处理中一起完成 - * @author xkliu - */ -public class PermInterceptor extends AbstractPermInterceptor { - public PermInterceptor(RedisManager redisManager) { - super(redisManager); - } - - /** - * 校验用户是否有API权限 - * @param request http请求 - * @param permissionValue 权限值 - * @return 是否有权限 - */ - public boolean preHandle(HttpServletRequest request, String permissionValue) { - return super.handle(request, permissionValue); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermCheckItem.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermCheckItem.java deleted file mode 100644 index 2cecf28..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermCheckItem.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.service; - -public class PermCheckItem { - // 全匹配 - private static final int TYPE_ALL_MATCH = 0; - // 前缀匹配 - private static final int TYPE_PREFIX_MATCH = 1; - - private int type; - - public static final PermCheckItem allMatch = new PermCheckItem(TYPE_ALL_MATCH); - public static final PermCheckItem prefixMatch = new PermCheckItem(TYPE_PREFIX_MATCH); - - private PermCheckItem(int type) { - this.type = type; - } - - public boolean isPerfixMath() { - return this.type == TYPE_PREFIX_MATCH; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermChecker.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermChecker.java deleted file mode 100644 index 8bb2cc5..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/realm/service/PermChecker.java +++ /dev/null @@ -1,35 +0,0 @@ -package cc.smtweb.framework.core.mvc.realm.service; - -import java.util.HashMap; -import java.util.Set; - -public class PermChecker extends HashMap { - private static final PermChecker CHECKER_ZERO = new PermChecker(); - - private PermChecker(){ - super(); - } - - private PermChecker(int size){ - super(size); - } - - public static PermChecker build(Set permits) { - if (permits != null) { - PermChecker result = new PermChecker(permits.size()); - - for (String perm: permits) { - if (perm.endsWith(":*")) { - perm = perm.substring(0, perm.length() - 2); - result.put(perm, PermCheckItem.prefixMatch); - } else { - result.putIfAbsent(perm, PermCheckItem.allMatch); - } - } - - return result; - } - - return CHECKER_ZERO; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJob.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJob.java deleted file mode 100644 index d3d8030..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJob.java +++ /dev/null @@ -1,59 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler; - -import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public abstract class AbstractJob { - final MethodAccess method; - @Getter - private String key; - boolean hasPointParam; -// @Getter @Setter -// private AbstractJobQueue jobQueue; - - public AbstractJob(MethodAccess methodAccess) { - this.method = methodAccess; - this.hasPointParam = methodAccess.findParam(SchedulerPoint.class) != null; - } - - protected void initKey(String key) { - this.key = key; - } - -// public void invoke(Map params) { -// try { -// // 组织断点对象参数 -// Map params = null; -// SchedulerPoint schedulerPoint = null; -// if (hasPointParam) { -// schedulerPoint = jobManager.loadBreakPoint(this); -// if (schedulerPoint != null) { -// params = new HashMap<>(1); -// params.put(SchedulerPoint.class.getName(), schedulerPoint); -// } -// } -// -// method.invoke(beanContext, params, null, null, null); -// -// if (hasPointParam) { -// jobManager.saveBreakPoint(this, schedulerPoint); -// } -// } catch (InvocationTargetException e) { -// if (e.getCause() != null) { -// log.error(e.getCause().getMessage(), e.getCause()); -// } else { -// log.error(e.getMessage(), e); -// } -// } catch (Exception e) { -// log.error(e.getMessage(), e); -// } -// } - - public abstract AbstractJobQueue createJobQueue(AbstractJobExecutor jobManager); - - public String getName() { - return this.method.fullName(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobExecutor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobExecutor.java deleted file mode 100644 index 57a0fe4..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobExecutor.java +++ /dev/null @@ -1,85 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.util.DateUtil; -import cc.smtweb.framework.core.util.JsonUtil; -import lombok.Getter; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutorService; - -public abstract class AbstractJobExecutor { - @Getter - private IBeanContext beanContext; - private ExecutorService executor; - protected Long redisLockValue; - private DbEngine dbEngine; - protected final Map jobMap = new HashMap<>(); - - public AbstractJobExecutor(IBeanContext beanContext, ExecutorService executor, Long redisLockValue, DbEngine dbEngine) { - this.beanContext = beanContext; - this.executor = executor; - this.redisLockValue = redisLockValue; - this.dbEngine = dbEngine; - } - - public abstract boolean tryLock(AbstractJob job); - - public abstract void unlock(AbstractJob job); - - // 执行任务 - public void execute(final AbstractJobQueue jobQueue, final AbstractJob job) { - this.executor.submit(() -> { - if (tryLock(job)) { - try { - jobQueue.execute(job); - } finally { - unlock(job); - } - } - }); - } - - void saveBreakPoint(AbstractJob job, SchedulerPoint schedulerPoint) { - if (schedulerPoint != null && schedulerPoint.changed) { - String value = JsonUtil.encodeString(schedulerPoint.value); - long now = DateUtil.nowDateTimeLong(); - if (schedulerPoint.insert) { - dbEngine.update("insert into sw_user.sch_break_point(bp_id, bp_job_name, bp_machine_id, bp_value, bp_create_time, bp_last_time) values(?,?,?,?,?,?)", - dbEngine.nextId(), job.getName(), this.redisLockValue, value, now, now); - } else { - dbEngine.update("update sw_user.sch_break_point set bp_machine_id=?, bp_value=?, bp_last_time=? where bp_job_name=?", - this.redisLockValue, value, now, job.getName()); - } - } - } - - SchedulerPoint loadBreakPoint(AbstractJob job) { - String value = dbEngine.queryString("select bp_value from sw_user.sch_break_point where bp_job_name=?", job.getName()); - - SchedulerPoint result; - if (value != null) { - SwMap swMap = JsonUtil.parse(value, SwMap.class); - result = new SchedulerPoint(swMap); - } else { - result = new SchedulerPoint(); - } - - return result; - } - - AbstractJobQueue initJobQueue(AbstractJob job) { - String key = job.getKey(); - - AbstractJobQueue jobQueue = jobMap.get(key); - if (jobQueue == null) { - jobQueue = job.createJobQueue(this); - jobMap.put(key, jobQueue); - } - - return jobQueue; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobQueue.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobQueue.java deleted file mode 100644 index 1f5993f..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/AbstractJobQueue.java +++ /dev/null @@ -1,72 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; - -/** - * Job执行队列 - * @author xkliu - */ -@Slf4j -public abstract class AbstractJobQueue { - private AtomicLong lastTime = new AtomicLong(); - private ReentrantLock lock = new ReentrantLock(); - @Getter - private AbstractJobExecutor jobExecutor; - - public AbstractJobQueue(AbstractJobExecutor jobExecutor) { - this.jobExecutor = jobExecutor; - } - - public void execute(AbstractJob job) { - try { - // 组织断点对象参数 - Map params = null; - SchedulerPoint schedulerPoint = null; - if (job.hasPointParam) { - schedulerPoint = jobExecutor.loadBreakPoint(job); - if (schedulerPoint != null) { - params = new HashMap<>(1); - params.put(SchedulerPoint.class.getName(), schedulerPoint); - } - } - - job.method.invoke(jobExecutor.getBeanContext(), params, null, null); - - if (job.hasPointParam) { - jobExecutor.saveBreakPoint(job, schedulerPoint); - } - } catch (Exception e) { - log.error(e.getMessage(), e); - } - - } - - public long getLastTime() { - return lastTime.get(); - } - - protected boolean tryLock() { - boolean result = lock.tryLock(); - - if (result) { - lastTime.set(System.currentTimeMillis()); - } - - return result; - } - - protected void unlock() { - lastTime.set(0); - lock.unlock(); - } - - public void updateLastTime() { - lastTime.set(System.currentTimeMillis()); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/CronTimerTask.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/CronTimerTask.java deleted file mode 100644 index 4184df9..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/CronTimerTask.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler; - -import com.serotonin.timer.TimerTask; -import com.serotonin.timer.TimerTrigger; -import lombok.extern.slf4j.Slf4j; - - -/** - * 包装定时器任务 - * - * @author xkliu - * - */ -@Slf4j -public class CronTimerTask extends TimerTask { - private final AbstractJobQueue jobQueue; - private AbstractJob job; - - CronTimerTask(TimerTrigger timerTrigger, AbstractJobQueue jobQueue, AbstractJob job) { - super(timerTrigger); - this.jobQueue = jobQueue; - this.job = job; - } - - @Override - public void run(long time) { - // 开启线程执行 - jobQueue.getJobExecutor().execute(jobQueue, job); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/FixedTimerTask.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/FixedTimerTask.java deleted file mode 100644 index 7f33937..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/FixedTimerTask.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler; - -import com.serotonin.timer.FixedRateTrigger; -import com.serotonin.timer.TimerTask; - -public class FixedTimerTask extends TimerTask { - private final Runnable job; - - // new TimerTask(new FixedRateTrigger(30, 60)), result.redisJobManager - public FixedTimerTask(int delay, int period, Runnable job) { - super(new FixedRateTrigger(delay, period)); - this.job = job; - } - - @Override - public void run(long runtime) { - job.run(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerPoint.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerPoint.java deleted file mode 100644 index b2bf66c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerPoint.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler; - -import cc.smtweb.framework.core.common.SwMap; - -/** - * 定时器断点数据 - * @author xkliu - */ -public class SchedulerPoint { - SwMap value; - boolean changed; - boolean insert; - - public SchedulerPoint() { - insert = true; - value = new SwMap(); - } - - public SchedulerPoint(SwMap value) { - this.value = value; - } - - public Object get(String key) { - return value.get(key); - } - - public Long readLong(String key) { - return value.readLong(key); - } - public Long readLong(String key, Long defaultValue) { - return value.readLong(key, defaultValue); - } - - public SchedulerPoint put(String key, Object value) { - this.value.put(key, value); - this.changed = true; - - return this; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerTaskManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerTaskManager.java deleted file mode 100644 index 7fe5a7d..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/SchedulerTaskManager.java +++ /dev/null @@ -1,97 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler; - -import cc.smtweb.framework.core.annotation.SwScheduling; -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.mvc.ISchedulerWakeup; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.controller.access.SchedulerMethodAccess; -import cc.smtweb.framework.core.mvc.scheduler.job.GroupJob; -import cc.smtweb.framework.core.mvc.scheduler.job.LocalJobExecutor; -import cc.smtweb.framework.core.mvc.scheduler.job.RedisJobExecutor; -import cc.smtweb.framework.core.mvc.scheduler.job.SimpleJob; -import com.serotonin.timer.RealTimeTimer; -import com.serotonin.timer.TimerTask; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.concurrent.BasicThreadFactory; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -public class SchedulerTaskManager implements ISchedulerWakeup { - private final ExecutorService executor; - private final RealTimeTimer timer; - private final Map timerTaskMap = new HashMap<>(); - - private SchedulerTaskManager() { - int poolSize = Runtime.getRuntime().availableProcessors(); - this.executor = new ThreadPoolExecutor(2, poolSize * 2 + 2, 5, TimeUnit.MINUTES, - new SynchronousQueue<>(), - new BasicThreadFactory.Builder().namingPattern("sw-scheduler-").build()); - - // 保证2个线程就够了,1个触发定时器,1个定时同步redis状态 - this.timer = new RealTimeTimer(); - this.timer.init(1, 4); - } - - public static SchedulerTaskManager build(IBeanContext beanContext, List tasks) { - if (!tasks.isEmpty()) { - SchedulerTaskManager result = new SchedulerTaskManager(); - - DbEngine dbEngine = beanContext.getBean(DbEngine.class); - RedisManager redisManager = beanContext.getBean(RedisManager.class); - Long redisLockValue = dbEngine.nextId(); - - LocalJobExecutor localJobExecutor = new LocalJobExecutor(beanContext, result.executor, redisLockValue, dbEngine); - RedisJobExecutor redisJobExecutor = new RedisJobExecutor(beanContext, result.executor, redisLockValue, dbEngine, redisManager); - - for (SchedulerMethodAccess schedulerMethodAccess: tasks) { - SwScheduling swScheduling = schedulerMethodAccess.getSwScheduling(); - - AbstractJob job; - String group = swScheduling.group(); - AbstractJobExecutor jobManager = swScheduling.multiServer() ? localJobExecutor : redisJobExecutor; - - if (StringUtils.isNotBlank(group)) { - job = new GroupJob(group, schedulerMethodAccess.getMethodAccess()); - } else { - job = new SimpleJob(schedulerMethodAccess.getMethodAccess()); - } - - AbstractJobQueue jobQueue = jobManager.initJobQueue(job); - CronTimerTask task = new CronTimerTask(schedulerMethodAccess.getTimerTrigger(), jobQueue, job); - - result.timer.schedule(task); - result.timerTaskMap.put(job.getName(), task); - } - - int time = RedisJobExecutor.TIME_CHECK_SEC * 1000; - result.timer.schedule(new FixedTimerTask(time, time, redisJobExecutor)); - - return result; - } - - return null; - } - - public void shutdown() { - this.timer.cancel(); - this.executor.shutdown(); - } - - @Override - public boolean wakeup(Class clazz, String methodName) { - TimerTask task = timerTaskMap.get(clazz.getName() + "." + methodName); - if (task != null) { - task.run(System.currentTimeMillis()); - return true; - } - - return false; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJob.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJob.java deleted file mode 100644 index 0fc49c5..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJob.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler.job; - -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobQueue; - -public class GroupJob extends AbstractJob { - @Override - public AbstractJobQueue createJobQueue(AbstractJobExecutor jobManager) { - return new GroupJobQueue(jobManager); - } - - public GroupJob(String group, MethodAccess methodAccess) { - super(methodAccess); - initKey(RedisManager.PREFIX_TIMER + '.' + group); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJobQueue.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJobQueue.java deleted file mode 100644 index 2fd9a56..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/GroupJobQueue.java +++ /dev/null @@ -1,82 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler.job; - -import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobQueue; - -import java.util.Deque; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Set; - -public class GroupJobQueue extends AbstractJobQueue { - private Deque queue; - private Set keySet; - private String currentJobName; - - public GroupJobQueue(AbstractJobExecutor jobManager) {super(jobManager);} - - private synchronized void setCurrent(AbstractJob job) { - currentJobName = job.getName(); - } - - private synchronized AbstractJob pull() { - AbstractJob result = null; - - if (queue != null) { - result = queue.pop(); - - if (result != null) { - keySet.remove(result.getName()); - } - } - - if (result != null) { - this.currentJobName = result.getName(); - } else { - this.currentJobName = null; - } - - return result; - } - - private synchronized boolean push(AbstractJob job) { - String jobName = job.getName(); - - if (jobName.equals(currentJobName)) { - return false; - } - - if (keySet == null) { - keySet = new HashSet<>(); - } else if (keySet.contains(jobName)) { - // 避免重复加入 - return false; - } - - keySet.add(jobName); - - if (queue == null) { - queue = new LinkedList<>(); - } - - queue.push(job); - return true; - } - - @Override - public void execute(AbstractJob job) { - if (tryLock()) { - try { - setCurrent(job); - do { - super.execute(job); - } while((job = pull()) != null); - } finally { - unlock(); - } - } else { - push(job); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/LocalJobExecutor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/LocalJobExecutor.java deleted file mode 100644 index d085307..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/LocalJobExecutor.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler.job; - -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; - -import java.util.concurrent.ExecutorService; - -public class LocalJobExecutor extends AbstractJobExecutor { - public LocalJobExecutor(IBeanContext beanContext, ExecutorService executor, Long redisLockValue, DbEngine dbEngine) { - super(beanContext, executor, redisLockValue, dbEngine); - } - - @Override - public boolean tryLock(AbstractJob job) { - return true; - } - - @Override - public void unlock(AbstractJob job) { - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/RedisJobExecutor.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/RedisJobExecutor.java deleted file mode 100644 index 643d67a..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/RedisJobExecutor.java +++ /dev/null @@ -1,70 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler.job; - -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.mvc.controller.IBeanContext; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; -import lombok.extern.slf4j.Slf4j; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.locks.ReentrantLock; - -@Slf4j -public class RedisJobExecutor extends AbstractJobExecutor implements Runnable { - public static final int TIME_CHECK_SEC = 30; - public static final int TIME_LOOK_SEC = 3 * TIME_CHECK_SEC; - - private ReentrantLock lock = new ReentrantLock(); - private RedisManager redisManager; - - public RedisJobExecutor(IBeanContext beanContext, ExecutorService executor, Long redisLockValue, DbEngine dbEngine, RedisManager redisManager) { - super(beanContext, executor, redisLockValue, dbEngine); - this.redisManager = redisManager; - } - - @Override - public boolean tryLock(AbstractJob job) { - // redis检查, 同group需要排队等待执行\ - String key = job.getKey(); - - boolean redisLocked = redisManager.setnx(key, redisLockValue, TIME_LOOK_SEC); - - if (!redisLocked) { - Long oldLockedValue = redisManager.get(key, Long.class); - if (!redisLockValue.equals(oldLockedValue)) { - return false; - } - } - - return redisLocked; - } - - @Override - public void unlock(AbstractJob job) { - redisManager.del(job.getKey()); - } - - @Override - public void run() { - if (lock.tryLock()) { - try { - // 定时更新redis锁定状态 - long now = System.currentTimeMillis(); - jobMap.forEach((key, value) -> { - long lastTime = value.getLastTime(); - - if (lastTime > 0 && now - lastTime >= TIME_CHECK_SEC) { - if (redisManager.set(key, redisLockValue, TIME_LOOK_SEC)) { - value.updateLastTime(); - } else { - log.error("update redis lock failed, key: " + key); - } - } - }); - } finally { - lock.unlock(); - } - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJob.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJob.java deleted file mode 100644 index 19b2720..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJob.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler.job; - -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.mvc.controller.access.MethodAccess; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobQueue; - -public class SimpleJob extends AbstractJob { - public SimpleJob(MethodAccess methodAccess) { - super(methodAccess); - initKey(RedisManager.PREFIX_TIMER + methodAccess.fullName()); - } - - @Override - public AbstractJobQueue createJobQueue(AbstractJobExecutor jobManager) { - return new SimpleJobQueue(jobManager); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJobQueue.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJobQueue.java deleted file mode 100644 index e0de2d1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/scheduler/job/SimpleJobQueue.java +++ /dev/null @@ -1,22 +0,0 @@ -package cc.smtweb.framework.core.mvc.scheduler.job; - -import cc.smtweb.framework.core.mvc.scheduler.AbstractJob; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobExecutor; -import cc.smtweb.framework.core.mvc.scheduler.AbstractJobQueue; - -public class SimpleJobQueue extends AbstractJobQueue { - public SimpleJobQueue(AbstractJobExecutor jobManager) { - super(jobManager); - } - - @Override - public void execute(AbstractJob job) { - if (tryLock()) { - try { - super.execute(job); - } finally { - unlock(); - } - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompProvider.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompProvider.java deleted file mode 100644 index 472a9a3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompProvider.java +++ /dev/null @@ -1,21 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by Akmm at 2022/3/3 11:13 - * 数据提供者,线程级缓存 - */ -public class AbstractCompProvider { - //临时缓存 - private Map cacheData = new HashMap<>(); - - protected T doGetData(String key, IDataProvider loader) { - cacheData.computeIfAbsent(key, s -> loader.load()); - if (!cacheData.containsKey(key)) { - cacheData.put(key, loader.load()); - } - return (T) cacheData.get(key); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompService.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompService.java deleted file mode 100644 index 1352112..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractCompService.java +++ /dev/null @@ -1,96 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.annotation.SwBody; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.session.UserSession; - -/** - * Created by Akmm at 2022/3/2 10:39 - * 通用业务mvc总调度 - */ -public abstract class AbstractCompService { - public final static String TYPE_LIST = "list"; - public final static String TYPE_COMBO = "combo"; - public final static String TYPE_TREE = "tree"; - public final static String TYPE_LOAD = "load"; - public final static String TYPE_SAVE = "save"; - public final static String TYPE_DEL = "del"; - - protected abstract AbstractHandler createHandler(String type); - - protected AbstractHandler getHandler(SwMap params, UserSession us, String type) throws Exception { - AbstractHandler handler = createHandler(type); - if (handler == null) throw new BizException("暂不支持此类服务:" + type); - if (params == null) params = new SwMap(); - if (us == null) us = UserSession.createSys(); - handler.init(params, us); - return handler; - } - - protected R pageHandler(SwMap params, UserSession us, String type, IWorker worker) { - try { - AbstractHandler handler = getHandler(params, us, type); - return worker.doWork(handler); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //保存 - public R save(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_SAVE, handler -> ((AbstractSaveHandler)handler).save()); - } - - //树,换爹 - public R trcp(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_SAVE, handler -> ((AbstractSaveHandler)handler).changeParent()); - } - - //读取 - public R load(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((AbstractLoadHandler)handler).load()); - } - - //删除 - public R del(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_DEL, handler -> ((AbstractDelHandler)handler).del()); - } - - //列表数据 - public R list(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LIST, handler -> ((AbstractListHandler)handler).data()); - } - - //列表总记录数及合计栏 - public R listTotal(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LIST, handler -> ((AbstractListHandler)handler).getTotal()); - } - - //combo数据 - public R combo(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_COMBO, handler -> ((DefaultComboHandler)handler).data()); - } - - //combo总记录数及合计栏 - public R comboTotal(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_COMBO, handler -> ((DefaultComboHandler)handler).getTotal()); - } - - //combo数据过滤 - public R comboFilter(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_COMBO, handler -> ((DefaultComboHandler)handler).filter()); - } - - //树数据 - public R tree(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_TREE, handler -> ((AbstractTreeHandler)handler).data()); - } - - //树过滤 - public R treeFilter(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_TREE, handler -> ((AbstractTreeHandler)handler).filter()); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractDelHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractDelHandler.java deleted file mode 100644 index cdbaaf8..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractDelHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; -import lombok.extern.slf4j.Slf4j; - -/** - * Created by Akmm at 2022/3/2 19:44 - * 保存 - */ -@Slf4j -public abstract class AbstractDelHandler extends AbstractHandler{ - protected long id; - - public R del() { - id = readId(); - - checkValid(); - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - delDb(); - } - - @Override - public void doAfterDbCommit() { - super.doAfterDbCommit(); - saveSuccess(); - } - - @Override - public void doAfterDbRollback() { - super.doAfterDbRollback(); - saveFailed(); - } - }); - return R.success(); - } - - /** - * 读取页面传回来的id - * @return - */ - protected long readId() { - return params.readLong("id", 0L); - } - - protected abstract void checkValid(); - protected abstract void delDb(); - protected void saveSuccess() {} - protected void saveFailed() {} -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractHandler.java deleted file mode 100644 index 90c16e0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.session.UserSession; - -/** - * Created by Akmm at 2022/3/2 19:44 - */ -public abstract class AbstractHandler { - protected SwMap params; - protected UserSession us; - - public void init(SwMap params, UserSession us) { - this.params = params; - this.us = us; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractListHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractListHandler.java deleted file mode 100644 index e8b3376..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractListHandler.java +++ /dev/null @@ -1,235 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.cache.SessionCache; -import cc.smtweb.framework.core.cache.SessionCacheFactory; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.mvc.service.list.FooterField; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY; - -/** - * Created by Akmm at 2022/3/2 19:44 - * 列表服务 - */ -@Slf4j -public abstract class AbstractListHandler extends AbstractHandler { - protected static String KEY_SQLPARA = "query-sqlPara"; - protected static String KEY_SQLPARA_SUM = "query-sqlPara-sum"; - protected static String KEY_PARAMS = "query-params"; - - private SessionCache sessionCache; - - protected String getCompId() { - return this.getClass().getSimpleName(); - } - - protected T getCache(String key) { - if (sessionCache == null) - sessionCache = SessionCacheFactory.getInstance().getUserCache(us.getUserId()); - return sessionCache.get(getCompId() + "." + key); - } - - protected void setCache(String key, Object v) { - if (sessionCache == null) - sessionCache = SessionCacheFactory.getInstance().getUserCache(us.getUserId()); - sessionCache.put(getCompId() + "." + key, v); - } - - protected void removeCache(String key) { - if (sessionCache == null) - sessionCache = SessionCacheFactory.getInstance().getUserCache(us.getUserId()); - sessionCache.remove(getCompId() + "." + key); - } - - public R data() { - return R.success(buildListData()); - } - - public SwListData buildListData() { - List listData; - SqlPara sqlPara = buildDataSql(); - - - String sort = params.readString("sort"); - String order = params.readString("order"); - String sql; - if (StringUtils.isEmpty(sort)) sql = sqlPara.sql; - else { - sql = "select ar.* from (" + sqlPara.sql + ") ar order by ar." + sort + " " + order; - if (StringUtils.isNotEmpty(getPkFieldName())) { - sql += "," + getPkFieldName(); - } - } - - listData = queryData(sql, sqlPara); - - afterQuery(listData); - return SwListData.create(listData, sqlPara.rows); - } - - protected List queryData(String sql, SqlPara sqlPara) { - sqlPara.rows = params.readInt("rows", 0); - sqlPara.page = params.readInt("page", 1); - - - if (sqlPara.rows == 0) { - return DbEngine.getInstance().query(sql, SwMap.class, sqlPara.paras); - } else { - //查分页数据 - return DbEngine.getInstance().pagedQuery(sql, SwMap.class, (sqlPara.page - 1) * sqlPara.rows, sqlPara.rows, sqlPara.paras); - } - } - - protected SqlPara buildSumSqlPara() { - SqlPara sqlPara = getCache(KEY_SQLPARA); - if (sqlPara == null) return null; - - List footerFields = getFooterFields(); - StringBuilder sql = new StringBuilder(128); - sql.append("select count(1) " + TOTAL_KEY); - for (FooterField cn : footerFields) { - if (!FooterField.STATIC_TEXT.equals(cn.type)) { - if (FooterField.SUM_TYPE_COUNT_ALL.equals(cn.type)) { - sql.append(",COUNT("); - } else if (FooterField.SUM_TYPE_SUM_NUM.equals(cn.type)) { - sql.append(",SUM("); - } else { - sql.append(",").append(cn.type).append("("); - } - if (FooterField.SUM_TYPE_COUNT.equals(cn.type)) - sql.append("distinct "); - sql.append(cn.field).append(") ").append(cn.field); - } - } - sql.append(" from (").append(sqlPara.getSqlNoOrderBy()).append(") xxxxxz"); - - return new SqlPara(sql.toString(), sqlPara.paras); - } - - public R getTotal() { - try { - SqlPara sqlParaSum = getCache(KEY_SQLPARA_SUM); - if (sqlParaSum == null) { - Map map = getCache(KEY_PARAMS); - if (map != null) params.putAll(map); - sqlParaSum = buildSumSqlPara(); - } - if (sqlParaSum == null) return R.success(); - setCache(KEY_SQLPARA_SUM, sqlParaSum); - - SwMap mapFooter = DbEngine.getInstance().queryEntity(sqlParaSum.sql, SwMap.class, sqlParaSum.paras); - - SwMap r = new SwMap(); - r.put("total", mapFooter.get(TOTAL_KEY)); - r.put("footer", mapFooter); - return R.success(r); - } catch (Exception e) { - return R.error("计算合计失败!", e); - } - } - - protected SqlPara buildDataSql() { - //从缓存里看看有没有保存的sql缓存; - SqlPara sqlParaInCache = getCache(KEY_SQLPARA); //缓存里面的对象; - boolean query = sqlParaInCache == null || params.readBool("query"); - if (!query) { - Map map = getCache(KEY_PARAMS); - if (map == null) query = true; - else { - Map params = getCachedParams(); - if (params.size() > map.size()) query = true;//本次参数更多 - else { - for (String key : params.keySet()) { - Object v = map.get(key); - String cv = v != null && StringUtils.isNotEmpty(v.toString()) ? v.toString() : ""; - v = params.get(key); - String rv = v != null && StringUtils.isNotEmpty(v.toString()) ? v.toString() : ""; - if (!cv.equals(rv)) { - query = true; - break; - } - } - } - } - } - SqlPara sqlPara = null; - if (query) {//新查询 - //缓存里面没有对象,重新构建查询条件,重新计算汇总数; - buildParam();//构造过滤条件,设默认值 - sqlPara = buildSqlPara(); //重新构建查询对象; - removeCache(KEY_SQLPARA_SUM); - - setCache(KEY_SQLPARA, sqlPara); - setCache(KEY_PARAMS, getCachedParams());//不缓存页码之类的东东,避免下次请求时,页码又回去了 - } else { - sqlPara = sqlParaInCache; - - Map map = getCache(KEY_PARAMS); - if (map != null) params.putAll(map); - } - return sqlPara; - } - - /** - * 构造过滤条件,设默认值 - * - * @throws Exception - */ - protected void buildParam() { - - } - - /** - * sql主键字段,用于点击表头排序时保证排序记录唯一性 - * - * @return - */ - protected String getPkFieldName() { - return null; - } - - protected void afterQuery(List listData) { - } - - protected abstract SqlPara buildSqlPara(); - - //构建合计字段 - private List getFooterFields() { - List footerFields = new ArrayList<>(); - buildFooterFields(footerFields); - return footerFields; - } - - protected void buildFooterFields(List footer) { - } - - protected Map getCachedParams() { - Map map = new HashMap<>(); - map.putAll(params); - map.remove("page"); - map.remove("rows"); - map.remove("sort"); - map.remove("order"); - map.remove("tokenkey"); - map.remove("tokenval"); - map.remove("_v"); - map.remove("_dn"); - map.remove("_sk"); - map.remove("_skw"); - map.remove("_tk"); - map.remove("_sb"); - map.remove("__exp_model"); - map.remove("model"); - map.remove("data"); - return map; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractLoadHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractLoadHandler.java deleted file mode 100644 index 8f36e81..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractLoadHandler.java +++ /dev/null @@ -1,32 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.R; - -/** - * Created by Akmm at 2022/3/2 19:44 - */ -public abstract class AbstractLoadHandler extends AbstractHandler { - - public R load() { - long id = readId(); - T bean; - if (id <= 0L) { - bean = createComp(); - } else { - bean = loadComp(id); - } - return R.success(bean); - } - - /** - * 读取页面传回来的id - * @return - */ - protected long readId() { - return params.readLong("id", 0L); - } - - protected abstract T createComp(); - - protected abstract T loadComp(long id); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractSaveHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractSaveHandler.java deleted file mode 100644 index 26b4b16..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractSaveHandler.java +++ /dev/null @@ -1,87 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; -import lombok.extern.slf4j.Slf4j; - -/** - * Created by Akmm at 2022/3/2 19:44 - * 保存 - */ -@Slf4j -public abstract class AbstractSaveHandler extends AbstractHandler { - protected T bean; - protected boolean isNew; - - - - public R save() { - long id = readId(); - - isNew = id <= 0L; - if (isNew) { - bean = createComp(); - } else { - bean = loadComp(id); - } - readFromPage(); - if (isNew) { - setNewId(); - } - checkValid(); - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work(){ - saveDb(); - } - - @Override - public void doAfterDbCommit(){ - saveSuccess(); - } - - @Override - public void doAfterDbRollback(){ - saveFailed(); - } - }); - return R.success(bean); - } - - /** - * 读取页面传回来的id - * - * @return - */ - protected long readId() { - return params.readLong("id", 0L); - } - protected abstract void setNewId(); - - //从页面读取数据 - protected abstract void readFromPage(); - - //保存前的校验 - protected abstract void checkValid(); - - //保存到数据库 - protected abstract void saveDb(); - - //保存成功之后 - protected void saveSuccess() { - } - - //保存失败之后 - protected void saveFailed() { - } - - //构建一个新对象 - protected abstract T createComp(); - - //从数据库读取 - protected abstract T loadComp(long id); - - //树,改变父亲 - public abstract R changeParent(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractTreeHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractTreeHandler.java deleted file mode 100644 index 0bd7382..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/AbstractTreeHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import lombok.extern.slf4j.Slf4j; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Akmm at 2022/3/2 19:44 - * 列表服务 - */ -@Slf4j -public abstract class AbstractTreeHandler extends AbstractHandler { - //树过滤 - public R filter() { - List rows = filterData(); - List listRet = buildNodes(rows, true); - return R.success(listRet); - } - - public R data() { - List rows = getChildren(params.readLong("parent_id")); - List listRet = buildNodes(rows, params.readBool("lazy")); - - return R.success(listRet); - } - - //搜索 - protected abstract List filterData(); - //获取指定节点的下级节点 - protected abstract List getChildren(long id); - protected List getChildren(T bean) { - return getChildren(getId(bean)); - } - - //根据bean,构建treenode - private List buildNodes(List rows, boolean lazy) { - List listRet = new ArrayList<>(); - if (rows == null || rows.isEmpty()) { - return listRet; - } - for (T row : rows) { - SwMap node = new SwMap(); - node.put("id", getId(row)); - node.put("text", getText(row)); - List children = getChildren(row); - node.put("leaf", children == null || children.isEmpty()); - node.put("bean", row); - buildNode(node, row); - listRet.add(node); - if (!lazy) { - List list = buildNodes(children, lazy); - node.put("children", list); - } - } - return listRet; - } - - //根据bean,构建treenode - protected void buildNode(SwMap node, T bean) {} - - protected abstract long getId(T bean); - - protected abstract String getText(T bean); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultComboHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultComboHandler.java deleted file mode 100644 index 296a35d..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultComboHandler.java +++ /dev/null @@ -1,84 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Created by Akmm at 2022/3/2 19:52 - * 默认实体实现 - */ -public class DefaultComboHandler extends DefaultListHandler { - - public DefaultComboHandler(String tableName) { - super(tableName); - } - - public R filter() { - return R.success(filterData()); - } - - protected SwListData filterData() { - String text = params.readString("text"); - if (StringUtils.isEmpty(text)) throw new BizException("没有搜素内容!"); - - SqlPara sqlPara = buildDataSql(); - String sort = params.readString("sort"); - String order = params.readString("order"); - - StringBuilder sqlFilter = new StringBuilder(); - List args = new ArrayList<>(sqlPara.paras.length); - Collections.addAll(args, sqlPara.paras); - - buildFilterCondition(text, sqlFilter, args); - if (sqlFilter.length() == 0) throw new BizException("没有待搜索的字段!"); - - String sql = "select ar.* from (" + sqlPara.sql + ") ar where " + sqlFilter.substring(4); - if (StringUtils.isNotEmpty(sort)) { - sql += " order by ar." + sort + " " + order; - if (StringUtils.isNotEmpty(getPkFieldName())) { - sql += "," + getPkFieldName(); - } - } - - List listData = DbEngine.getInstance().pagedQuery(sql, SwMap.class, 0, 10, args.toArray()); - afterQuery(listData); - return SwListData.create(listData, 0); - } - - //搜索条件 - protected void buildFilterCondition(String text, StringBuilder sqlFilter, List args) { - List fields = new ArrayList<>(); - getFilterFields(fields); - if (fields.isEmpty()) return; - - text = text + "%";//combo不支持全模糊 - for (String field: fields) { - sqlFilter.append(" or " + field + " like ?"); - args.add(text); - } - - } - - //构建参与搜索的字段,默认为code和name字段 - protected void getFilterFields(List fields) { - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - ModelField field = table.findFieldByType(SwEnum.FieldType.CODE.value); - if (field != null) fields.add(field.getName()); - - field = table.findFieldByType(SwEnum.FieldType.NAME.value); - if (field != null) fields.add(field.getName()); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultDelHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultDelHandler.java deleted file mode 100644 index de73fc3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultDelHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.EntityHelper; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelTable; - -/** - * Created by Akmm at 2022/3/2 19:52 - * 默认实体实现 - */ -public class DefaultDelHandler extends AbstractDelHandler { - protected String tableName; - - public DefaultDelHandler(String tableName) { - this.tableName = tableName; - } - - @Override - protected void checkValid() { - EntityHelper.checkExists(tableName, id); -// ModelTable table = ModelTableCache.getInstance().getByName(tableName); - //todo 检查外键引用的使用情况 - - } - - @Override - protected void delDb() { - EntityDao dao = DbEngine.getInstance().findDao(tableName); - dao.deleteEntity(id); - } - - @Override - protected void saveSuccess() { - super.saveSuccess(); - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table.isNeedCache()) { - AbstractCache cache = CacheManager.getIntance().getCache(tableName); - cache.remove(id); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultListHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultListHandler.java deleted file mode 100644 index 791756b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultListHandler.java +++ /dev/null @@ -1,73 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.EntityHelper; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Akmm at 2022/3/2 19:52 - * 默认实体实现 - */ -public class DefaultListHandler extends AbstractListHandler { - protected String tableName; - - public DefaultListHandler(String tableName) { - this.tableName = tableName; - } - - @Override - protected SqlPara buildSqlPara() { - EntityDao dao = DbEngine.getInstance().findDao(tableName); - StringBuilder sql = new StringBuilder(512); - List args = new ArrayList<>(); - dao.handleSelect(sql, null); - - StringBuilder sqlCondition = new StringBuilder(128); - buildCondition(sqlCondition, args); - String filter = sqlCondition.toString().trim(); - if (StringUtils.isNotEmpty(filter)) { - if (filter.startsWith("or ")) { - sql.append("\nwhere ").append(filter.substring(3)); - } else if (filter.startsWith("and ")) { - sql.append("\nwhere ").append(filter.substring(4)); - } else if (!filter.startsWith("where ")) { - sql.append("\nwhere ").append(filter); - } else { - sql.append(filter); - } - } - - buildOrder(sql); - - return new SqlPara(sql.toString(), args.toArray()); - } - - protected void buildCondition(StringBuilder sql, List args) { - } - - protected void buildOrder(StringBuilder sql) { - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table == null) return; - sql.append(" order by "); - - ModelField field = table.findFieldByType(SwEnum.FieldType.CODE.value); - if (field != null) sql.append(field.getName()).append(","); - sql.append(table.getIdField()); - } - - @Override - protected void afterQuery(List listData) { - super.afterQuery(listData); - EntityHelper.loadBeanLink(tableName, listData, null); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultLoadHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultLoadHandler.java deleted file mode 100644 index a42639f..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultLoadHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; - -/** - * Created by Akmm at 2022/3/2 19:52 - * 默认实体实现 - */ -public class DefaultLoadHandler extends AbstractLoadHandler { - protected String tableName; - - public DefaultLoadHandler(String tableName) { - this.tableName = tableName; - } - - @Override - protected T createComp() { - final EntityDao dao = DbEngine.getInstance().findDao(tableName); - T bean = dao.createBean(); - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - ModelField field = table.findFieldByType(SwEnum.FieldType.CREATE_USER.value); - if (field != null) bean.put(field.getName(), us.getUserId()); - return bean; - } - - @Override - protected T loadComp(long id) { - return new DefaultProvider(tableName).getBean(id); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultProvider.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultProvider.java deleted file mode 100644 index 3f15f88..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.EntityHelper; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/3/3 20:04 - */ -public class DefaultProvider extends AbstractCompProvider { - public String tableName; - - public DefaultProvider(String tableName) { - this.tableName = tableName; - } - - public T getBean(long id) { - return doGetData(tableName + "." + id, () -> this.loadBean(id)); - } - - private T loadBean(long id) { - EntityDao bdao = (EntityDao) DbEngine.getInstance().findDao(tableName); - T bean = bdao.queryEntity(id); - if (bean == null) throw new BizException("没有找到指定数据(id=" + id + ")"); - EntityHelper.loadBeanLink(bean.getTableName(), bean.getData(), null); - return bean; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultSaveHandler.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultSaveHandler.java deleted file mode 100644 index 0a0defa..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/DefaultSaveHandler.java +++ /dev/null @@ -1,176 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelIndex; -import cc.smtweb.framework.core.db.vo.ModelTable; -import org.apache.commons.lang3.StringUtils; - -import java.util.List; - -/** - * Created by Akmm at 2022/3/2 19:52 - * 默认实体实现 - */ -public class DefaultSaveHandler extends AbstractSaveHandler { - protected String tableName; - - private List listTreeBean = null; - - public DefaultSaveHandler(String tableName) { - this.tableName = tableName; - } - - @Override - protected T createComp() { - final EntityDao dao = DbEngine.getInstance().findDao(tableName); - T bean = dao.createBean(); - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - ModelField field = table.findFieldByType(SwEnum.FieldType.CREATE_USER.value); - if (field != null) bean.put(field.getName(), us.getUserId()); - field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); - if (field != null) bean.put(field.getName(), us.getUserId()); - return bean; - } - - @Override - protected long readId() { - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - return params.readLong(table.getIdField()); - } - - @Override - protected void setNewId() { - bean.setEntityId(DbEngine.getInstance().nextId()); - } - - @Override - protected T loadComp(long id) { - return new DefaultProvider(tableName).getBean(id); - } - - @Override - protected void readFromPage() { - bean.readFromMap(params); - } - - @Override - protected void checkValid() { - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - for (ModelField field : table.getFields()) { - if (field.isNotNull() && StringUtils.isEmpty(bean.getStr(field.getName()))) { - throw new BizException(field.getTitle() + "不能为空!"); - } - if (field.getFieldType() == SwEnum.FieldType.PARENT_ID.value) { - TreeHelper.getTreeHelper(tableName).checkParent(bean); - } - } - - EntityDao dao = DbEngine.getInstance().findDao(tableName); - for (ModelIndex mi : table.getIndexes()) { - if (mi.isUnique()) { - dao.checkUnique(bean, mi.getFields().split(",")); - } - } - } - - @Override - protected void saveDb() { - EntityDao dao = DbEngine.getInstance().findDao(tableName); - if (isNew) { - dao.insertEntity(bean); - } else { - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); - if (field != null) bean.put(field.getName(), us.getUserId()); - - updateBean(dao); - if (table.getType() == SwEnum.TableType.TYPE_TREE.value) { - listTreeBean = TreeHelper.getTreeHelper(tableName).resetTreeLevel(bean); - } - } - } - - //更新入库 - protected void updateBean(EntityDao dao) { - dao.updateEntity(bean); - } - - - @Override - protected void saveSuccess() { - super.saveSuccess(); - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table.isNeedCache()) { - AbstractCache cache = CacheManager.getIntance().getCache(tableName); - //树型表,父亲改变了,要多处理下缓存;还有个东东:级次码 - if (listTreeBean != null && !listTreeBean.isEmpty()) { - for (T b : listTreeBean) { - cache.put(b); - } - } else { - cache.put(bean); - } - } - } - - @Override - protected void saveFailed() { - super.saveFailed(); - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table.isNeedCache()) { - AbstractCache cache = CacheManager.getIntance().getCache(tableName); - cache.reset(bean); - } - } - - //树,改变父亲 - public R changeParent(){ - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table.getType() != SwEnum.TableType.TYPE_TREE.value) throw new BizException("非树型表,不支持更改父节点"); - - long id = params.readLong("id"); - long parentId = params.readLong("parent_id"); - - AbstractCache cache = CacheManager.getIntance().getCache(tableName); - if (table.isNeedCache()) { - bean = cache.get(id); - } else { - bean = loadComp(id); - } - TreeHelper.getTreeHelper(tableName).checkParent(bean); - //不考虑没有级次码等情况,这个在表设计时校验 - ModelField fieldParentId = table.findFieldByType(SwEnum.FieldType.PARENT_ID.value); - - bean.put(fieldParentId.getName(), parentId); - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - EntityDao dao = DbEngine.getInstance().findDao(tableName); - listTreeBean = TreeHelper.getTreeHelper(tableName).resetTreeLevel(bean); - dao.updateEntity(bean, fieldParentId.getName()); - } - - @Override - public void doAfterDbCommit(){ - saveSuccess(); - } - - @Override - public void doAfterDbRollback() { - saveFailed(); - } - }); - return R.success(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/IDataProvider.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/IDataProvider.java deleted file mode 100644 index 84f130e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/IDataProvider.java +++ /dev/null @@ -1,8 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -/** - * Created by Akmm at 2022/3/3 12:10 - */ -public interface IDataProvider { - T load(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/IWorker.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/IWorker.java deleted file mode 100644 index a37939e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/IWorker.java +++ /dev/null @@ -1,11 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.R; - -/** - * Created by Akmm at 2022/3/2 19:01 - * 所有handler的接口 - */ -public interface IWorker { - R doWork(AbstractHandler handler); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlNamedPara.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlNamedPara.java deleted file mode 100644 index 9c6177e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlNamedPara.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.common.SwMap; - -import java.util.HashMap; -import java.util.Map; - -//一个sql及其参数,具名参数 -public class SqlNamedPara extends SqlPara { - public SwMap mapParas = new SwMap(); - //字段别名 - public Map mapFieldAlias = new HashMap<>(); - - public SqlNamedPara(String sql) { - this.sql = sql; - } - - public SqlNamedPara(String sql, SwMap paras) { - this.sql = sql; - this.mapParas = paras; - } - - public void addParas(String name, Object value) { - mapParas.put(name, value); - } - - public void addFieldAlias(String fieldName, String alias) { - mapFieldAlias.put(fieldName, alias); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlPara.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlPara.java deleted file mode 100644 index 2c07fe0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SqlPara.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -//一个sql及其参数 -public class SqlPara { - public String sql; - public Object[] paras; - public int rows; - public int page; - - public SqlPara() { - } - - public SqlPara(String sql, Object... paras) { - this.sql = sql; - this.paras = paras; - } - - //获取不带order by 的sql语句 - public String getSqlNoOrderBy() { - String sSql = sql.toUpperCase(); - int n = sSql.lastIndexOf("ORDER BY ");//截取最后一个 order by - if (n < 0) return sql; - String retSql = sql.substring(0, n); - String s = sSql.substring(n); - if (s.contains("SELECT")) return sql; //最后一个order by之后,有子查询的不算 - if (!s.contains(")")) return retSql; //校验order by之后带括号的情况,一般是表达式 - n = 0; - for (int i = 0, len = s.length(); i < len; i++) { - final char c = s.charAt(i); - if (c == '(') n++; - else if (c == ')') n--; - if (n < 0) return sql; - } - return retSql; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SwListData.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SwListData.java deleted file mode 100644 index d2299d2..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/SwListData.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import lombok.Getter; - -import java.util.ArrayList; -import java.util.List; - -@Getter -public class SwListData { - public static final SwListData EMPTY = new SwListData(new ArrayList<>(), 0); - - private final List rows; - // 总数, -1 表示需要异步获取数量, >=0 表示总数 - private int total = 0; - - private SwListData(List rows, int total) { - this.rows = rows; - this.total = total; - } - - public static SwListData create(List list, int rows) { - if (list == null) { - return SwListData.EMPTY; - } - - if (rows > 0 && list.size() >= rows) { - return new SwListData(list, -1); - } else { - return new SwListData(list, list.size()); - } - } - - public boolean isEmpty() { - return this.rows == null || this.rows.isEmpty(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java deleted file mode 100644 index 413bb37..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java +++ /dev/null @@ -1,132 +0,0 @@ -package cc.smtweb.framework.core.mvc.service; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Created by Akmm at 2022/3/17 19:56 - */ -public class TreeHelper { - private static Map mapInstance; - static { - mapInstance = new ConcurrentHashMap<>(); - } - private String tableName; - - private ModelTable table; - protected AbstractCache cache; - private EntityDao dao; - - private String fieldParent; - private String fieldLevelCode; - - - public static TreeHelper getTreeHelper(String tableName) { - return mapInstance.computeIfAbsent(tableName, k-> new TreeHelper(tableName)); - } - - public static TreeHelper getTreeHelper(String tableName, Class clazz) { - TreeHelper helper = mapInstance.get(tableName); - if (helper == null) { - try { - helper = clazz.newInstance(); - mapInstance.put(tableName, helper); - } catch (Exception e) { - throw new SwException(e); - } - } - return helper; - } - - //先禁止外部创建 - protected TreeHelper(String tableName) { - this.tableName = tableName; - table = ModelTableCache.getInstance().getByName(tableName); - cache = CacheManager.getIntance().getCache(tableName); - dao = DbEngine.getInstance().findDao(tableName); - - ModelField field = table.findFieldByType(SwEnum.FieldType.PARENT_ID.value); - fieldParent = field.getName(); - field = table.findFieldByType(SwEnum.FieldType.LEVEL_CODE.value); - fieldLevelCode = field.getName(); - } - - public long getParentId(T bean) { - return bean.getLong(fieldParent); - } - - public String getLevelCode(T bean) { - return bean.getStr(fieldLevelCode); - } - - public Collection getChildren(T bean) { - return getChildren(bean.getEntityId()); - } - - public Collection getChildren(long id) { - return cache.getListByKey(SwConsts.KEY_PARENT_ID, String.valueOf(id)); - } - - public List getChildren(long id, Comparator comparator) { - Collection set = cache.getListByKey(SwConsts.KEY_PARENT_ID, String.valueOf(id)); - - List list = set == null ? new ArrayList<>(): new ArrayList<>(set); - if (comparator != null) - list.sort(comparator); - return list; - } - - public void checkParent(T bean) { - if (table.getType() != SwEnum.TableType.TYPE_TREE.value) return; - if (!table.isNeedCache()) throw new BizException("请将树型表定义为需要缓存!"); - long pId = getParentId(bean); - if (bean.getEntityId() == pId) throw new BizException("上级节点不能为自己!"); - if (pId <= 0) return; - T parent = cache.get(pId); - if (parent == null) return; - String plevelcode = SwConsts.SPLIT_CHAR + parent.getStr(fieldLevelCode) + SwConsts.SPLIT_CHAR; - if (plevelcode.contains(SwConsts.SPLIT_CHAR + bean.getEntityId() + SwConsts.SPLIT_CHAR)) { - throw new BizException("上级节点不能为自己的下级!"); - } - } - - public List resetTreeLevel(T bean) { - List list = new ArrayList<>(); - if (table.getType() != SwEnum.TableType.TYPE_TREE.value) return list; - if (!table.isNeedCache()) throw new BizException("请定义为需要缓存!"); - - T oldBean = cache.get(bean.getEntityId()); - if (bean.getLong(fieldParent) != oldBean.getLong(fieldParent)) { - resetParentChildren(bean, list); - } - return list; - } - - private void resetParentChildren(T bean, List list) { - T parent = cache.get(getParentId(bean)); - if (parent != null) { - bean.put(fieldLevelCode, getLevelCode(parent) + SwConsts.SPLIT_CHAR + parent.getEntityId()); - dao.updateEntity(bean, fieldLevelCode); - list.add(bean); - } - Collection children = getChildren(bean); - if (children != null && !children.isEmpty()) { - for (T child : children) { - resetParentChildren(child, list); - } - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/list/FooterField.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/list/FooterField.java deleted file mode 100644 index 2da36c6..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/service/list/FooterField.java +++ /dev/null @@ -1,57 +0,0 @@ -package cc.smtweb.framework.core.mvc.service.list; - -/** - * Created by Akmm at 13-4-16 上午10:51 - * 合计行列定义 - */ -public class FooterField { - //计数 不同值计数 - public static final String SUM_TYPE_COUNT = "COUNT"; - //计数 记录数 - public static final String SUM_TYPE_COUNT_ALL = "COUNT_A"; - //求和 - public static final String SUM_TYPE_SUM = "SUM"; - //整数求和 - public static final String SUM_TYPE_SUM_NUM = "SUM_NUM"; - //平均数 - public static final String SUM_TYPE_AVG = "AVG"; - //最大值 - public static final String SUM_TYPE_MAX = "MAX"; - //最小值 - public static final String SUM_TYPE_MIN = "MIN"; - //静态文本 - public static final String STATIC_TEXT = "TEXT"; - - public String field; - public String type; - public String text; - - public FooterField() { - } - - public FooterField(String field, String type, String text) { - this.field = field; - this.type = type; - this.text = text; - } - - public String toString() { - return "field=" + field + ";type=" + type + ";text=" + text; - } - - public static FooterField newSumField(String field) { - return new FooterField(field, SUM_TYPE_SUM, null); - } - - public static FooterField newCountField(String field) { - return new FooterField(field, SUM_TYPE_COUNT, null); - } - - public static FooterField newTextField(String field, String text) { - return new FooterField(field, STATIC_TEXT, text); - } - - public static FooterField newSumField(String field, String type) { - return new FooterField(field, type, null); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/ICalcVar.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/ICalcVar.java deleted file mode 100644 index 4a85ec9..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/ICalcVar.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.smtweb.framework.core.mvc.variable; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.session.UserSession; - -/** - * Created by Akmm at 2022/5/12 9:07 - * 计算并返回变量值 - */ -public interface ICalcVar { - /** - * 计算并返回变量值 - * @param params 参数 - * @param us 用户会话信息 - * @return - */ - Object calcVar(SwMap params, UserSession us); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariable.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariable.java deleted file mode 100644 index a952274..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariable.java +++ /dev/null @@ -1,26 +0,0 @@ -package cc.smtweb.framework.core.mvc.variable; - -import lombok.Data; - -/** - * Created by Akmm at 2022/5/12 9:11 - * 变量定义信息 - */ -@Data -public class SwVariable { - //变量名 - private String name; - //中文标题 - private String label; - //描述 - private String remark; - //计算值的方法 - private ICalcVar calcVar; - - public SwVariable(String name, String label, String remark, ICalcVar calcVar) { - this.name = name; - this.label = label; - this.remark = remark; - this.calcVar = calcVar; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariableFactory.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariableFactory.java deleted file mode 100644 index dfbb34e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/mvc/variable/SwVariableFactory.java +++ /dev/null @@ -1,45 +0,0 @@ -package cc.smtweb.framework.core.mvc.variable; - -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.session.UserSession; -import cc.smtweb.framework.core.util.DateUtil; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by Akmm at 2022/5/11 19:07 - * 变量工厂,变量的注册及计算 - */ -public class SwVariableFactory { - private static SwVariableFactory instance; - static { - instance = new SwVariableFactory(); - } - - public static SwVariableFactory getInstance() { - return instance; - } - - //记录变量信息 - private Map map = new HashMap<>(); - private SwVariableFactory() { - regVariable("SYS_DATE", "当前日期", "YYYYMMDD格式", (params, us) -> DateUtil.nowDateLong()); - regVariable("CUR_USER_ID", "当前操作员id", "当前操作员主键", (params, us) -> us.getUserId()); - } - - //注册变量 - public void regVariable(String name, String label, String remark, ICalcVar calcVar) { - if (map.containsKey(name)) throw new BizException("变量重复定义:name=" + name); - map.put(name, new SwVariable(name, label, remark, calcVar)); - } - - //计算变量值 - public Object calcVar(String name, SwMap params, UserSession us) { - SwVariable var = map.get(name); - if (var == null) throw new BizException("没有定义此变量:" + name); - return var.getCalcVar().calcVar(params, us); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/SessionManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/SessionManager.java deleted file mode 100644 index b03e1c4..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/SessionManager.java +++ /dev/null @@ -1,73 +0,0 @@ -package cc.smtweb.framework.core.session; - -import cc.smtweb.framework.core.cache.redis.RedisBroadcastEvent; -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.db.jdbc.IdGenerator; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import org.apache.commons.lang3.StringUtils; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.RequestContextHolder; - -import java.util.Random; - -public class SessionManager { - private final RedisManager redisManager; - private final IdGenerator idGenerator; - - public SessionManager(RedisManager redisManager, IdGenerator idGenerator) { - this.redisManager = redisManager; - this.idGenerator = idGenerator; - } - - // 登录,产生session - public String login(UserSession userSession) { - if (userSession != null) { - String sid = RedisManager.PREFIX_SESSION + Long.toHexString(idGenerator.nextId()) + "_" + Integer.toHexString(new Random().nextInt()); - - redisManager.set(sid, userSession, RedisManager.SESSION_EXPIRE_SEC); - - return sid; - } - - return null; - } - - public void logout() { - String sid = (String)RequestContextHolder.currentRequestAttributes().getAttribute(IEditor.USER_TOKEN, RequestAttributes.SCOPE_REQUEST); - if (StringUtils.isNoneBlank(sid)) { - redisManager.del(sid); - } - } - - // token延时 - public boolean flush(String token) { - if (token != null) { - // 更新Token redis TTL - return redisManager.expire(token, RedisManager.SESSION_EXPIRE_SEC); - } - - return false; - } - - /** - * 清除指定用户权限本地缓存 - * @param userId 用户ID - */ - public void removePermits(long userId) { - RedisBroadcastEvent event = new RedisBroadcastEvent(); - event.setAction(RedisBroadcastEvent.CODE_REMOVE); - event.setIdent("ReamlCache"); - event.setKey(userId + ""); - redisManager.publish(event); - } - - /** - * 清除所有用户权限本地缓存 - */ - public void clearPermits() { - RedisBroadcastEvent event = new RedisBroadcastEvent(); - event.setAction(RedisBroadcastEvent.CODE_CLEAR); - event.setKey("ReamlCache"); - redisManager.publish(event); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java deleted file mode 100644 index 09e63a6..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java +++ /dev/null @@ -1,109 +0,0 @@ -package cc.smtweb.framework.core.session; - -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.mvc.controller.IEditor; -import cc.smtweb.framework.core.mvc.realm.exception.UnauthenticatedException; -import org.apache.commons.lang3.StringUtils; -import org.springframework.web.context.request.RequestContextHolder; - -import javax.servlet.http.HttpServletRequest; - -/** - * 〈session工具类〉 - * - * @author kevin - * @since 1.0.0 - */ -public class SessionUtil { - private SessionUtil() { - } - - public static Object getSession() { - return RequestContextHolder.currentRequestAttributes().getAttribute(IEditor.USER_SESSION, 0); - } - - public static String readToken(HttpServletRequest request) { - String token = request.getHeader("Auth-Token"); - - if (token == null) { - token = request.getParameter("auth_token"); - } - return token; - } - - public static UserSession checkSession(HttpServletRequest request, RedisManager redisManager) { - String token = readToken(request); - - if (StringUtils.isBlank(token)) { - throw new UnauthenticatedException("not find Auth-Token in header"); - } - - UserSession us = redisManager.get(token, UserSession.class); - if (us == null) { - throw new UnauthenticatedException("not find UserSession by token: " + token); - } - - return us; - } - - - public static UserSession checkSession(String accessToken, RedisManager redisManager) { - if (StringUtils.isBlank(accessToken)) { - throw new UnauthenticatedException("not find Auth-Token in header"); - } - - UserSession us = redisManager.get(accessToken, UserSession.class); - if (us == null) { - throw new UnauthenticatedException("not find UserSession by token: " + accessToken); - } - - return us; - } - -// private static Session getShiroSession() { -// Session session = SecurityUtils.getSubject().getSession(); -// if (session == null) { -// throw new SmartException(ExceptionMessage.NO_LOGIN_ERROR); -// } -// return session; -// } - -// public static String getSid() { -// return getShiroSession().getId().toString(); -// } - -// public static UserSession getSession() { -// Object session = getShiroSession().getAttribute(USER_SESSION); -// if (session == null) { -// throw new SmartException(ExceptionMessage.NO_LOGIN_ERROR); -// } -// UserSession userSession = (UserSession) session; -// if (userSession.isChange()) { -// throw new SmartException(ExceptionMessage.USER_PERMISSION_CHANGE); -// } -// return userSession; -// } -// -// public static void updateSession(UserSession userSession) { -// getShiroSession().setAttribute(USER_SESSION, userSession); -// } - -// public static String login(String userName, UserSession userSession) { -// // 通过 shiro 登录验证 -// Subject subject = SecurityUtils.getSubject(); -// try { -// // 统一默认密码登录 -// subject.login(new UsernamePasswordToken(userName, CommonUtil.INIT_PASSWORD)); -// } catch (ShiroException ex) { -// throw new SmartException(ExceptionMessage.USER_ERROR); -// } -// -// Session session = subject.getSession(); -// if (session == null) { -// throw new SmartException(ExceptionMessage.NO_LOGIN_ERROR); -// } -// -// session.setAttribute(USER_SESSION, userSession); -// return session.getId().toString(); -// } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/UserSession.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/UserSession.java deleted file mode 100644 index 492c6cf..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/UserSession.java +++ /dev/null @@ -1,31 +0,0 @@ -package cc.smtweb.framework.core.session; - -import lombok.Getter; -import lombok.Setter; - -import java.io.Serializable; - -/** - * 用户会话缓存,前端调用API时传输 Auto_Token 参数来查找用户会话 - * @author xkliu - */ -@Getter @Setter -public class UserSession implements Serializable { - private static final long serialVersionUID = 3854315462714888716L; - // 用户ID - private long userId; - // 当前组织ID - private long companyId; - // 站点ID - private long siteId; - // 终端类型 - private byte terminalType; - - public static UserSession createSys() { - UserSession us = new UserSession(); - us.userId = 1; - us.companyId = 1; - us.terminalType = 0; - return us; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/UserSessionArgumentResolver.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/UserSessionArgumentResolver.java deleted file mode 100644 index fc9e21c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/session/UserSessionArgumentResolver.java +++ /dev/null @@ -1,26 +0,0 @@ -package cc.smtweb.framework.core.session; - -import cc.smtweb.framework.core.mvc.controller.IEditor; -import org.springframework.core.MethodParameter; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.method.support.ModelAndViewContainer; - -/** - * spring 参数拦截器,提供UserSession在@Service的函数参数中@Param使用 - * @author kevin - */ -public class UserSessionArgumentResolver implements HandlerMethodArgumentResolver { - @Override - public boolean supportsParameter(MethodParameter methodParameter) { - return methodParameter.getParameterType().isAssignableFrom(UserSession.class); - } - - @Override - public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { - return nativeWebRequest.getAttribute(IEditor.USER_SESSION, RequestAttributes.SCOPE_REQUEST); -// return SessionUtil.getSession(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/ISysTask.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/ISysTask.java deleted file mode 100644 index cb5d8ec..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/ISysTask.java +++ /dev/null @@ -1,8 +0,0 @@ -package cc.smtweb.framework.core.systask; - -/** - * 任务接口 - */ -public interface ISysTask { - int run(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/SysTaskManager.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/SysTaskManager.java deleted file mode 100644 index 2a5a5c1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/SysTaskManager.java +++ /dev/null @@ -1,40 +0,0 @@ -package cc.smtweb.framework.core.systask; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.event.EventListener; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.List; - -@Service -public class SysTaskManager { - @Autowired - private ApplicationContext applicationContext; - - private List tasks = new ArrayList<>(); - - public void add(ISysTask task) { - tasks.add(task); - } - - @EventListener - public void onTaskStartEvent(TaskStartEvent event) { - runAll(); - } - - // 每隔60秒定时执行 -// @Scheduled(fixedRate = 60000) -// public void fixedRateJob() { -// System.out.println("fixedRate 每隔60秒" + new java.util.Date()); -// -// runAll(); -// } - - private void runAll() { - for (ISysTask task : tasks) { - task.run(); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/TaskStartEvent.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/TaskStartEvent.java deleted file mode 100644 index 35b8bf0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/TaskStartEvent.java +++ /dev/null @@ -1,4 +0,0 @@ -package cc.smtweb.framework.core.systask; - -public class TaskStartEvent { -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/WebStartedEvent.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/WebStartedEvent.java deleted file mode 100644 index cd8bba0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/systask/WebStartedEvent.java +++ /dev/null @@ -1,4 +0,0 @@ -package cc.smtweb.framework.core.systask; - -public class WebStartedEvent { -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/CommUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/CommUtil.java deleted file mode 100644 index f616640..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/CommUtil.java +++ /dev/null @@ -1,140 +0,0 @@ -package cc.smtweb.framework.core.util; - -import cc.smtweb.framework.core.db.impl.BaseBean; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.util.kryo.KryoTool; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.io.Serializable; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.nio.charset.StandardCharsets; -import java.text.Collator; -import java.util.Collection; -import java.util.HashSet; -import java.util.Locale; -import java.util.Set; - -/** - * Created by Akmm at 2022/1/5 9:10 - * 通用工具类 - */ -@Slf4j -public class CommUtil { - private static Collator chineseCollator = Collator.getInstance(Locale.CHINA); - - /** - * 找指定类的泛型类 - * @param cls - * @param - * @return - */ - public static Class getParameterizedType(Class cls) { - while (cls != null) { //找到泛型类 - Type pt = cls.getGenericSuperclass(); - if (pt instanceof ParameterizedType) { - return (Class) ((ParameterizedType) pt).getActualTypeArguments()[0]; - } - cls = (Class) pt; - } - return null; - } - - /** - * 序列化对象 - * @param obj - * @param - * @return - */ - public static byte[] writeObject(T obj) { - return KryoTool.getINST().writeObject(obj); - } - - /** - * 反序列化 - * @param data - * @param clazz - * @param - * @return - */ - public static T readObject(byte[] data, Class clazz) { - return KryoTool.getINST().readObject(data, clazz); - } - - public static T cloneObj(T obj, Class cls) { - byte[] data = writeObject(obj); - return readObject(data, cls); - } - - public static boolean isEmpty(Collection c) { - return c == null || c.isEmpty(); - } - - /** - * 从DefaultEntity实体转成自己的对象类 - * @param bean - * @param clazz - * @param - * @return - */ - public static T castEntity(DefaultEntity bean, Class clazz) { - try { - T ret = clazz.newInstance(); - ret.getData().putAll(bean.getData()); - return ret; - } catch (Exception e) { - log.error("转换bean失败:", e); - return null; - } - } - - /*public static String getSqlInIds(Collection ids) { - if (null == ids || ids.isEmpty()) return ""; - StringBuilder s = new StringBuilder(128); - Set set = new HashSet<>(); - for (String id : ids) { - if (set.contains(id)) continue; - set.add(id); - if (StringUtils.isEmpty(id)) continue; - s.append(id).append(","); - } - if (s.length() == 0) return ""; - return s.substring(0, s.length() - 1); - }*/ - - public static String getSqlInIds(Collection ids) { - if (null == ids || ids.isEmpty()) return ""; - StringBuilder s = new StringBuilder(128); - Set set = new HashSet<>(); - for (Long id : ids) { - if (set.contains(id)) continue; - set.add(id); - if (id <= 0) continue; - s.append(id).append(","); - } - if (s.length() == 0) return ""; - return s.substring(0, s.length() - 1); - } - - //中文字符串比较 - public static int chineseCompare(String s1, String s2) { - return chineseCollator.compare(s1, s2); - } - public static int compareStr(String s1, String s2) { - if (StringUtils.isEmpty(s1) && StringUtils.isEmpty(s2)) return 0; - if (StringUtils.isEmpty(s1)) return -1; - if (StringUtils.isEmpty(s2)) return 1; - return chineseCollator.compare(s1, s2); - } - - public static boolean isStrEquals(String s1, String s2) { - return compareStr(s1, s2) == 0; - } - - //获取字段字符串长度 - public static int getStrLenB(String s) { - if (StringUtils.isEmpty(s)) return 0; - return s.getBytes(StandardCharsets.UTF_8).length; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/DateUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/DateUtil.java deleted file mode 100644 index 6c55dd3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/DateUtil.java +++ /dev/null @@ -1,319 +0,0 @@ -package cc.smtweb.framework.core.util; - -import org.apache.commons.lang3.time.DateUtils; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; - -/** - * 日期工具类 - */ -public class DateUtil { -// private static ThreadLocal stdTimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("HH:mm:ss")); - private static ThreadLocal stdDateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd")); - private static ThreadLocal stdDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); -// private static ThreadLocal stdLongDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")); - - private static ThreadLocal simpleWeekFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("EEEE")); - private static ThreadLocal simpleTimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("HHmmss")); - private static ThreadLocal simpleDateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd")); - private static ThreadLocal simpleDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmss")); - private static ThreadLocal simpleLongDatetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmmssSSS")); - - - private DateUtil(){} - - /** - * 获取当前时间 - * @return - */ - public static Date now() { - return new Date(System.currentTimeMillis()); - } - - /** - * 按yyyy-MM-dd格式化 - * @param date - * @return - */ - public static String formatDate(Date date) { - return stdDateFormat.get().format(date); - } - - /** - * 按yyyy-MM-dd HH:mm:ss格式化 - * @param date - * @return - */ - public static String formatDateTime(Date date) { - return stdDatetimeFormat.get().format(date); - } - - /** - * 格式化 - * @param date YYYYMMDD格式 - * @return - */ - public static String formatDate(long date) { - String d = String.valueOf(date); - if(d.length() < 8) return d; //就是2011-03-04 13:11:01这种形式 - return d.substring(0, 4) + "-" + d.substring(4, 6) + "-" + d.substring(6, 8); - } - - public static String formatDateTime(long date) { - String d = String.valueOf(date); - if(d.length() < 8) return d; //就是2011-03-04 13:11:01这种形式 - if(d.length() < 14) return d.substring(0, 4) + "-" + d.substring(4, 6) + "-" + d.substring(6, 8); - return d.substring(0, 4) + "-" + d.substring(4, 6) + "-" + d.substring(6, 8) + " " + d.substring(8, 10) + ":" + d.substring(10, 12) + ":" + d.substring(12); - } - - /** - * 按yyyyMMdd格式化 - * @param date - * @return - */ - public static String formatSimpleDate(Date date) { - return simpleDateFormat.get().format(date); - } - - /** - * 按yyyyMMddHHmmss格式化 - * @param date - * @return - */ - public static String formatSimpleDateTime(Date date) { - return simpleDatetimeFormat.get().format(date); - } - - /** - * 按yyyyMMddHHmmssSSS格式化 - * @param date - * @return - */ - public static String formatSimpleDateTimeS(Date date) { - return simpleLongDatetimeFormat.get().format(date); - } - - /** - * 按yyyyMMdd格式化 - * @param date - * @return - */ - public static long date2Long(Date date) { - return Long.parseLong(formatSimpleDate(date)); - } - - /** - * 按yyyyMMddHHmmss格式化 - * @param date - * @return - */ - public static long dateTime2Long(Date date) { - return Long.parseLong(formatSimpleDateTime(date)); - } - - public static String nowDate() { - return formatDate(now()); - } - - public static String nowDateTime() { - return formatDateTime(now()); - } - - public static long nowDateLong() { - return date2Long(now()); - } - - public static long nowDateTimeLong() { - return dateTime2Long(now()); - } - - // 获得当天0点时间 - public static long getTimesmorning() { - return getTimesmorning(System.currentTimeMillis()); - } - - // 获得指定时间0点时间 - public static long getTimesmorning(long time) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.MILLISECOND, 0); - return cal.getTimeInMillis(); - } - - // 获得昨天0点时间 - public static long getYesterdaymorning() { - return getTimesmorning() - DateUtils.MILLIS_PER_DAY; - } - - // 获得当天近7天时间 - public static long getWeekFromNow() { - return getTimesmorning() - DateUtils.MILLIS_PER_DAY * 7; - } - - // 获得当天24点时间 - public static long getTimesnight() { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.HOUR_OF_DAY, 24); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.MILLISECOND, 0); - return cal.getTimeInMillis(); - } - - public static long getTimesnight(long time) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - cal.set(Calendar.HOUR_OF_DAY, 24); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.MILLISECOND, 0); - return cal.getTimeInMillis(); - } - - // 获得本周一0点时间 - public static long getTimesWeekmorning() { - Calendar cal = Calendar.getInstance(); - cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); - cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); - return cal.getTimeInMillis(); - } - - // 获得本周日24点时间 - public static long getTimesWeeknight() { - return getTimesWeekmorning() + DateUtils.MILLIS_PER_DAY * 7; - } - - // 获得本月第一天0点时间 - public static long getTimesMonthMorning() { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(System.currentTimeMillis()); - cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); - cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH)); - return cal.getTimeInMillis(); - } - - // 获得本月最后一天24点时间 - public static long getTimesMontgHight() { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(System.currentTimeMillis()); - cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); - cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); - cal.set(Calendar.HOUR_OF_DAY, 24); - return cal.getTimeInMillis(); - } - - public static long getLastMonthStartMorning() { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(getTimesMonthMorning()); - cal.add(Calendar.MONTH, -1); - return cal.getTimeInMillis(); - } - - public static long getLastMonthStartMorning(long timeInMillis) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(timeInMillis); - cal.add(Calendar.MONTH, -1); - return cal.getTimeInMillis(); - } - - public static Date getCurrentQuarterStartTime() { - Calendar c = Calendar.getInstance(); - c.setTimeInMillis(getTimesMonthMorning()); - int currentMonth = c.get(Calendar.MONTH) + 1; - SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd"); - Date now = null; - try { - if (currentMonth <= 3) { - c.set(Calendar.MONTH, 0); - } else if (currentMonth <= 6) { - c.set(Calendar.MONTH, 3); - } else if (currentMonth <= 9) { - c.set(Calendar.MONTH, 4); - } else if (currentMonth <= 12) { - c.set(Calendar.MONTH, 9); - } - - c.set(Calendar.DATE, 1); - now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00"); - } catch (Exception e) { - e.printStackTrace(); - } - return now; - } - - /** - * 当前季度的结束时间,即2012-03-31 23:59:59 - * - * @return - */ - public static Date getCurrentQuarterEndTime() { - Calendar cal = Calendar.getInstance(); - cal.setTime(getCurrentQuarterStartTime()); - cal.add(Calendar.MONTH, 3); - return cal.getTime(); - } - - public static long getCurrentYearStartTime() { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(getTimesMonthMorning()); - cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); - cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.YEAR)); - return cal.getTimeInMillis(); - } - - public static long getCurrentYearEndTime() { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(getCurrentYearStartTime()); - cal.add(Calendar.YEAR, 1); - return cal.getTimeInMillis(); - } - - public static long getLastYearStartTime() { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(getCurrentYearStartTime()); - cal.add(Calendar.YEAR, -1); - return cal.getTimeInMillis(); - } - - public static long getLastYearStartTime(long timeInMillis) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(timeInMillis); - cal.add(Calendar.YEAR, -1); - return cal.getTimeInMillis(); - } - - public static String parseTimeTag(Date date){ - if(date == null){ - return ""; - } - int now = date2Day(new Date()); - int day = date2Day(date); - int deDay = now - day; -// int deMonth = now/100 - day/100; - int deYear = now/10000 - day/10000; - if(deYear < 1){ - switch(deDay){ - case 0: return new SimpleDateFormat("HH:mm").format(date); - case 1: return "昨天"; - default: - return new SimpleDateFormat("MM-dd").format(date); - } - } - return new SimpleDateFormat("yyyy-MM-dd").format(date); - } - - private static int date2Day(Date date){ - return Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(date)); - } - - public static void main(String[] args) { - System.out.println(getTimesmorning()); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/FileUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/FileUtil.java new file mode 100644 index 0000000..69669ae --- /dev/null +++ b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/FileUtil.java @@ -0,0 +1,7 @@ +package cc.smtweb.framework.core.util; + +/** + * Created by Akmm at 2022/7/4 21:37 + */ +public class FileUtil { +} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/IpAddrUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/IpAddrUtil.java deleted file mode 100644 index 9ba2642..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/IpAddrUtil.java +++ /dev/null @@ -1,101 +0,0 @@ -package cc.smtweb.framework.core.util; - -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * 〈IP〉工具类 - * - * @author kevin - * @since 1.0.0 - */ -public class IpAddrUtil { - - private IpAddrUtil() { - } - - //指定字符串是否工具类 - public static boolean isIpAddress(String ipAddr) { - if (StringUtils.isEmpty(ipAddr)) { - return false; - } else { - String regTxt = - "\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b"; - return regMatch(ipAddr, regTxt); - } - } - - //正则匹配校验 - private static boolean regMatch(String source, String regTxt) { - Pattern pattern = Pattern.compile(regTxt); - Matcher matcher = pattern.matcher(source); - return matcher.matches(); - } - - //ip转long - public static long ip2Long(String ipAddr) { - long[] ip = new long[4]; - int position1 = ipAddr.indexOf("."); - int position2 = ipAddr.indexOf(".", position1 + 1); - int position3 = ipAddr.indexOf(".", position2 + 1); - ip[0] = Long.parseLong(ipAddr.substring(0, position1)); - ip[1] = Long.parseLong(ipAddr.substring(position1 + 1, position2)); - ip[2] = Long.parseLong(ipAddr.substring(position2 + 1, position3)); - ip[3] = Long.parseLong(ipAddr.substring(position3 + 1)); - return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]; - } - - //long转ip格式 - public static String long2IP(long ipAddr) { - return (ipAddr >>> 24) + - "." + - ((ipAddr & 16777215L) >>> 16) + - "." + - ((ipAddr & 65535L) >>> 8) + - "." + - (ipAddr & 255L); - } - - //获取当前请求ip,返回long格式 - public static long getLongIp(HttpServletRequest request) { - try { - String ipAddr = getIpAddr(request); - return StringUtils.isBlank(ipAddr) ? 0L : ip2Long(ipAddr); - } catch (Exception var2) { - return 0L; - } - } - - //获取当前请求的ip,返回ip格式 - public static String getIpAddr(HttpServletRequest request) { - if (request == null) { - return ""; - } else { - String ip = request.getHeader("X-Forwarded-For"); - if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("Proxy-Client-IP"); - } - - if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("WL-Proxy-Client-IP"); - } - - if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("HTTP_CLIENT_IP"); - } - - if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("HTTP_X_FORWARDED_FOR"); - } - - if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - ip = request.getRemoteAddr(); - } - - return ip; - } - } -} \ No newline at end of file diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/JsonUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/JsonUtil.java deleted file mode 100644 index d049d96..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/JsonUtil.java +++ /dev/null @@ -1,296 +0,0 @@ -package cc.smtweb.framework.core.util; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.exception.JsonParseException; -import cc.smtweb.framework.core.util.jackson.*; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.ser.FilterProvider; -import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; -import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.BeanUtils; - -import java.beans.PropertyDescriptor; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.sql.Timestamp; -import java.util.*; - -import static org.springframework.beans.BeanUtils.getPropertyDescriptors; - -/** - * json工具类 - */ -@Slf4j -public class JsonUtil { - public final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - public final static ObjectMapper API_OBJECT_MAPPER = new ObjectMapper(); - - static { - init(OBJECT_MAPPER); - // 不序列化空值 - OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); -// OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); -// OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); -// // 设置将MAP转换为JSON时候只转换值不等于NULL的 -// objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); - - init(API_OBJECT_MAPPER); - API_OBJECT_MAPPER.getSerializerProvider().setNullValueSerializer(new NullSerializer()); - - FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.serializeAllExcept(new HashSet<>())); - } - - private static void init(ObjectMapper mapper) { - // JSON转化为对象时忽略未对应的属性 - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - SimpleModule module = new SimpleModule(); - LongSerializer longSerializer = new LongSerializer(); - module.addSerializer(Long.class, longSerializer); - module.addSerializer(Long.TYPE, longSerializer); - - DateSerializer dateSerializer = new DateSerializer(); - module.addSerializer(java.sql.Date.class, dateSerializer); - TimeSerializer timeSerializer = new TimeSerializer(); - module.addSerializer(java.sql.Time.class, timeSerializer); -// module.addSerializer(BaseBean.class, new BaseBeanSerializer()); - - module.addDeserializer(Timestamp.class, new TimestampDeserializer()); - module.addDeserializer(java.util.Date.class, new DateDeserializer()); - - mapper.registerModule(module); - mapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); - } - - public static JsonNode readTree(String body) { - try { - return OBJECT_MAPPER.readTree(body); - } catch (IOException e) { - log.error(e.getMessage(), e); - } - - return null; - } - - // 创建新节点 - public static ObjectNode createObjectNode() { - return OBJECT_MAPPER.createObjectNode(); - } - - // 将 JsonNode 对象转成 json - public static String writeValueAsString(JsonNode newNode) { - try { - return OBJECT_MAPPER.writeValueAsString(newNode); - } catch (JsonProcessingException e) { - log.error(e.getMessage(), e); - } - - return null; - } - - public static T parse(String str, Class clazz) { - try { - if (StringUtils.isBlank(str)) { - return null; - } else { - return OBJECT_MAPPER.readValue(str, clazz); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to " + clazz + " type", e); - } - } - - /** - * 将Map对象转换为Bean对象 - * - * @param map Map对象 - * @param clazz Bean对象类 - * @param Bean对象类型 - * @return Bean对象实例 - */ - public static T parse(Map map, Class clazz) { - try { - if (map == null || map.isEmpty()) { - return null; - } else { - // 对象实例化 - T bean = BeanUtils.instantiateClass(clazz); - if (SwMap.class.isAssignableFrom(clazz)) { - ((SwMap) bean).putAll(map); - } else { - // 循环设置对象属性 - PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz); - for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { - String properName = propertyDescriptor.getName(); - // 过滤class属性 - if (!"class".equals(properName)) { - if (map.containsKey(properName)) { - Method writeMethod = propertyDescriptor.getWriteMethod(); - if (writeMethod != null) { - Object value = map.get(properName); - if (!writeMethod.isAccessible()) { - writeMethod.setAccessible(true); - } - writeMethod.invoke(bean, value); - } - } - } - } - } - - return bean; - } - } catch (Exception e) { - throw new JsonParseException("can't convert map to " + clazz + " type", e); - } - } - - public static T parse(InputStream is, Class clazz) { - try { - if (is == null) { - return null; - } else { - return OBJECT_MAPPER.readValue(is, clazz); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to " + clazz + " type", e); - } - } - - public static T parse(byte[] str, Class clazz) { - try { - if (str == null || str.length == 0) { - return null; - } else { - return OBJECT_MAPPER.readValue(str, clazz); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to " + clazz + " type", e); - } - } - - public static JsonNode parse(String str) { - try { - if (StringUtils.isBlank(str)) { - return null; - } else { - return OBJECT_MAPPER.readTree(str); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to JsonNode", e); - } - } - - /** - * 转换json文本为对象列表 - * - * @param is json文本流 - * @param 列表中对象类 - * @param clazz 列表中的对象类 - * @return 列表对象 - */ - public static List parseList(InputStream is, Class clazz) { - try { - if (is == null) { - return null; - } else { - JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); - return OBJECT_MAPPER.readValue(is, javaType); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to list type", e); - } - } - - /** - * 转换json文本为对象列表 - * - * @param str json文本字节数组 - * @param 列表中对象类 - * @param clazz 列表中的对象类 - * @return 列表对象 - */ - public static List parseList(byte[] str, Class clazz) { - try { - if (str == null || str.length == 0) { - return null; - } else { - JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); - return OBJECT_MAPPER.readValue(str, javaType); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to list type", e); - } - } - - /** - * 转换json文本为对象列表 - * - * @param str json文本 - * @param 列表中对象类 - * @param clazz 列表中的对象类 - * @return 列表对象 - */ - public static List parseList(String str, Class clazz) { - try { - if (StringUtils.isBlank(str)) { - return null; - } else { - JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz); - return OBJECT_MAPPER.readValue(str, javaType); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to list<" + clazz.getSimpleName() + "> type", e); - } - } - - public static Map parseMap(String str) { - try { - if (StringUtils.isBlank(str)) { - return null; - } else { - return OBJECT_MAPPER.readValue(str, Map.class); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to Map type", e); - } - } - - public static String encodeString(Object obj) { - try { - return OBJECT_MAPPER.writeValueAsString(obj); - } catch (JsonProcessingException e) { - throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); - } - } - - public static byte[] encodeBytes(Object obj) { - try { - return OBJECT_MAPPER.writeValueAsBytes(obj); - } catch (JsonProcessingException e) { - throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); - } - } - - public static SwMap bean2Map(Object obj) { - return parse(encodeString(obj), SwMap.class); - } - - public static List bean2MapList(Object obj) { - List list = new ArrayList<>(); - SwMap[] arr = parse(encodeString(obj), SwMap[].class); - Collections.addAll(list, arr); - return list; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/MapUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/MapUtil.java deleted file mode 100644 index 9b38819..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/MapUtil.java +++ /dev/null @@ -1,221 +0,0 @@ -package cc.smtweb.framework.core.util; - -import cc.smtweb.framework.core.common.SwMap; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -/** - * map工具类 - */ -public class MapUtil { - private MapUtil() {} - - public static String readString(Map map, String name) { - return readString(map, name, ""); - } - - public static String readString(Map map, String name, String defaultValue) { - Object s = map.get(name); - - if (s != null) { - return s.toString(); - } - - return defaultValue; - } - - public static long readLong(Map map, String name) { - return readLong(map, name, 0L); - } - - public static long readLong(Map map, String name, Long defaultValue) { - Object s = map.get(name); - - if (s != null) { - if (s instanceof Number) { - return ((Number) s).longValue(); - } else { - String value = s.toString(); - if (StringUtils.isNotBlank(value)) { - return Long.parseLong(value); - } - } - } - - return defaultValue; - } - - public static Long[] readLongArray(Map map, String name) { - return readLongArray(map, name, null); - } - - public static Long[] readLongArray(Map map, String name, Long[] defaultValue) { - Object value = map.get(name); - - if (value != null) { - if (value instanceof Long[]) { - return (Long[]) value; - } else if (value instanceof Object[]) { - Object[] items = (Object[])value; - List result = new ArrayList<>(items.length); - - for (Object item: items) { - if (item != null) { - String s = item.toString(); - if (StringUtils.isNotBlank(s)) { - result.add(Long.valueOf(s)); - } - } - } - - if (result.size() > 0) { - return result.toArray(new Long[result.size()]); - } - } else if (value instanceof List) { - List items = (List)value; - List result = new ArrayList<>(items.size()); - - for (Object item: items) { - if (item != null) { - String s = item.toString(); - if (StringUtils.isNotBlank(s)) { - result.add(Long.valueOf(s)); - } - } - } - - if (result.size() > 0) { - return result.toArray(new Long[result.size()]); - } - } else if (value instanceof String) { - String[] ary = value.toString().split(","); - if (ary.length > 0) { - List result = new ArrayList<>(ary.length); - - for (String item: ary) { - if (StringUtils.isNotBlank(item)) { - result.add(Long.valueOf(item)); - } - } - - if (result.size() > 0) { - return result.toArray(new Long[result.size()]); - } - } - } - } - - return defaultValue; - } - - public static int readInt(Map map, String name) { - return readInt(map, name, 0); - } - - public static int readInt(Map map, String name, int defaultValue) { - Object s = map.get(name); - - if (s != null) { - if (s instanceof Number) { - return ((Number) s).intValue(); - } else { - String value = s.toString(); - if (StringUtils.isNotBlank(value)) { - return Integer.parseInt(value); - } - } - } - - return defaultValue; - } - - public static float readFloat(Map map, String name) { - return readFloat(map, name, 0.0F); - } - - public static float readFloat(Map map, String name, float defaultValue) { - Object s = map.get(name); - - if (s != null) { - if (s instanceof Number) { - return ((Number) s).floatValue(); - } else { - String value = s.toString(); - if (StringUtils.isNotBlank(value)) { - return Float.parseFloat(value); - } - } - } - - return defaultValue; - } - - public static double readDouble(Map map, String name) { - return readDouble(map, name, 0d); - } - - public static double readDouble(Map map, String name, double defaultValue) { - Object s = map.get(name); - - if (s != null) { - if (s instanceof Number) { - return ((Number) s).doubleValue(); - } else { - String value = s.toString(); - if (StringUtils.isNotBlank(value)) { - return Double.parseDouble(value); - } - } - } - - return defaultValue; - } - - public static boolean readBool(Map map, String name) { - return readBool(map, name, false); - } - - public static boolean readBool(Map map, String name, boolean defaultValue) { - Object s = map.get(name); - - if (s != null) { - if (s instanceof Boolean) { - return (Boolean) s; - } else { - String value = s.toString(); - if ("true".equalsIgnoreCase(value) || "1".equals(value) || "y".equalsIgnoreCase(value)) { - return Boolean.TRUE; - } - } - } - - return defaultValue; - } - - public static Set readLongSet(SwMap swMap, String name) { - Object value = swMap.get(name); - if (value != null) { - String[] ary = value.toString().split(","); - if (ary.length > 0) { - Set result = new HashSet<>(ary.length); - - for (String item : ary) { - if (StringUtils.isNotBlank(item)) { - result.add(Long.valueOf(item)); - } - } - - return result; - } - } - - return null; - } - - public static List> readListMap(Map map, String name) { - Object v = map.get(name); - if (v == null) return null; - return (List>)v; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/NumberUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/NumberUtil.java deleted file mode 100644 index 0d6cd8e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/NumberUtil.java +++ /dev/null @@ -1,621 +0,0 @@ -package cc.smtweb.framework.core.util; - -import org.apache.commons.jexl3.JexlBuilder; -import org.apache.commons.jexl3.JexlContext; -import org.apache.commons.jexl3.JexlExpression; -import org.apache.commons.jexl3.MapContext; -import org.apache.commons.lang3.StringUtils; - -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.text.DecimalFormat; -import java.util.Map; - -public class NumberUtil { - private NumberUtil() {} - - //整数 - private static DecimalFormat dfLng = new DecimalFormat("##############0"); - private static DecimalFormat dfLong = new DecimalFormat("###,###,###,###,##0"); - //一位小数 - private static DecimalFormat df1 = new DecimalFormat("##############0.0"); - private static DecimalFormat df1Format = new DecimalFormat("###,###,###,###,##0.0"); - //两位小数 - private static DecimalFormat df2 = new DecimalFormat("##############0.00"); - private static DecimalFormat df2Format = new DecimalFormat("###,###,###,###,##0.00"); - //四位小数 - private static DecimalFormat df4 = new DecimalFormat("###,###,###,###,##0.0000"); - //六位小数 - private static DecimalFormat df6Number = new DecimalFormat("#######################0.000000"); - private static DecimalFormat df6NumberF = new DecimalFormat("#,###,###,###,###,###,##0.000000"); - - public final static DecimalFormat stdAmountFormat = new DecimalFormat("###,###,###,###,##0.00"); - public final static DecimalFormat stdNumberFormat = new DecimalFormat("#0.00"); - public final static String DEF_NUM_TEN_THOUSAND = "10000";//万 - public static final double MAX_VALUE = 9999999999999.99D; - public static final double MIN_VALUE = -9999999999999.99D; - - private final static BigDecimal ONE_BIG = new BigDecimal(1.00D); - private static final String UNIT = "万仟佰拾亿仟佰拾万仟佰拾元角分"; - private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖"; - - /** - * 4舍5入double,2位小数 - */ - public static double roundDouble(double src) { - return roundDouble(src, 2); - } - - /** - * 4舍5入double,N 位小数 - * - * @param src - * @param scale 小数位数 - * @return - */ - public static double roundDouble(Object src, int scale) { - if (src == null) return 0.0; - String v = src.toString(); - if (StringUtils.isEmpty(v)) return 0.0; - if (scale < 0) scale = 2; - - BigDecimal src_b = new BigDecimal(v); - BigDecimal src_v = src_b.divide(ONE_BIG, scale + 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 - src_v = src_v.divide(ONE_BIG, scale, BigDecimal.ROUND_HALF_UP);// 4舍5入 - return src_v.doubleValue(); - } - - /** - * 舍位处理,原生floor有坑,部分浮点数记录为.99999999999形式,导致floor结果错误 - * - * @param d - * @return - */ - public static double floor(double d) { - return Math.floor(roundDouble(d, 2)); - } - - /** - * 比较两Double是否相等,将会吧他们专程BigDecimal进行比较; - * - * @param src double1 - * @param tag double2 - * @return src > tag 返回1, src < tag 返回-1, 否则返回0 - */ - public static int compare(double src, double tag) { - BigDecimal src_b = new BigDecimal(src); - BigDecimal src_v = src_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 - - BigDecimal tag_b = new BigDecimal(tag); - BigDecimal tag_v = tag_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入 - - return src_v.compareTo(tag_v); - } - - /** - * 自动过滤金额中的逗号转换为double,如果出错,则返回0 - * - * @param s 源串,可能为带逗号的金额串; - * @return double - */ - public static Double toDouble(String s) { - return todouble(s); - } - - /** - * 自动过滤金额中的逗号转换为double,如果出错,则返回0 - * - * @param s 源串,可能为带逗号的金额串; - * @return double - */ - public static double todouble(String s) { - try { - return Double.parseDouble(s.replaceAll(",", "")); - } catch (Exception e) { - return 0.00; - } - } - - /** - * 获取double,主要过滤d为null的情况; - * - * @param d Double对象; - * @return double - */ - public static double todouble(Double d) { - if (d == null) return 0.0d; - return d.doubleValue(); - } - - /** - * 自动过滤金额中的逗号转换为float,如果出错,则返回0 - * - * @param s 源串,可能为带逗号的金额串; - * @return Float - */ - public static Float toFloat(String s) { - return tofloat(s); - } - - /** - * 自动过滤金额中的逗号转换为float,如果出错,则返回0 - * - * @param s 源串,可能为带逗号的金额串; - * @return Float - */ - public static float tofloat(String s) { - try { - return Float.parseFloat(s.replaceAll(",", "")); - } catch (Exception e) { - return 0.0f; - } - } - - public static long tolong(String src, long defaultvalue) { - try { - return Long.parseLong(src); - } catch (Exception e) { - return defaultvalue; - } - } - - public static int toint(String src, int defaultvalue) { - try { - return Integer.parseInt(src); - } catch (Exception e) { - return defaultvalue; - } - } - - /** - * 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001 - * - * @param value double类型 - * @return boolean - */ - public static boolean isBigThanZero(double value) { - return (value > 0.00001); - } - - /** - * 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001 - * - * @param value String类型 - * @return boolean - */ - public static boolean isBigThanZero(String value) { - return !StringUtils.isEmpty(value) && isBigThanZero(toDouble(value)); - } - - /** - * 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。 - * - * @param value double类型 - * @return boolean - */ - public static boolean isEqualsZero(double value) { - return (-0.00001 < value && value < 0.00001); - } - - /** - * 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。 - * - * @param value String类型 - * @return boolean - */ - public static boolean isEqualsZero(String value) { - return StringUtils.isEmpty(value) || isEqualsZero(toDouble(value)); - } - - /** - * 是否是负数 - * - * @param db_val 要判断的double - * @return 负数则返回true; - */ - public static boolean isNegative(double db_val) { - return (compare(db_val, 0.00D) == -1); - } - - /** - * 是否是正数 - * - * @param db_val 要判断的double - * @return 正数则返回true; - */ - public static boolean isPlus(double db_val) { - return (compare(db_val, 0.00D) == 1); - } - - /** - * 得到金额字符串,保持小数点2位 - * - * @param db 将double转换为金额字符串; - * @return 金额字符串#0.00; - */ - public static String toStdNumberString(double db) { - try { - return stdNumberFormat.format(db); - } catch (Exception e) { - return "0.00"; - } - } - - public static String toStdNumberStringEx(double db) { - try { - if (compare(db, -1d) == 0) return "-"; - return stdNumberFormat.format(db); - } catch (Exception e) { - return "0.00"; - } - } - - /** - * 将金额格式字符串,如23,333,093.01 去掉逗号 - * - * @param s 金额串 - * @return String 去掉逗号后的串,如果amount为空,则返回0.00 - */ - public static String toStdNumberString(String s) { - if (StringUtils.isEmpty(s)) - return "0.00"; - return stdNumberFormat.format(todouble(s)); - } - - /** - * 将数据转换为两位小数的数字格式; - * - * @param d 数据 - * @param isZeroToEmpty 如果未0,是否返回“”; - * @return 两位小数的字符串; - */ - public static String toStdNumberString(double d, boolean isZeroToEmpty) { - if (isEqualsZero(d)) { - return isZeroToEmpty ? "" : "0.00"; - } - return stdNumberFormat.format(d); - } - - public static String toStdNumberString(String s, boolean isZeroToEmpty) { - return toStdNumberString(todouble(s), isZeroToEmpty); - } - - public static String toStdNumberString(double d, int scale) { - DecimalFormat dfn = null; - if (scale == 1) dfn = df1Format; - if (scale == 2) dfn = df2Format; - else if (scale == 4) dfn = df4; - else if (scale == 6) dfn = df6NumberF; - else if (scale <= 0) dfn = dfLong; - else { - StringBuilder sb = new StringBuilder("###,###,###,###,##0."); - for (int i = 0; i < scale; i++) sb.append("0"); - dfn = new DecimalFormat(sb.toString()); - } - return dfn.format(d); - } - - /** - * 将数字乘100,保留小数点后两位, 然后后面添加% - * - * @param d 值 - * @param isZeroToEmpty,如果值为0,是否返回空; - * @return 字符串; - */ - public static String toStdPercentNumberStr(double d, boolean isZeroToEmpty) { - if (d > -0.00000000001 && d < 0.00000000001) { - return isZeroToEmpty ? "" : "0.00%"; - } - return toStdNumberString(d * 100) + "%"; - } - - - public static String toStdAmountString(double d) { - return toStdAmountString(d, false); - } - - /** - * 将数据转换为两位小数的金额格式,带逗号; - * - * @param d 数据 - * @param isZeroToEmpty 如果未0,是否返回“”; - * @return 金额格式的字符串; - */ - public static String toStdAmountString(double d, boolean isZeroToEmpty) { - if (isEqualsZero(d)) { - return isZeroToEmpty ? "" : "0.00"; - } - return stdAmountFormat.format(d); - } - - public static String toStdAmountString(String s) { - return toStdAmountString(todouble(s), false); - } - - public static String toStdAmountString(String s, boolean isZeroToEmpty) { - return toStdAmountString(todouble(s), isZeroToEmpty); - } - - - /** - * 将小写金额转换为人民币大写金额 - * - * @param s 金额格式的串 - * @return String 转换结果 - */ - public static String toCapsAmountString(String s) { - if (StringUtils.isEmpty(s)) return ""; - return toCapsAmountString(todouble(s)); - } - - /** - * 将小写金额转换为人民币大写金额 - * - * @param v double - * @return String 转换结果 - */ - public static String toCapsAmountString(double v) { - if (v < MIN_VALUE || v > MAX_VALUE) return "参数非法!"; - - boolean negative = isNegative(v); - - if (negative) v = Math.abs(v); - long l = Math.round(v * 100); - if (l == 0) return "零元整"; - - String strValue = String.valueOf(l); - // i用来控制数 - int i = 0; - // j用来控制单位 - int j = UNIT.length() - strValue.length(); - StringBuilder rs = new StringBuilder(32); - boolean isZero = false; - for (; i < strValue.length(); i++, j++) { - char ch = strValue.charAt(i); - if (ch == '0') { - isZero = true; - if (UNIT.charAt(j) == '亿' || UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元') { - rs.append(UNIT.charAt(j)); - isZero = false; - } - } else { - if (isZero) { - rs.append('零'); - isZero = false; - } - rs.append(DIGIT.charAt(ch - '0')).append(UNIT.charAt(j)); - } - } - if (rs.charAt(rs.length() - 1) != '分') - rs.append('整'); - - i = rs.indexOf("亿万"); - if (i > 0) rs.delete(i + 1, i + 2); // i+1 ->万 - - if (negative) - return rs.insert(0, '负').toString(); - else - return rs.toString(); - } - - /** - * 返回0 到 maxvalue的随机数 - * - * @param maxvalue 随机数的最大值 - * @return int - */ - public static int rnd(int maxvalue) { - return (int) (Math.random() * (maxvalue + 1)); - } - - - public static double chkDbNull(Double v) { - return v == null ? 0 : v; - } - - public static double max(double d1, double d2) { - return compare(d1, d2) < 0 ? d2 : d1; - } - - public static double min(double d1, double d2) { - return compare(d1, d2) < 0 ? d1 : d2; - } - - /** - * 获取浮点数(有错误默认为0),可以识别金额中的逗号格式 - * - * @param str 带转换的字符串 - * @return 浮点数 - */ - public static double getDoubleIgnoreErr(String str) { - if (str == null) - return 0.0; - str = str.trim(); - if (str.equals("")) - return 0.0; - str = str.replaceAll(",", "").replaceAll(",", ""); - try { - return Double.valueOf(str); - } catch (Exception e) { - return 0.0; - } - } - - public static int getIntIgnoreErr(String str) { - if (StringUtils.isEmpty(str)) - return 0; - str = str.replaceAll(",", "").replaceAll(",", ""); - if (str.contains(".")) - str = str.substring(0, str.indexOf('.')); - try { - return Integer.valueOf(str); - } catch (Exception e) { - return 0; - } - } - - public static long getLongIgnoreErr(String str) { - if (StringUtils.isEmpty(str)) - return 0L; - str = str.replaceAll(",", "").replaceAll(",", ""); - try { - return Long.valueOf(str); - } catch (Exception e) { - return 0L; - } - } - - /** - * 计算公式 参数以Map方式传入 - * - * @param expr 表达式 - * @param mapVar 变量 - * @return 计算结果 - */ - public static Object calcExprMapObject(String expr, Map mapVar) { - if (StringUtils.isEmpty(expr)) return ""; - JexlContext jc = new MapContext(); - for (String k : mapVar.keySet()) jc.set(k, mapVar.get(k)); - JexlExpression e = new JexlBuilder().create().createExpression(expr); - return e.evaluate(jc); - } - - /** - * 计算公式,参数以数组方式传入,key、value交替 - * - * @param expr 表达式 - * @param vars 变量 - * @return - */ - public static Object calcExprObjectEx(String expr, Object... vars) { - if (StringUtils.isEmpty(expr)) return ""; - JexlContext jc = new MapContext(); - for (int i = 0, len = vars.length; i < len; ) { - jc.set((String) vars[i++], vars[i++]); - } - JexlExpression e = new JexlBuilder().create().createExpression(expr); - return e.evaluate(jc); - } - - public static double calcExprMapDouble(String expr, Map mapVar) { - Object o = calcExprMapObject(expr, mapVar); - if (o != null) return getDoubleIgnoreErr(o.toString()); - return 0.0; - } - - public static double calcExprDoubleEx(String expr, Object... vars) { - Object o = calcExprObjectEx(expr, vars); - if (o != null) return getDoubleIgnoreErr(o.toString()); - return 0.0; - } - - public static int calcExprMapInt(String expr, Map mapVar) { - Object o = calcExprMapObject(expr, mapVar); - if (o != null) return getIntIgnoreErr(o.toString()); - return 0; - } - - public static int calcExprIntEx(String expr, Object... vars) { - Object o = calcExprObjectEx(expr, vars); - if (o != null) return getIntIgnoreErr(o.toString()); - return 0; - } - - public static boolean calcExprMapBool(String expr, Map mapVar) { - Object o = calcExprMapObject(expr, mapVar); - if (o != null) return (Boolean)o; - return false; - } - - public static boolean calcExprBoolEx(String expr, Object... vars) { - Object o = calcExprObjectEx(expr, vars); - if (o != null) return (Boolean)o; - return false; - } - -/* - public static Object calcExprObjectJ(String expr, Object... vars) throws Exception{ - if (StringUtils.isEmpty(expr)) return ""; - ExpressionEvaluator ee = new ExpressionEvaluator(); - ee.setExpressionType(int.class); - ee.setParameters(new String[]{"a", "b", "c"}, new Class[]{int.class, int.class, String.class}); - ee.cook(expr); - return ee.evaluate(vars); - } -*/ - - public static void main(String[] args) throws Exception{ - /*long t = System.currentTimeMillis(); - for (int i = 0; i < 10000; i++) { - System.out.print(calcExprIntEx("\"add\".equals(c) ? a + b : a - b", "a", 5, "b", 2, "c", "t")); - } - System.out.println(); - System.out.println(System.currentTimeMillis() - t); -// System.out.println(calcExprBoolEx("1==2")); - - t = System.currentTimeMillis(); - for (int i = 0; i < 10000; i++) { - System.out.print(calcExprObjectJ("\"add\".equals(c) ? a + b : a - b", 5, 2, "t")); - } - System.out.println(); - System.out.println(System.currentTimeMillis() - t);*/ - } - - /** - * double 去尾法 - * - * @param src 待处理数据 - * @param scale 保留小数位数 - * @return - */ - public static double cutDouble(double src, int scale) { - String v = toStdNumberString(src, 6);//先到6位小数,再去计算,否则容易出错,如8.3成8.29999999999,舍位就成了8.29了 - DecimalFormat formater = new DecimalFormat(); - formater.setMaximumFractionDigits(scale); - formater.setGroupingSize(0); - formater.setRoundingMode(RoundingMode.FLOOR); - return new BigDecimal(formater.format(toDouble(v))).doubleValue(); - } - - /** - * double 进位法 - * - * @param src 待处理数据 - * @param scale 保留小数位数 - * @return - */ - public static double upDouble(double src, int scale) { - String v = toStdNumberString(src, 6);//先到6位小数,再去计算 - DecimalFormat formater = new DecimalFormat(); - formater.setMaximumFractionDigits(scale); - formater.setGroupingSize(0); - formater.setRoundingMode(RoundingMode.UP); - return new BigDecimal(formater.format(toDouble(v))).doubleValue(); - } - - public static byte[] longToBytes(long l) { - byte[] result = new byte[8]; - for (int i = 7; i >= 0; i--) { - result[i] = (byte) (l & 0xFF); - l >>= 8; - } - return result; - } - - public static long bytesToLong(byte[] b) { - long result = 0; - for (int i = 0; i < 8; i++) { - result <<= 8; - result |= (b[i] & 0xFF); - } - return result; - } - - public static boolean longEquals(Long l1, Long l2) { - if (l1 != null) { - return l1.equals(l2); - } - - return l2 == null; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/SpringUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/SpringUtil.java deleted file mode 100644 index 7063c85..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/SpringUtil.java +++ /dev/null @@ -1,42 +0,0 @@ -package cc.smtweb.framework.core.util; - -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.stereotype.Component; - -/** - * @Author: tanghp - * @Date: 2021-07-28 11:00 - * @Desc: - */ -@Component -public class SpringUtil implements ApplicationContextAware { - private static ApplicationContext applicationContext; - - public SpringUtil() { - } - - public void setApplicationContext(ApplicationContext applicationContext) { - if (SpringUtil.applicationContext == null) { - SpringUtil.applicationContext = applicationContext; - } - - } - - public static ApplicationContext getApplicationContext() { - return applicationContext; - } - - public static T getBean(String name) { - return (T)applicationContext.getBean(name); - } - - public static T getBean(Class clazz) { - return applicationContext.getBean(clazz); - } - - public static T getBean(String name, Class clazz) { - return applicationContext.getBean(name, clazz); - } -} - diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/SqlUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/SqlUtil.java deleted file mode 100644 index f67d777..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/SqlUtil.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.smtweb.framework.core.util; - -/** - * Created by Akmm at 2022/5/20 16:57 - * sql工具类 - */ -public class SqlUtil { - /** - * 将sql中的表名替换成schema.table的格式 - * @param sql - * @return - */ - public static String replaceTable(String sql) { - return sql; - } - - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/VariableUtil.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/VariableUtil.java deleted file mode 100644 index a425403..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/VariableUtil.java +++ /dev/null @@ -1,65 +0,0 @@ -package cc.smtweb.framework.core.util; - -/** - * 变量命名规则工具类 - */ -public class VariableUtil { - private VariableUtil() {} - - /*** - * 下划线命名转为驼峰命名 - * - * @param para - * 下划线命名的字符串 - */ - public static String underlineToHump(String para){ - StringBuilder result = new StringBuilder(); - String[] a = para.split("_"); - for(String s:a){ - if(result.length()==0){ - result.append(s.toLowerCase()); - }else{ - result.append(s.substring(0, 1).toUpperCase()); - result.append(s.substring(1).toLowerCase()); - } - } - return result.toString(); - } - - /*** - * 下划线命名转为大写驼峰命名 - * 大驼峰式命名法(upper camel case) - * - * @param para - * 下划线命名的字符串 - */ - public static String underlineToUpperHump(String para){ - StringBuilder result=new StringBuilder(); - String[] a = para.split("_"); - for(String s : a){ - result.append(s.substring(0, 1).toUpperCase()); - result.append(s.substring(1).toLowerCase()); - } - return result.toString(); - } - - - /*** - * 驼峰命名转为下划线命名 - * - * @param para - * 驼峰命名的字符串 - */ - public static String humpToUnderline(String para){ - StringBuilder sb = new StringBuilder(para); - //偏移量,第i个下划线的位置是 当前的位置+ 偏移量(i-1),第一个下划线偏移量是0 - int temp = 0; - for(int i = 0; i { - - @Override - public void serialize(BaseBean value, JsonGenerator gen, - SerializerProvider serializers) throws IOException, - JsonProcessingException { - if (value == null) { - gen.writeNull(); - } else { - gen.writeObject(value.getData()); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/DateDeserializer.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/DateDeserializer.java deleted file mode 100644 index 7fe37eb..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/DateDeserializer.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.framework.core.util.jackson; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; -import org.apache.commons.lang3.StringUtils; - -import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -public class DateDeserializer extends JsonDeserializer { - @Override - public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { - if (jsonParser != null && StringUtils.isNotEmpty(jsonParser.getText())) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - try { - return dateFormat.parse(jsonParser.getText()); - } catch (ParseException e) { - throw new InvalidFormatException(jsonParser, e.getMessage(), jsonParser.getText(), Long.class); - } - } else { - return null; - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/DateSerializer.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/DateSerializer.java deleted file mode 100644 index c0e3961..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/DateSerializer.java +++ /dev/null @@ -1,70 +0,0 @@ -package cc.smtweb.framework.core.util.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; -import java.util.Date; - -public class DateSerializer extends JsonSerializer { - - @Override - public void serialize(Date value, JsonGenerator gen, - SerializerProvider serializers) throws IOException, - JsonProcessingException { - if (value == null) { - gen.writeNull(); - } else { - gen.writeString(toString(value)); -// gen.writeNumber(value); -// gen.writeString("\""); - } - } - - @SuppressWarnings("deprecation") - public String toString (Date value) { - int year = value.getYear() + 1900; - int month = value.getMonth() + 1; - int day = value.getDate(); - String yearString; - String monthString; - String dayString; - String yearZeros = "0000"; - StringBuffer timestampBuf; - - if (year < 1000) { - // Add leading zeros - yearString = "" + year; - yearString = yearZeros.substring(0, (4-yearString.length())) + - yearString; - } else { - yearString = "" + year; - } - if (month < 10) { - monthString = "0" + month; - } else { - monthString = Integer.toString(month); - } - if (day < 10) { - dayString = "0" + day; - } else { - dayString = Integer.toString(day); - } - - // do a string buffer here instead. - timestampBuf = new StringBuffer(10); - timestampBuf.append(yearString); - timestampBuf.append("-"); - timestampBuf.append(monthString); - timestampBuf.append("-"); - timestampBuf.append(dayString); - - return (timestampBuf.toString()); - } - - public static void main(String[] args) { - System.out.println(new DateSerializer().toString(new Date())); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/LongDeserializer.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/LongDeserializer.java deleted file mode 100644 index ed8225b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/LongDeserializer.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.framework.core.util.jackson; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; -import org.apache.commons.lang3.StringUtils; - -import java.io.IOException; - -public class LongDeserializer extends JsonDeserializer { - @Override - public Long deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { - if (jsonParser != null && StringUtils.isNotBlank(jsonParser.getText())) { - try { - return Long.valueOf(jsonParser.getText()); - } catch (NumberFormatException e) { - throw new InvalidFormatException(jsonParser, e.getMessage(), jsonParser.getText(), Long.class); - } - } else { - return null; - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/LongSerializer.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/LongSerializer.java deleted file mode 100644 index d48d678..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/LongSerializer.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.smtweb.framework.core.util.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -public class LongSerializer extends JsonSerializer { - - @Override - public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - if (value == null) { - gen.writeNull(); - } else { - gen.writeString(String.valueOf(value)); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/NullSerializer.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/NullSerializer.java deleted file mode 100644 index 1c57c81..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/NullSerializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.smtweb.framework.core.util.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -public class NullSerializer extends JsonSerializer { - @Override - public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) - throws IOException { - jgen.writeString(""); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/TimeSerializer.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/TimeSerializer.java deleted file mode 100644 index ffc457b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/TimeSerializer.java +++ /dev/null @@ -1,61 +0,0 @@ -package cc.smtweb.framework.core.util.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; -import java.util.Date; - -public class TimeSerializer extends JsonSerializer { - - @Override - public void serialize(Date value, JsonGenerator gen, - SerializerProvider serializers) throws IOException, - JsonProcessingException { - if (value == null) { - gen.writeNull(); - } else { - gen.writeString(toString(value)); -// gen.writeNumber(value); -// gen.writeString("\""); - } - } - - @SuppressWarnings("deprecation") - public String toString (Date value) { - int hour = value.getHours(); - int minute = value.getMinutes(); - int second = value.getSeconds(); - String hourString; - String minuteString; - String secondString; - if (hour < 10) { - hourString = "0" + hour; - } else { - hourString = Integer.toString(hour); - } - if (minute < 10) { - minuteString = "0" + minute; - } else { - minuteString = Integer.toString(minute); - } - if (second < 10) { - secondString = "0" + second; - } else { - secondString = Integer.toString(second); - } - - // do a string buffer here instead. - StringBuffer timestampBuf = new StringBuffer(8); - timestampBuf.append(hourString); - timestampBuf.append(":"); - timestampBuf.append(minuteString); - timestampBuf.append(":"); - timestampBuf.append(secondString); - - return (timestampBuf.toString()); - } - -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/TimestampDeserializer.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/TimestampDeserializer.java deleted file mode 100644 index fb1a3a0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/jackson/TimestampDeserializer.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.smtweb.framework.core.util.jackson; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.exc.InvalidFormatException; -import org.apache.commons.lang3.StringUtils; - -import java.io.IOException; -import java.sql.Timestamp; -import java.text.ParseException; -import java.text.SimpleDateFormat; - -public class TimestampDeserializer extends JsonDeserializer { - @Override - public Timestamp deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { - if (jsonParser != null && StringUtils.isNotEmpty(jsonParser.getText())) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - try { - return new Timestamp(dateFormat.parse(jsonParser.getText()).getTime()); - } catch (ParseException e) { - throw new InvalidFormatException(jsonParser, e.getMessage(), jsonParser.getText(), Long.class); - } - } else { - return null; - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/kryo/KryoTool.java b/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/kryo/KryoTool.java deleted file mode 100644 index f444964..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/util/kryo/KryoTool.java +++ /dev/null @@ -1,78 +0,0 @@ -package cc.smtweb.framework.core.util.kryo; - -import com.esotericsoftware.kryo.Kryo; -import com.esotericsoftware.kryo.io.Input; -import com.esotericsoftware.kryo.io.Output; -import com.esotericsoftware.kryo.pool.KryoFactory; -import com.esotericsoftware.kryo.pool.KryoPool; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Serializable; - -/** - * 序列化工具类,单例 - */ -public class KryoTool { - private static KryoTool INST; - - static { - INST = new KryoTool(); - } - - public static KryoTool getINST() { - return INST; - } - - private KryoPool pool; - - public KryoTool() { - KryoFactory factory = () -> { - Kryo kryo = new Kryo(); - kryo.setReferences(false); - // 关闭注册 - kryo.setRegistrationRequired(false); - return kryo; - }; - - // Build pool with SoftReferences enabled (optional) - pool = new KryoPool.Builder(factory).softReferences().build(); - } - - public byte[] writeObject(T obj) { - byte[] result = null; - - if (obj != null) { - Kryo kryo = pool.borrow(); - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Output output = new Output(baos); - kryo.writeObject(output, obj); - output.close(); - - result = baos.toByteArray(); - } finally { - pool.release(kryo); - } - } - - return result; - } - - public T readObject(byte[] data, Class clazz) { - T result = null; - - if (data != null) { - Kryo kryo = pool.borrow(); - try { - ByteArrayInputStream bais = new ByteArrayInputStream(data); - Input input = new Input(bais); - result = kryo.readObject(input, clazz); - } finally { - pool.release(kryo); - } - } - - return result; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/AbstractTimer.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/AbstractTimer.java deleted file mode 100644 index c2713d0..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/AbstractTimer.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.serotonin.timer; - -import org.apache.commons.lang3.StringUtils; - -import java.util.List; - -abstract public class AbstractTimer { - abstract public boolean isInitialized(); - - abstract public long currentTimeMillis(); - - abstract public void execute(Runnable command); - - public void execute(Runnable command, String name) { - if (StringUtils.isBlank(name)) - execute(command); - else - execute(new NamedRunnable(command, name)); - } - - abstract public void execute(ScheduledRunnable command, long fireTime); - - public void execute(ScheduledRunnable command, long fireTime, String name) { - if (StringUtils.isBlank(name)) - execute(command, fireTime); - else - execute(new ScheduledNamedRunnable(command, name), fireTime); - } - - final public TimerTask schedule(TimerTask task) { - if (task.getTimer() == this) - throw new IllegalStateException("Task already scheduled or cancelled"); - - task.setTimer(this); - scheduleImpl(task); - - return task; - } - - public void scheduleAll(AbstractTimer that) { - for (TimerTask task : that.cancel()) - schedule(task); - } - - abstract protected void scheduleImpl(TimerTask task); - - abstract public List cancel(); - - abstract public int purge(); - - abstract public int size(); - - abstract public List getTasks(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/AbstractTimerTrigger.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/AbstractTimerTrigger.java deleted file mode 100644 index cd1ecbf..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/AbstractTimerTrigger.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.serotonin.timer; - -import java.util.Date; - -abstract public class AbstractTimerTrigger extends TimerTrigger { - private final boolean delayed; - private final long first; - - public AbstractTimerTrigger(long delay) { - this.delayed = true; - first = delay; - } - - public AbstractTimerTrigger(Date start) { - delayed = false; - first = start.getTime(); - } - - @Override - final protected long getFirstExecutionTime() { - if (delayed) - return timer.currentTimeMillis() + first; - return first; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/CronExpression.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/CronExpression.java deleted file mode 100644 index 8439758..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/CronExpression.java +++ /dev/null @@ -1,1444 +0,0 @@ -package com.serotonin.timer; - -import java.text.ParseException; -import java.util.*; - -/** - * Significant portions of this code (i.e. most of it) were lifted from the Quartz scheduling library for Java. - * - * @see http://www.quartz-scheduler.org/api/2.1.0/ - * - * @author Matthew Lohbihler (edits to make compatible with this package) - */ -public class CronExpression implements Cloneable { - protected static final int YEAR_AT_WHICH_TO_GIVE_UP_SCHEDULING = 2299; - - protected static final int SECOND = 0; - protected static final int MINUTE = 1; - protected static final int HOUR = 2; - protected static final int DAY_OF_MONTH = 3; - protected static final int MONTH = 4; - protected static final int DAY_OF_WEEK = 5; - protected static final int YEAR = 6; - protected static final int ALL_SPEC_INT = 99; // '*' - protected static final int NO_SPEC_INT = 98; // '?' - protected static final Integer ALL_SPEC = new Integer(ALL_SPEC_INT); - protected static final Integer NO_SPEC = new Integer(NO_SPEC_INT); - - protected static final Map monthMap = new HashMap(20); - protected static final Map dayMap = new HashMap(60); - static { - monthMap.put("JAN", new Integer(0)); - monthMap.put("FEB", new Integer(1)); - monthMap.put("MAR", new Integer(2)); - monthMap.put("APR", new Integer(3)); - monthMap.put("MAY", new Integer(4)); - monthMap.put("JUN", new Integer(5)); - monthMap.put("JUL", new Integer(6)); - monthMap.put("AUG", new Integer(7)); - monthMap.put("SEP", new Integer(8)); - monthMap.put("OCT", new Integer(9)); - monthMap.put("NOV", new Integer(10)); - monthMap.put("DEC", new Integer(11)); - - dayMap.put("SUN", new Integer(1)); - dayMap.put("MON", new Integer(2)); - dayMap.put("TUE", new Integer(3)); - dayMap.put("WED", new Integer(4)); - dayMap.put("THU", new Integer(5)); - dayMap.put("FRI", new Integer(6)); - dayMap.put("SAT", new Integer(7)); - } - - private String cronExpression = null; - private TimeZone timeZone = null; - protected transient TreeSet seconds; - protected transient TreeSet minutes; - protected transient TreeSet hours; - protected transient TreeSet daysOfMonth; - protected transient TreeSet months; - protected transient TreeSet daysOfWeek; - protected transient TreeSet years; - - protected transient boolean lastdayOfWeek = false; - protected transient int nthdayOfWeek = 0; - protected transient boolean lastdayOfMonth = false; - protected transient boolean nearestWeekday = false; - protected transient boolean expressionParsed = false; - - /** - * Constructs a new CronExpression based on the specified parameter. - * - * @param cronExpression - * String representation of the cron expression the new object should represent - * @throws ParseException - * if the string expression cannot be parsed into a valid CronExpression - */ - public CronExpression(String cronExpression) throws ParseException { - if (cronExpression == null) { - throw new IllegalArgumentException("cronExpression cannot be null"); - } - - this.cronExpression = cronExpression.toUpperCase(Locale.US); - - buildExpression(this.cronExpression); - } - - /** - * Indicates whether the given date satisfies the cron expression. Note that milliseconds are ignored, so two Dates - * falling on different milliseconds of the same second will always have the same result here. - * - * @param date - * the date to evaluate - * @return a boolean indicating whether the given date satisfies the cron expression - */ - public boolean isSatisfiedBy(Date date) { - Calendar testDateCal = Calendar.getInstance(getTimeZone()); - testDateCal.setTime(date); - testDateCal.set(Calendar.MILLISECOND, 0); - Date originalDate = testDateCal.getTime(); - - testDateCal.add(Calendar.SECOND, -1); - - Date timeAfter = getTimeAfter(testDateCal.getTime()); - - return ((timeAfter != null) && (timeAfter.equals(originalDate))); - } - - /** - * Returns the next date/time after the given date/time which satisfies the cron expression. - * - * @param date - * the date/time at which to begin the search for the next valid date/time - * @return the next valid date/time - */ - public Date getNextValidTimeAfter(Date date) { - return getTimeAfter(date); - } - - /** - * Returns the next date/time after the given date/time which does not satisfy the expression - * - * @param date - * the date/time at which to begin the search for the next invalid date/time - * @return the next valid date/time - */ - public Date getNextInvalidTimeAfter(Date date) { - long difference = 1000; - - // move back to the nearest second so differences will be accurate - Calendar adjustCal = Calendar.getInstance(getTimeZone()); - adjustCal.setTime(date); - adjustCal.set(Calendar.MILLISECOND, 0); - Date lastDate = adjustCal.getTime(); - - Date newDate = null; - - // TODO: (QUARTZ-481) IMPROVE THIS! The following is a BAD solution to this problem. Performance will be very - // bad here, depending on the cron expression. It is, however A solution. - - // keep getting the next included time until it's farther than one second - // apart. At that point, lastDate is the last valid fire time. We return - // the second immediately following it. - while (difference == 1000) { - newDate = getTimeAfter(lastDate); - - difference = newDate.getTime() - lastDate.getTime(); - - if (difference == 1000) { - lastDate = newDate; - } - } - - return new Date(lastDate.getTime() + 1000); - } - - /** - * Returns the time zone for which this CronExpression will be resolved. - */ - public TimeZone getTimeZone() { - if (timeZone == null) { - timeZone = TimeZone.getDefault(); - } - - return timeZone; - } - - /** - * Sets the time zone for which this CronExpression will be resolved. - */ - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; - } - - /** - * Returns the string representation of the CronExpression - * - * @return a string representation of the CronExpression - */ - @Override - public String toString() { - return cronExpression; - } - - /** - * Indicates whether the specified cron expression can be parsed into a valid cron expression - * - * @param cronExpression - * the expression to evaluate - * @return a boolean indicating whether the given expression is a valid cron expression - */ - public static boolean isValidExpression(String cronExpression) { - - try { - new CronExpression(cronExpression); - } - catch (ParseException pe) { - return false; - } - - return true; - } - - // ////////////////////////////////////////////////////////////////////////// - // - // Expression Parsing Functions - // - // ////////////////////////////////////////////////////////////////////////// - - protected void buildExpression(String expression) throws ParseException { - expressionParsed = true; - - try { - - if (seconds == null) { - seconds = new TreeSet(); - } - if (minutes == null) { - minutes = new TreeSet(); - } - if (hours == null) { - hours = new TreeSet(); - } - if (daysOfMonth == null) { - daysOfMonth = new TreeSet(); - } - if (months == null) { - months = new TreeSet(); - } - if (daysOfWeek == null) { - daysOfWeek = new TreeSet(); - } - if (years == null) { - years = new TreeSet(); - } - - int exprOn = SECOND; - - StringTokenizer exprsTok = new StringTokenizer(expression, " \t", false); - - while (exprsTok.hasMoreTokens() && exprOn <= YEAR) { - String expr = exprsTok.nextToken().trim(); - - // throw an exception if L is used with other days of the month - if (exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.indexOf(",") >= 0) { - throw new ParseException( - "Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1); - } - // throw an exception if L is used with other days of the week - if (exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.indexOf(",") >= 0) { - throw new ParseException( - "Support for specifying 'L' with other days of the week is not implemented", -1); - } - - StringTokenizer vTok = new StringTokenizer(expr, ","); - while (vTok.hasMoreTokens()) { - String v = vTok.nextToken(); - storeExpressionVals(0, v, exprOn); - } - - exprOn++; - } - - if (exprOn <= DAY_OF_WEEK) { - throw new ParseException("Unexpected end of expression.", expression.length()); - } - - if (exprOn <= YEAR) { - storeExpressionVals(0, "*", YEAR); - } - - TreeSet dow = getSet(DAY_OF_WEEK); - TreeSet dom = getSet(DAY_OF_MONTH); - - // Copying the logic from the UnsupportedOperationException below - boolean dayOfMSpec = !dom.contains(NO_SPEC); - boolean dayOfWSpec = !dow.contains(NO_SPEC); - - if (dayOfMSpec && !dayOfWSpec) { - // skip - } - else if (dayOfWSpec && !dayOfMSpec) { - // skip - } - else { - throw new ParseException( - "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.", 0); - } - } - catch (ParseException pe) { - throw pe; - } - catch (Exception e) { - throw new ParseException("Illegal cron expression format (" + e.toString() + ")", 0); - } - } - - protected int storeExpressionVals(int pos, String s, int type) throws ParseException { - - int incr = 0; - int i = skipWhiteSpace(pos, s); - if (i >= s.length()) { - return i; - } - char c = s.charAt(i); - if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW"))) { - String sub = s.substring(i, i + 3); - int sval = -1; - int eval = -1; - if (type == MONTH) { - sval = getMonthNumber(sub) + 1; - if (sval <= 0) { - throw new ParseException("Invalid Month value: '" + sub + "'", i); - } - if (s.length() > i + 3) { - c = s.charAt(i + 3); - if (c == '-') { - i += 4; - sub = s.substring(i, i + 3); - eval = getMonthNumber(sub) + 1; - if (eval <= 0) { - throw new ParseException("Invalid Month value: '" + sub + "'", i); - } - } - } - } - else if (type == DAY_OF_WEEK) { - sval = getDayOfWeekNumber(sub); - if (sval < 0) { - throw new ParseException("Invalid Day-of-Week value: '" + sub + "'", i); - } - if (s.length() > i + 3) { - c = s.charAt(i + 3); - if (c == '-') { - i += 4; - sub = s.substring(i, i + 3); - eval = getDayOfWeekNumber(sub); - if (eval < 0) { - throw new ParseException("Invalid Day-of-Week value: '" + sub + "'", i); - } - } - else if (c == '#') { - try { - i += 4; - nthdayOfWeek = Integer.parseInt(s.substring(i)); - if (nthdayOfWeek < 1 || nthdayOfWeek > 5) { - throw new Exception(); - } - } - catch (Exception e) { - throw new ParseException("A numeric value between 1 and 5 must follow the '#' option", i); - } - } - else if (c == 'L') { - lastdayOfWeek = true; - i++; - } - } - - } - else { - throw new ParseException("Illegal characters for this position: '" + sub + "'", i); - } - if (eval != -1) { - incr = 1; - } - addToSet(sval, eval, incr, type); - return (i + 3); - } - - if (c == '?') { - i++; - if ((i + 1) < s.length() && (s.charAt(i) != ' ' && s.charAt(i + 1) != '\t')) { - throw new ParseException("Illegal character after '?': " + s.charAt(i), i); - } - if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) { - throw new ParseException("'?' can only be specfied for Day-of-Month or Day-of-Week.", i); - } - if (type == DAY_OF_WEEK && !lastdayOfMonth) { - int val = (daysOfMonth.last()).intValue(); - if (val == NO_SPEC_INT) { - throw new ParseException("'?' can only be specfied for Day-of-Month -OR- Day-of-Week.", i); - } - } - - addToSet(NO_SPEC_INT, -1, 0, type); - return i; - } - - if (c == '*' || c == '/') { - if (c == '*' && (i + 1) >= s.length()) { - addToSet(ALL_SPEC_INT, -1, incr, type); - return i + 1; - } - else if (c == '/' && ((i + 1) >= s.length() || s.charAt(i + 1) == ' ' || s.charAt(i + 1) == '\t')) { - throw new ParseException("'/' must be followed by an integer.", i); - } - else if (c == '*') { - i++; - } - c = s.charAt(i); - if (c == '/') { // is an increment specified? - i++; - if (i >= s.length()) { - throw new ParseException("Unexpected end of string.", i); - } - - incr = getNumericValue(s, i); - - i++; - if (incr > 10) { - i++; - } - if (incr > 59 && (type == SECOND || type == MINUTE)) { - throw new ParseException("Increment > 60 : " + incr, i); - } - else if (incr > 23 && (type == HOUR)) { - throw new ParseException("Increment > 24 : " + incr, i); - } - else if (incr > 31 && (type == DAY_OF_MONTH)) { - throw new ParseException("Increment > 31 : " + incr, i); - } - else if (incr > 7 && (type == DAY_OF_WEEK)) { - throw new ParseException("Increment > 7 : " + incr, i); - } - else if (incr > 12 && (type == MONTH)) { - throw new ParseException("Increment > 12 : " + incr, i); - } - } - else { - incr = 1; - } - - addToSet(ALL_SPEC_INT, -1, incr, type); - return i; - } - else if (c == 'L') { - i++; - if (type == DAY_OF_MONTH) { - lastdayOfMonth = true; - } - if (type == DAY_OF_WEEK) { - addToSet(7, 7, 0, type); - } - if (type == DAY_OF_MONTH && s.length() > i) { - c = s.charAt(i); - if (c == 'W') { - nearestWeekday = true; - i++; - } - } - return i; - } - else if (c >= '0' && c <= '9') { - int val = Integer.parseInt(String.valueOf(c)); - i++; - if (i >= s.length()) { - addToSet(val, -1, -1, type); - } - else { - c = s.charAt(i); - if (c >= '0' && c <= '9') { - ValueSet vs = getValue(val, s, i); - val = vs.value; - i = vs.pos; - } - i = checkNext(i, s, val, type); - return i; - } - } - else { - throw new ParseException("Unexpected character: " + c, i); - } - - return i; - } - - protected int checkNext(int pos, String s, int val, int type) throws ParseException { - - int end = -1; - int i = pos; - - if (i >= s.length()) { - addToSet(val, end, -1, type); - return i; - } - - char c = s.charAt(pos); - - if (c == 'L') { - if (type == DAY_OF_WEEK) { - lastdayOfWeek = true; - } - else { - throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i); - } - TreeSet set = getSet(type); - set.add(new Integer(val)); - i++; - return i; - } - - if (c == 'W') { - if (type == DAY_OF_MONTH) { - nearestWeekday = true; - } - else { - throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i); - } - TreeSet set = getSet(type); - set.add(new Integer(val)); - i++; - return i; - } - - if (c == '#') { - if (type != DAY_OF_WEEK) { - throw new ParseException("'#' option is not valid here. (pos=" + i + ")", i); - } - i++; - try { - nthdayOfWeek = Integer.parseInt(s.substring(i)); - if (nthdayOfWeek < 1 || nthdayOfWeek > 5) { - throw new Exception(); - } - } - catch (Exception e) { - throw new ParseException("A numeric value between 1 and 5 must follow the '#' option", i); - } - - TreeSet set = getSet(type); - set.add(new Integer(val)); - i++; - return i; - } - - if (c == '-') { - i++; - c = s.charAt(i); - int v = Integer.parseInt(String.valueOf(c)); - end = v; - i++; - if (i >= s.length()) { - addToSet(val, end, 1, type); - return i; - } - c = s.charAt(i); - if (c >= '0' && c <= '9') { - ValueSet vs = getValue(v, s, i); - int v1 = vs.value; - end = v1; - i = vs.pos; - } - if (i < s.length() && ((c = s.charAt(i)) == '/')) { - i++; - c = s.charAt(i); - int v2 = Integer.parseInt(String.valueOf(c)); - i++; - if (i >= s.length()) { - addToSet(val, end, v2, type); - return i; - } - c = s.charAt(i); - if (c >= '0' && c <= '9') { - ValueSet vs = getValue(v2, s, i); - int v3 = vs.value; - addToSet(val, end, v3, type); - i = vs.pos; - return i; - } - - addToSet(val, end, v2, type); - return i; - } - - addToSet(val, end, 1, type); - return i; - } - - if (c == '/') { - i++; - c = s.charAt(i); - int v2 = Integer.parseInt(String.valueOf(c)); - i++; - if (i >= s.length()) { - addToSet(val, end, v2, type); - return i; - } - c = s.charAt(i); - if (c >= '0' && c <= '9') { - ValueSet vs = getValue(v2, s, i); - int v3 = vs.value; - addToSet(val, end, v3, type); - i = vs.pos; - return i; - } - - throw new ParseException("Unexpected character '" + c + "' after '/'", i); - } - - addToSet(val, end, 0, type); - i++; - return i; - } - - public String getCronExpression() { - return cronExpression; - } - - public String getExpressionSummary() { - StringBuffer buf = new StringBuffer(); - - buf.append("seconds: "); - buf.append(getExpressionSetSummary(seconds)); - buf.append("\n"); - buf.append("minutes: "); - buf.append(getExpressionSetSummary(minutes)); - buf.append("\n"); - buf.append("hours: "); - buf.append(getExpressionSetSummary(hours)); - buf.append("\n"); - buf.append("daysOfMonth: "); - buf.append(getExpressionSetSummary(daysOfMonth)); - buf.append("\n"); - buf.append("months: "); - buf.append(getExpressionSetSummary(months)); - buf.append("\n"); - buf.append("daysOfWeek: "); - buf.append(getExpressionSetSummary(daysOfWeek)); - buf.append("\n"); - buf.append("lastdayOfWeek: "); - buf.append(lastdayOfWeek); - buf.append("\n"); - buf.append("nearestWeekday: "); - buf.append(nearestWeekday); - buf.append("\n"); - buf.append("NthDayOfWeek: "); - buf.append(nthdayOfWeek); - buf.append("\n"); - buf.append("lastdayOfMonth: "); - buf.append(lastdayOfMonth); - buf.append("\n"); - buf.append("years: "); - buf.append(getExpressionSetSummary(years)); - buf.append("\n"); - - return buf.toString(); - } - - protected String getExpressionSetSummary(Set set) { - - if (set.contains(NO_SPEC)) { - return "?"; - } - if (set.contains(ALL_SPEC)) { - return "*"; - } - - StringBuffer buf = new StringBuffer(); - - Iterator itr = set.iterator(); - boolean first = true; - while (itr.hasNext()) { - Integer iVal = itr.next(); - String val = iVal.toString(); - if (!first) { - buf.append(","); - } - buf.append(val); - first = false; - } - - return buf.toString(); - } - - protected String getExpressionSetSummary(List list) { - - if (list.contains(NO_SPEC)) { - return "?"; - } - if (list.contains(ALL_SPEC)) { - return "*"; - } - - StringBuffer buf = new StringBuffer(); - - Iterator itr = list.iterator(); - boolean first = true; - while (itr.hasNext()) { - Integer iVal = itr.next(); - String val = iVal.toString(); - if (!first) { - buf.append(","); - } - buf.append(val); - first = false; - } - - return buf.toString(); - } - - protected int skipWhiteSpace(int i, String s) { - for (; i < s.length() && (s.charAt(i) == ' ' || s.charAt(i) == '\t'); i++) { - ; - } - - return i; - } - - protected int findNextWhiteSpace(int i, String s) { - for (; i < s.length() && (s.charAt(i) != ' ' || s.charAt(i) != '\t'); i++) { - ; - } - - return i; - } - - protected void addToSet(int val, int end, int incr, int type) throws ParseException { - - TreeSet set = getSet(type); - - if (type == SECOND || type == MINUTE) { - if ((val < 0 || val > 59 || end > 59) && (val != ALL_SPEC_INT)) { - throw new ParseException("Minute and Second values must be between 0 and 59", -1); - } - } - else if (type == HOUR) { - if ((val < 0 || val > 23 || end > 23) && (val != ALL_SPEC_INT)) { - throw new ParseException("Hour values must be between 0 and 23", -1); - } - } - else if (type == DAY_OF_MONTH) { - if ((val < 1 || val > 31 || end > 31) && (val != ALL_SPEC_INT) && (val != NO_SPEC_INT)) { - throw new ParseException("Day of month values must be between 1 and 31", -1); - } - } - else if (type == MONTH) { - if ((val < 1 || val > 12 || end > 12) && (val != ALL_SPEC_INT)) { - throw new ParseException("Month values must be between 1 and 12", -1); - } - } - else if (type == DAY_OF_WEEK) { - if ((val == 0 || val > 7 || end > 7) && (val != ALL_SPEC_INT) && (val != NO_SPEC_INT)) { - throw new ParseException("Day-of-Week values must be between 1 and 7", -1); - } - } - - if ((incr == 0 || incr == -1) && val != ALL_SPEC_INT) { - if (val != -1) { - set.add(new Integer(val)); - } - else { - set.add(NO_SPEC); - } - - return; - } - - int startAt = val; - int stopAt = end; - - if (val == ALL_SPEC_INT && incr <= 0) { - incr = 1; - set.add(ALL_SPEC); // put in a marker, but also fill values - } - - if (type == SECOND || type == MINUTE) { - if (stopAt == -1) { - stopAt = 59; - } - if (startAt == -1 || startAt == ALL_SPEC_INT) { - startAt = 0; - } - } - else if (type == HOUR) { - if (stopAt == -1) { - stopAt = 23; - } - if (startAt == -1 || startAt == ALL_SPEC_INT) { - startAt = 0; - } - } - else if (type == DAY_OF_MONTH) { - if (stopAt == -1) { - stopAt = 31; - } - if (startAt == -1 || startAt == ALL_SPEC_INT) { - startAt = 1; - } - } - else if (type == MONTH) { - if (stopAt == -1) { - stopAt = 12; - } - if (startAt == -1 || startAt == ALL_SPEC_INT) { - startAt = 1; - } - } - else if (type == DAY_OF_WEEK) { - if (stopAt == -1) { - stopAt = 7; - } - if (startAt == -1 || startAt == ALL_SPEC_INT) { - startAt = 1; - } - } - else if (type == YEAR) { - if (stopAt == -1) { - stopAt = YEAR_AT_WHICH_TO_GIVE_UP_SCHEDULING; - } - if (startAt == -1 || startAt == ALL_SPEC_INT) { - startAt = 1970; - } - } - - // if the end of the range is before the start, then we need to overflow into - // the next day, month etc. This is done by adding the maximum amount for that - // type, and using modulus max to determine the value being added. - int max = -1; - if (stopAt < startAt) { - switch (type) { - case SECOND: - max = 60; - break; - case MINUTE: - max = 60; - break; - case HOUR: - max = 24; - break; - case MONTH: - max = 12; - break; - case DAY_OF_WEEK: - max = 7; - break; - case DAY_OF_MONTH: - max = 31; - break; - case YEAR: - throw new IllegalArgumentException("Start year must be less than stop year"); - default: - throw new IllegalArgumentException("Unexpected type encountered"); - } - stopAt += max; - } - - for (int i = startAt; i <= stopAt; i += incr) { - if (max == -1) { - // ie: there's no max to overflow over - set.add(new Integer(i)); - } - else { - // take the modulus to get the real value - int i2 = i % max; - - // 1-indexed ranges should not include 0, and should include their max - if (i2 == 0 && (type == MONTH || type == DAY_OF_WEEK || type == DAY_OF_MONTH)) { - i2 = max; - } - - set.add(new Integer(i2)); - } - } - } - - protected TreeSet getSet(int type) { - switch (type) { - case SECOND: - return seconds; - case MINUTE: - return minutes; - case HOUR: - return hours; - case DAY_OF_MONTH: - return daysOfMonth; - case MONTH: - return months; - case DAY_OF_WEEK: - return daysOfWeek; - case YEAR: - return years; - default: - return null; - } - } - - protected ValueSet getValue(int v, String s, int i) { - char c = s.charAt(i); - String s1 = String.valueOf(v); - while (c >= '0' && c <= '9') { - s1 += c; - i++; - if (i >= s.length()) { - break; - } - c = s.charAt(i); - } - ValueSet val = new ValueSet(); - - val.pos = (i < s.length()) ? i : i + 1; - val.value = Integer.parseInt(s1); - return val; - } - - protected int getNumericValue(String s, int i) { - int endOfVal = findNextWhiteSpace(i, s); - String val = s.substring(i, endOfVal); - return Integer.parseInt(val); - } - - protected int getMonthNumber(String s) { - Integer integer = monthMap.get(s); - - if (integer == null) { - return -1; - } - - return integer.intValue(); - } - - protected int getDayOfWeekNumber(String s) { - Integer integer = dayMap.get(s); - - if (integer == null) { - return -1; - } - - return integer.intValue(); - } - - // ////////////////////////////////////////////////////////////////////////// - // - // Computation Functions - // - // ////////////////////////////////////////////////////////////////////////// - - protected Date getTimeAfter(Date afterTime) { - - // Computation is based on Gregorian year only. - Calendar cl = new GregorianCalendar(getTimeZone()); - - // move ahead one second, since we're computing the time *after* the - // given time - afterTime = new Date(afterTime.getTime() + 1000); - // CronTrigger does not deal with milliseconds - cl.setTime(afterTime); - cl.set(Calendar.MILLISECOND, 0); - - boolean gotOne = false; - // loop until we've computed the next time, or we've past the endTime - while (!gotOne) { - - // if (endTime != null && cl.getTime().after(endTime)) return null; - if (cl.get(Calendar.YEAR) > 2999) { // prevent endless loop... - return null; - } - - SortedSet st = null; - int t = 0; - - int sec = cl.get(Calendar.SECOND); - int min = cl.get(Calendar.MINUTE); - - // get second................................................. - st = seconds.tailSet(new Integer(sec)); - if (st != null && st.size() != 0) { - sec = (st.first()).intValue(); - } - else { - sec = (seconds.first()).intValue(); - min++; - cl.set(Calendar.MINUTE, min); - } - cl.set(Calendar.SECOND, sec); - - min = cl.get(Calendar.MINUTE); - int hr = cl.get(Calendar.HOUR_OF_DAY); - t = -1; - - // get minute................................................. - st = minutes.tailSet(new Integer(min)); - if (st != null && st.size() != 0) { - t = min; - min = (st.first()).intValue(); - } - else { - min = (minutes.first()).intValue(); - hr++; - } - if (min != t) { - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, min); - setCalendarHour(cl, hr); - continue; - } - cl.set(Calendar.MINUTE, min); - - hr = cl.get(Calendar.HOUR_OF_DAY); - int day = cl.get(Calendar.DAY_OF_MONTH); - t = -1; - - // get hour................................................... - st = hours.tailSet(new Integer(hr)); - if (st != null && st.size() != 0) { - t = hr; - hr = (st.first()).intValue(); - } - else { - hr = (hours.first()).intValue(); - day++; - } - if (hr != t) { - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.DAY_OF_MONTH, day); - setCalendarHour(cl, hr); - continue; - } - cl.set(Calendar.HOUR_OF_DAY, hr); - - day = cl.get(Calendar.DAY_OF_MONTH); - int mon = cl.get(Calendar.MONTH) + 1; - // '+ 1' because calendar is 0-based for this field, and we are - // 1-based - t = -1; - int tmon = mon; - - // get day................................................... - boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC); - boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC); - if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule - st = daysOfMonth.tailSet(new Integer(day)); - if (lastdayOfMonth) { - if (!nearestWeekday) { - t = day; - day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); - } - else { - t = day; - day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); - - Calendar tcal = Calendar.getInstance(getTimeZone()); - tcal.set(Calendar.SECOND, 0); - tcal.set(Calendar.MINUTE, 0); - tcal.set(Calendar.HOUR_OF_DAY, 0); - tcal.set(Calendar.DAY_OF_MONTH, day); - tcal.set(Calendar.MONTH, mon - 1); - tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR)); - - int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); - int dow = tcal.get(Calendar.DAY_OF_WEEK); - - if (dow == Calendar.SATURDAY && day == 1) { - day += 2; - } - else if (dow == Calendar.SATURDAY) { - day -= 1; - } - else if (dow == Calendar.SUNDAY && day == ldom) { - day -= 2; - } - else if (dow == Calendar.SUNDAY) { - day += 1; - } - - tcal.set(Calendar.SECOND, sec); - tcal.set(Calendar.MINUTE, min); - tcal.set(Calendar.HOUR_OF_DAY, hr); - tcal.set(Calendar.DAY_OF_MONTH, day); - tcal.set(Calendar.MONTH, mon - 1); - Date nTime = tcal.getTime(); - if (nTime.before(afterTime)) { - day = 1; - mon++; - } - } - } - else if (nearestWeekday) { - t = day; - day = (daysOfMonth.first()).intValue(); - - Calendar tcal = Calendar.getInstance(getTimeZone()); - tcal.set(Calendar.SECOND, 0); - tcal.set(Calendar.MINUTE, 0); - tcal.set(Calendar.HOUR_OF_DAY, 0); - tcal.set(Calendar.DAY_OF_MONTH, day); - tcal.set(Calendar.MONTH, mon - 1); - tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR)); - - int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); - int dow = tcal.get(Calendar.DAY_OF_WEEK); - - if (dow == Calendar.SATURDAY && day == 1) { - day += 2; - } - else if (dow == Calendar.SATURDAY) { - day -= 1; - } - else if (dow == Calendar.SUNDAY && day == ldom) { - day -= 2; - } - else if (dow == Calendar.SUNDAY) { - day += 1; - } - - tcal.set(Calendar.SECOND, sec); - tcal.set(Calendar.MINUTE, min); - tcal.set(Calendar.HOUR_OF_DAY, hr); - tcal.set(Calendar.DAY_OF_MONTH, day); - tcal.set(Calendar.MONTH, mon - 1); - Date nTime = tcal.getTime(); - if (nTime.before(afterTime)) { - day = (daysOfMonth.first()).intValue(); - mon++; - } - } - else if (st != null && st.size() != 0) { - t = day; - day = (st.first()).intValue(); - // make sure we don't over-run a short month, such as february - int lastDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); - if (day > lastDay) { - day = (daysOfMonth.first()).intValue(); - mon++; - } - } - else { - day = (daysOfMonth.first()).intValue(); - mon++; - } - - if (day != t || mon != tmon) { - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, day); - cl.set(Calendar.MONTH, mon - 1); - // '- 1' because calendar is 0-based for this field, and we - // are 1-based - continue; - } - } - else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule - if (lastdayOfWeek) { // are we looking for the last XXX day of - // the month? - int dow = (daysOfWeek.first()).intValue(); // desired - // d-o-w - int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w - int daysToAdd = 0; - if (cDow < dow) { - daysToAdd = dow - cDow; - } - if (cDow > dow) { - daysToAdd = dow + (7 - cDow); - } - - int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); - - if (day + daysToAdd > lDay) { // did we already miss the - // last one? - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, 1); - cl.set(Calendar.MONTH, mon); - // no '- 1' here because we are promoting the month - continue; - } - - // find date of last occurance of this day in this month... - while ((day + daysToAdd + 7) <= lDay) { - daysToAdd += 7; - } - - day += daysToAdd; - - if (daysToAdd > 0) { - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, day); - cl.set(Calendar.MONTH, mon - 1); - // '- 1' here because we are not promoting the month - continue; - } - - } - else if (nthdayOfWeek != 0) { - // are we looking for the Nth XXX day in the month? - int dow = (daysOfWeek.first()).intValue(); // desired - // d-o-w - int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w - int daysToAdd = 0; - if (cDow < dow) { - daysToAdd = dow - cDow; - } - else if (cDow > dow) { - daysToAdd = dow + (7 - cDow); - } - - boolean dayShifted = false; - if (daysToAdd > 0) { - dayShifted = true; - } - - day += daysToAdd; - int weekOfMonth = day / 7; - if (day % 7 > 0) { - weekOfMonth++; - } - - daysToAdd = (nthdayOfWeek - weekOfMonth) * 7; - day += daysToAdd; - if (daysToAdd < 0 || day > getLastDayOfMonth(mon, cl.get(Calendar.YEAR))) { - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, 1); - cl.set(Calendar.MONTH, mon); - // no '- 1' here because we are promoting the month - continue; - } - else if (daysToAdd > 0 || dayShifted) { - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, day); - cl.set(Calendar.MONTH, mon - 1); - // '- 1' here because we are NOT promoting the month - continue; - } - } - else { - int cDow = cl.get(Calendar.DAY_OF_WEEK); // current d-o-w - int dow = (daysOfWeek.first()).intValue(); // desired - // d-o-w - st = daysOfWeek.tailSet(new Integer(cDow)); - if (st != null && st.size() > 0) { - dow = (st.first()).intValue(); - } - - int daysToAdd = 0; - if (cDow < dow) { - daysToAdd = dow - cDow; - } - if (cDow > dow) { - daysToAdd = dow + (7 - cDow); - } - - int lDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); - - if (day + daysToAdd > lDay) { // will we pass the end of - // the month? - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, 1); - cl.set(Calendar.MONTH, mon); - // no '- 1' here because we are promoting the month - continue; - } - else if (daysToAdd > 0) { // are we swithing days? - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, day + daysToAdd); - cl.set(Calendar.MONTH, mon - 1); - // '- 1' because calendar is 0-based for this field, - // and we are 1-based - continue; - } - } - } - else { // dayOfWSpec && !dayOfMSpec - throw new UnsupportedOperationException( - "Support for specifying both a day-of-week AND a day-of-month parameter is not implemented."); - // TODO: - } - cl.set(Calendar.DAY_OF_MONTH, day); - - mon = cl.get(Calendar.MONTH) + 1; - // '+ 1' because calendar is 0-based for this field, and we are - // 1-based - int year = cl.get(Calendar.YEAR); - t = -1; - - // test for expressions that never generate a valid fire date, - // but keep looping... - if (year > YEAR_AT_WHICH_TO_GIVE_UP_SCHEDULING) { - return null; - } - - // get month................................................... - st = months.tailSet(new Integer(mon)); - if (st != null && st.size() != 0) { - t = mon; - mon = (st.first()).intValue(); - } - else { - mon = (months.first()).intValue(); - year++; - } - if (mon != t) { - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, 1); - cl.set(Calendar.MONTH, mon - 1); - // '- 1' because calendar is 0-based for this field, and we are - // 1-based - cl.set(Calendar.YEAR, year); - continue; - } - cl.set(Calendar.MONTH, mon - 1); - // '- 1' because calendar is 0-based for this field, and we are - // 1-based - - year = cl.get(Calendar.YEAR); - t = -1; - - // get year................................................... - st = years.tailSet(new Integer(year)); - if (st != null && st.size() != 0) { - t = year; - year = (st.first()).intValue(); - } - else { - return null; // ran out of years... - } - - if (year != t) { - cl.set(Calendar.SECOND, 0); - cl.set(Calendar.MINUTE, 0); - cl.set(Calendar.HOUR_OF_DAY, 0); - cl.set(Calendar.DAY_OF_MONTH, 1); - cl.set(Calendar.MONTH, 0); - // '- 1' because calendar is 0-based for this field, and we are - // 1-based - cl.set(Calendar.YEAR, year); - continue; - } - cl.set(Calendar.YEAR, year); - - gotOne = true; - } // while( !done ) - - return cl.getTime(); - } - - /** - * Advance the calendar to the particular hour paying particular attention to daylight saving problems. - * - * @param cal - * @param hour - */ - protected void setCalendarHour(Calendar cal, int hour) { - cal.set(Calendar.HOUR_OF_DAY, hour); - if (cal.get(Calendar.HOUR_OF_DAY) != hour && hour != 24) { - cal.set(Calendar.HOUR_OF_DAY, hour + 1); - } - } - - /** - * NOT YET IMPLEMENTED: Returns the time before the given time that the CronExpression matches. - */ - protected Date getTimeBefore(@SuppressWarnings("unused") Date endTime) { - // TODO: implement QUARTZ-423 - return null; - } - - /** - * NOT YET IMPLEMENTED: Returns the final time that the CronExpression will match. - */ - public Date getFinalFireTime() { - // TODO: implement QUARTZ-423 - return null; - } - - protected boolean isLeapYear(int year) { - return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)); - } - - protected int getLastDayOfMonth(int monthNum, int year) { - - switch (monthNum) { - case 1: - return 31; - case 2: - return (isLeapYear(year)) ? 29 : 28; - case 3: - return 31; - case 4: - return 30; - case 5: - return 31; - case 6: - return 30; - case 7: - return 31; - case 8: - return 31; - case 9: - return 30; - case 10: - return 31; - case 11: - return 30; - case 12: - return 31; - default: - throw new IllegalArgumentException("Illegal month number: " + monthNum); - } - } - - private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException { - stream.defaultReadObject(); - try { - buildExpression(cronExpression); - } - catch (Exception ignore) { - // never happens - } - } - - @Override - public Object clone() { - CronExpression copy = null; - try { - copy = new CronExpression(getCronExpression()); - if (getTimeZone() != null) - copy.setTimeZone((TimeZone) getTimeZone().clone()); - } - catch (ParseException ex) { // never happens since the source is valid... - throw new IncompatibleClassChangeError("Not Cloneable."); - } - return copy; - } -} - -class ValueSet { - public int value; - - public int pos; -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/CronTimerTrigger.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/CronTimerTrigger.java deleted file mode 100644 index 3c55a1b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/CronTimerTrigger.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.serotonin.timer; - -import java.text.ParseException; -import java.util.Date; - -public class CronTimerTrigger extends TimerTrigger { - private final CronExpression cronExpression; - private long mostRecent; - - public CronTimerTrigger(String pattern) throws ParseException { - cronExpression = new CronExpression(pattern); - } - - @Override - protected long calculateNextExecutionTimeImpl() { - mostRecent = nextExecutionTime; - return cronExpression.getNextValidTimeAfter(new Date(nextExecutionTime)).getTime(); - } - - @Override - protected long calculateNextExecutionTimeImpl(long after) { - return cronExpression.getNextValidTimeAfter(new Date(after)).getTime(); - } - - @Override - protected long getFirstExecutionTime() { - return cronExpression.getNextValidTimeAfter(new Date(timer.currentTimeMillis())).getTime(); - } - - @Override - public long mostRecentExecutionTime() { - return mostRecent; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ExecutionRejectedException.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ExecutionRejectedException.java deleted file mode 100644 index abf9455..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ExecutionRejectedException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.serotonin.timer; - -public class ExecutionRejectedException extends Exception { - /** - * - */ - private static final long serialVersionUID = 1L; - - public ExecutionRejectedException() { - super(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/FixedDelayTrigger.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/FixedDelayTrigger.java deleted file mode 100644 index 9f7e141..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/FixedDelayTrigger.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.serotonin.timer; - -import java.util.Date; - -public class FixedDelayTrigger extends AbstractTimerTrigger { - private final long period; - - public FixedDelayTrigger(long delay, long period) { - super(delay); - this.period = period; - } - - public FixedDelayTrigger(Date start, long period) { - super(start); - this.period = period; - } - - @Override - protected long calculateNextExecutionTimeImpl() { - return timer.currentTimeMillis() + period; - } - - @Override - protected long calculateNextExecutionTimeImpl(long after) { - return after + period; - } - - @Override - public long mostRecentExecutionTime() { - return nextExecutionTime - period; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/FixedRateTrigger.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/FixedRateTrigger.java deleted file mode 100644 index 0e778e2..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/FixedRateTrigger.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.serotonin.timer; - -import java.util.Date; - -public class FixedRateTrigger extends AbstractTimerTrigger { - private final long period; - - /** - * Use this constructor to quantize the start of the trigger to the period. - * - * @param period - * @param now - * @param quantize - * unused. Required for signature uniqueness. - */ - public FixedRateTrigger(long period, long now, boolean quantize) { - this(new Date(now + period - (now % period)), period); - } - - public FixedRateTrigger(long delay, long period) { - super(delay); - this.period = period; - } - - public FixedRateTrigger(Date start, long period) { - super(start); - this.period = period; - } - - @Override - protected long calculateNextExecutionTimeImpl() { - return nextExecutionTime + period; - } - - @Override - protected long calculateNextExecutionTimeImpl(long after) { - long d = after - nextExecutionTime; - if (d < 0) - return nextExecutionTime + period; - - long periods = d / period; - return nextExecutionTime + period * (periods + 1); - } - - @Override - public long mostRecentExecutionTime() { - return nextExecutionTime - period; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ModelTimeoutClient.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ModelTimeoutClient.java deleted file mode 100644 index 91c0f1e..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ModelTimeoutClient.java +++ /dev/null @@ -1,9 +0,0 @@ -/* - Copyright (C) 2006-2011 Serotonin Software Technologies Inc. All rights reserved. - @author Matthew Lohbihler - */ -package com.serotonin.timer; - -public interface ModelTimeoutClient { - void scheduleTimeout(T model, long fireTime); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ModelTimeoutTask.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ModelTimeoutTask.java deleted file mode 100644 index 5f5438d..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ModelTimeoutTask.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.serotonin.timer; - -import java.util.Date; - -/** - * A parameterizable one-time task. Allows the pass-through of a model to the target. - * - * @author Matthew - * - * @param - */ -public class ModelTimeoutTask extends TimerTask { - private final ModelTimeoutClient client; - private final T model; - - public ModelTimeoutTask(long delay, ModelTimeoutClient client, T model) { - this(new OneTimeTrigger(delay), client, model); - } - - public ModelTimeoutTask(Date date, ModelTimeoutClient client, T model) { - this(new OneTimeTrigger(date), client, model); - } - - public ModelTimeoutTask(TimerTrigger trigger, ModelTimeoutClient client, T model) { - super(trigger); - this.client = client; - this.model = model; - } - - @Override - public void run(long runtime) { - client.scheduleTimeout(model, runtime); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/NamedRunnable.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/NamedRunnable.java deleted file mode 100644 index 6d4b116..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/NamedRunnable.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.serotonin.timer; - -/** - * A class that wraps a Runnable and sets the thread name to the given name. - * - * @author Matthew Lohbihler - */ -public class NamedRunnable implements Runnable { - private final Runnable runnable; - private final String name; - - public NamedRunnable(Runnable runnable, String name) { - this.runnable = runnable; - this.name = name; - } - - public void run() { - String originalName = Thread.currentThread().getName(); - - // Append the given name to the original name. - Thread.currentThread().setName(originalName + " --> " + name); - - try { - // Ok, go ahead and run the thingy. - runnable.run(); - } - finally { - // Return the name to its original. - Thread.currentThread().setName(originalName); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/NonConcurrentTask.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/NonConcurrentTask.java deleted file mode 100644 index 37229a4..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/NonConcurrentTask.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.serotonin.timer; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Date; - -/** - * Extends the timer task to prevent tasks from running concurrently. This is useful when a job is run regularly on a - * schedule, and there may be cases where a particular run could go on so long that is not finished before the next is - * scheduled to begin. In such cases, the next job will be aborted, and a warning message will be written to the log. - * - * @author Matthew Lohbihler - */ -abstract public class NonConcurrentTask extends TimerTask { - private static final Log LOG = LogFactory.getLog(NonConcurrentTask.class); - - private Thread thread; - private long threadRuntime; - - public NonConcurrentTask(TimerTrigger trigger) { - super(trigger); - } - - public NonConcurrentTask(TimerTrigger trigger, String name) { - super(trigger, name); - } - - @Override - final public void run(long runtime) { - Thread localThread = thread; - if (localThread != null) { - LOG.warn("NonConcurrentTask run at " + new Date(runtime) + " aborted because another run at " - + new Date(threadRuntime) + " has not yet completed: " + getClass().getName()); - return; - } - - try { - thread = Thread.currentThread(); - threadRuntime = runtime; - runNonConcurrent(runtime); - } - finally { - thread = null; - } - } - - abstract public void runNonConcurrent(long runtime); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/OneTimeTrigger.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/OneTimeTrigger.java deleted file mode 100644 index a804238..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/OneTimeTrigger.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.serotonin.timer; - -import java.util.Date; - -public class OneTimeTrigger extends AbstractTimerTrigger { - public OneTimeTrigger(long delay) { - super(delay); - } - - public OneTimeTrigger(Date start) { - super(start); - } - - @Override - protected long calculateNextExecutionTimeImpl() { - return 0; - } - - @Override - protected long calculateNextExecutionTimeImpl(long after) { - return 0; - } - - @Override - final public long mostRecentExecutionTime() { - return nextExecutionTime; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/RealTimeTimer.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/RealTimeTimer.java deleted file mode 100644 index 22f43b3..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/RealTimeTimer.java +++ /dev/null @@ -1,320 +0,0 @@ -package com.serotonin.timer; - -import org.apache.commons.lang3.concurrent.BasicThreadFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.*; - - -public class RealTimeTimer extends AbstractTimer { - private static final Log LOG = LogFactory.getLog(RealTimeTimer.class); - - /** - * The timer task queue. This data structure is shared with the timer thread. The timer produces tasks, via its - * various schedule calls, and the timer thread consumes, executing timer tasks as appropriate, and removing them - * from the queue when they're obsolete. - */ - private final TaskQueue queue = new TaskQueue(); - - /** - * The timer thread. - */ - private TimerThread thread; - - // Do i own the executor? - private boolean ownsExecutor; - private Exception cancelStack; - - private TimeSource timeSource = new SystemTimeSource(); - - public void setTimeSource(TimeSource timeSource) { - this.timeSource = timeSource; - } - - public void init(int minThread, int maxThread) { - ownsExecutor = true; - ThreadFactory threadFactory = new BasicThreadFactory.Builder() - .namingPattern("sw-timer-").build(); - init(new ThreadPoolExecutor(minThread, maxThread, 30L, TimeUnit.SECONDS, new SynchronousQueue<>(), threadFactory)); - } - - public void init(ExecutorService executorService) { - thread = new TimerThread(queue, executorService, timeSource); - thread.setName("Serotonin Timer"); - thread.setDaemon(false); - thread.start(); - } - - @Override - public boolean isInitialized() { - return thread != null; - } - - /** - * This object causes the timer's task execution thread to exit gracefully when there are no live references to the - * Timer object and no tasks in the timer queue. It is used in preference to a finalizer on Timer as such a - * finalizer would be susceptible to a subclass's finalizer forgetting to call it. - */ - @Override - protected void finalize() { - synchronized (queue) { - if (thread != null) - thread.newTasksMayBeScheduled = false; - if (cancelStack == null) - cancelStack = new Exception(); - queue.notify(); - } - } - - /** - * A convenience method that executes the given command in the executor service immediately. - * - * @param command - * @throws ExecutionRejectedException - */ - @Override - public void execute(Runnable command) { - if (thread == null) - throw new IllegalStateException("Run init first"); - thread.execute(command); - } - - /** - * A convenience method that executes the given command in the executor service immediately. - * - * @param command - * @throws ExecutionRejectedException - */ - @Override - public void execute(ScheduledRunnable command, long fireTime) { - if (thread == null) - throw new IllegalStateException("Run init first"); - thread.execute(command, fireTime); - } - - /** - * Schedule the specified timer task for execution at the specified time with the specified period, in milliseconds. - * If period is positive, the task is scheduled for repeated execution; if period is zero, the task is scheduled for - * one-time execution. Time is specified in Date.getTime() format. This method checks timer state, task state, and - * initial execution time, but not period. - * - * @throws IllegalArgumentException - * if time() is negative. - * @throws IllegalStateException - * if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated. - */ - @Override - protected void scheduleImpl(TimerTask task) { - if (thread == null) - throw new IllegalStateException("Run init first"); - - if (task.state == TimerTask.CANCELLED || task.state == TimerTask.EXECUTED) - throw new IllegalStateException("Task already executed or cancelled"); - - synchronized (queue) { - if (!thread.newTasksMayBeScheduled) { - if (cancelStack != null) { - LOG.error("Timer already cancelled."); - LOG.error(" Cancel stack:", cancelStack); - LOG.error(" Current stack:", new Exception()); - throw new IllegalStateException("Timer already cancelled.", cancelStack); - } - throw new IllegalStateException("Timer already cancelled."); - } - - synchronized (task.lock) { - if (task.state == TimerTask.VIRGIN) { - long time = task.trigger.getFirstExecutionTime(); - - if (time < 0) - throw new IllegalArgumentException("Illegal execution time."); - - task.trigger.nextExecutionTime = time; - task.state = TimerTask.SCHEDULED; - } - } - - queue.add(task); - if (queue.getMin() == task) - queue.notify(); - } - } - - /** - * Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing - * task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more - * tasks may be scheduled on it. - * - *

- * Note that calling this method from within the run method of a timer task that was invoked by this timer - * absolutely guarantees that the ongoing task execution is the last task execution that will ever be performed by - * this timer. - * - *

- * This method may be called repeatedly; the second and subsequent calls have no effect. - */ - @Override - public List cancel() { - List tasks; - synchronized (queue) { - thread.newTasksMayBeScheduled = false; - if (cancelStack == null) - cancelStack = new Exception(); - tasks = getTasks(); - queue.clear(); - queue.notify(); // In case queue was already empty. - } - - if (ownsExecutor) - getExecutorService().shutdown(); - - return tasks; - } - - public ExecutorService getExecutorService() { - return thread.getExecutorService(); - } - - /** - * Removes all canceled tasks from this timer's task queue. Calling this method has no effect on the behavior of - * the timer, but eliminates the references to the canceled tasks from the queue. If there are no external - * references to these tasks, they become eligible for garbage collection. - * - *

- * Most programs will have no need to call this method. It is designed for use by the rare application that cancels - * a large number of tasks. Calling this method trades time for space: the runtime of the method may be proportional - * to n + c log n, where n is the number of tasks in the queue and c is the number of canceled tasks. - * - *

- * Note that it is permissible to call this method from within a a task scheduled on this timer. - * - * @return the number of tasks removed from the queue. - * @since 1.5 - */ - @Override - public int purge() { - int result = 0; - - synchronized (queue) { - for (int i = queue.size(); i > 0; i--) { - if (queue.get(i).state == TimerTask.CANCELLED) { - queue.quickRemove(i); - result++; - } - } - - if (result != 0) - queue.heapify(); - } - - return result; - } - - @Override - public int size() { - return queue.size(); - } - - @Override - public List getTasks() { - List result = new ArrayList(); - synchronized (queue) { - for (int i = 0; i < queue.size(); i++) - result.add(queue.get(i + 1)); - } - return result; - } - - @Override - public long currentTimeMillis() { - return timeSource.currentTimeMillis(); - } - // - // @SuppressWarnings("unchecked") - // public static void main(String[] args) throws Exception { - // RealTimeTimer timer = new RealTimeTimer(); - // ExecutorService executorService = Executors.newCachedThreadPool(); - // timer.init(executorService); - // - // timer.schedule(new NamedTask("task 7", new OneTimeTrigger(25000))); - // timer.schedule(new NamedTask("task 1", new OneTimeTrigger(1000))); - // timer.schedule(new NamedTask("task 2", new OneTimeTrigger(2000))); - // timer.schedule(new NamedTask("task 4", new OneTimeTrigger(20000))); - // timer.schedule(new NamedTask("task 5", new OneTimeTrigger(21000))); - // timer.schedule(new NamedTask("task 3", new OneTimeTrigger(10000))); - // timer.schedule(new NamedTask("task 6", new OneTimeTrigger(22000))); - // timer.schedule(new NamedTask("rate", new FixedRateTrigger(5000, 1800))); - // timer.schedule(new NamedTask("delay", new FixedDelayTrigger(6000, - // 2100))); - // timer.schedule(new NamedTask("cron", new - // CronTimerTrigger("0/6 * * * * ?"))); - // - // Thread.sleep(15000); - // System.out.println("Serializing"); - // - // List tasks = timer.cancel(); - // timer = null; - // - // ByteArrayOutputStream baos = new ByteArrayOutputStream(); - // ObjectOutputStream oos = new ObjectOutputStream(baos); - // oos.writeObject(tasks); - // - // Thread.sleep(20000); - // - // ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - // ObjectInputStream ois = new ObjectInputStream(bais); - // tasks = (List) ois.readObject(); - // - // System.out.println("Simulating"); - // SimulationTimer sim = new SimulationTimer(); - // for (TimerTask task : tasks) - // sim.schedule(task); - // - // for (int i = 0; i < 10; i++) { - // long start = System.currentTimeMillis(); - // sim.fastForwardTo(start); - // System.out.println("Run " + i + " took " + (System.currentTimeMillis() - - // start) + " ms"); - // } - // - // System.out.println("Real time"); - // timer = new RealTimeTimer(); - // timer.init(executorService); - // timer.scheduleAll(sim); - // - // Thread.sleep(10000); - // - // timer.cancel(); - // executorService.shutdown(); - // } - // - // static class NamedTask extends TimerTask { - // private static final long serialVersionUID = 1L; - // - // String name; - // - // NamedTask(String name, TimerTrigger trigger) { - // super(trigger); - // this.name = name; - // } - // - // @Override - // public String toString() { - // return "NamedTask(" + name + ")"; - // } - // - // @Override - // protected void run(long runtime) { - // System.out.println(name + " ran at " + runtime); - // try { - // Thread.sleep(300); - // } - // catch (InterruptedException e) { - // // no op - // } - // } - // } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ScheduledNamedRunnable.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ScheduledNamedRunnable.java deleted file mode 100644 index 0f75b9c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ScheduledNamedRunnable.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.serotonin.timer; - -/** - * A class that wraps a Runnable and sets the thread name to the given name. - * - * @author Matthew Lohbihler - */ -public class ScheduledNamedRunnable implements ScheduledRunnable { - private final ScheduledRunnable runnable; - private final String name; - - public ScheduledNamedRunnable(ScheduledRunnable runnable, String name) { - this.runnable = runnable; - this.name = name; - } - - @Override - public void run(long fireTime) { - String originalName = Thread.currentThread().getName(); - - // Append the given name to the original name. - Thread.currentThread().setName(originalName + " --> " + name); - - try { - // Ok, go ahead and run the thingy. - runnable.run(fireTime); - } - finally { - // Return the name to its original. - Thread.currentThread().setName(originalName); - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ScheduledRunnable.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ScheduledRunnable.java deleted file mode 100644 index e16ef8c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/ScheduledRunnable.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.serotonin.timer; - -/** - * Same as {@link Runnable}, but has a fireTime (millis) parameter. - */ -public interface ScheduledRunnable { - void run(long fireTime); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SimulationTimeSource.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SimulationTimeSource.java deleted file mode 100644 index a2b1e69..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SimulationTimeSource.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.serotonin.timer; - -public class SimulationTimeSource implements TimeSource { - private long time; - - public long currentTimeMillis() { - return time; - } - - public void setTime(long time) { - this.time = time; - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SimulationTimer.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SimulationTimer.java deleted file mode 100644 index 542691c..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SimulationTimer.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.serotonin.timer; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * The simulation timer is a single threaded timer under the temporal control of the next and fastForward methods. Tasks - * are run in the same thread as the timer, so they will seem to complete instantly. Running them in an executor has the - * opposite effect of making them appear to take an awful long time to complete. - * - * @author Matthew Lohbihler - */ -public class SimulationTimer extends AbstractTimer { - private final List queue = new ArrayList(); - private boolean cancelled; - private long currentTime; - - @Override - public boolean isInitialized() { - return true; - } - - public void setStartTime(long startTime) { - currentTime = startTime; - } - - public void next() { - fastForwardTo(currentTime + 1); - } - - public void fastForwardTo(long time) { - while (!queue.isEmpty() && queue.get(0).trigger.nextExecutionTime <= time) { - TimerTask task = queue.get(0); - - currentTime = task.trigger.nextExecutionTime; - - if (task.state == TimerTask.CANCELLED) - queue.remove(0); - else { - long next = task.trigger.calculateNextExecutionTime(); - if (next <= 0) { // Non-repeating, remove - queue.remove(0); - task.state = TimerTask.EXECUTED; - } - else { - // Repeating task, reschedule - task.trigger.nextExecutionTime = next; - updateQueue(); - } - - task.run(); - } - } - - currentTime = time; - } - - @Override - public void execute(Runnable command) { - command.run(); - } - - @Override - public void execute(ScheduledRunnable command, long fireTime) { - command.run(fireTime); - } - - @Override - protected void scheduleImpl(TimerTask task) { - if (cancelled) - throw new IllegalStateException("Timer already cancelled."); - - if (task.state == TimerTask.CANCELLED || task.state == TimerTask.EXECUTED) - throw new IllegalStateException("Task already executed or cancelled"); - - if (task.state == TimerTask.VIRGIN) { - long time = task.trigger.getFirstExecutionTime(); - if (time < 0) - throw new IllegalArgumentException("Illegal execution time."); - - task.trigger.nextExecutionTime = time; - task.state = TimerTask.SCHEDULED; - } - - queue.add(task); - updateQueue(); - } - - private void updateQueue() { - Collections.sort(queue, new Comparator() { - @Override - public int compare(TimerTask t1, TimerTask t2) { - long diff = t1.trigger.nextExecutionTime - t2.trigger.nextExecutionTime; - if (diff < 0) - return -1; - if (diff == 0) - return 0; - return 1; - } - }); - } - - @Override - public List cancel() { - cancelled = true; - List tasks = getTasks(); - queue.clear(); - return tasks; - } - - @Override - public int purge() { - int result = 0; - - for (int i = queue.size(); i > 0; i--) { - if (queue.get(i).state == TimerTask.CANCELLED) { - queue.remove(i); - result++; - } - } - - return result; - } - - @Override - public int size() { - return queue.size(); - } - - @Override - public List getTasks() { - return new ArrayList(queue); - } - - @Override - public long currentTimeMillis() { - return currentTime; - } - // - // public static void main(String[] args) throws Exception { - // long startTime = System.currentTimeMillis() - 32000; - // SimulationTimer simTimer = new SimulationTimer(); - // simTimer.setStartTime(startTime); - // - // simTimer.schedule(new NamedTask("task 7", new OneTimeTrigger(25000))); - // simTimer.schedule(new NamedTask("task 1", new OneTimeTrigger(1000))); - // simTimer.schedule(new NamedTask("task 2", new OneTimeTrigger(2000))); - // simTimer.schedule(new NamedTask("task 4", new OneTimeTrigger(20000))); - // simTimer.schedule(new NamedTask("task 5", new OneTimeTrigger(21000))); - // simTimer.schedule(new NamedTask("task 3", new OneTimeTrigger(10000))); - // simTimer.schedule(new NamedTask("task 6", new OneTimeTrigger(22000))); - // simTimer.schedule(new NamedTask("rate", new FixedRateTrigger(5000, - // 1800))); - // simTimer.schedule(new NamedTask("delay", new FixedDelayTrigger(6000, - // 2100))); - // simTimer.schedule(new NamedTask("cron", new - // CronTimerTrigger("0/6 * * * * ?"))); - // - // simTimer.fastForwardTo(System.currentTimeMillis()); - // - // System.out.println("Rescheduling"); - // - // RealTimeTimer rtTimer = new RealTimeTimer(); - // ExecutorService executorService = Executors.newCachedThreadPool(); - // rtTimer.init(executorService); - // rtTimer.scheduleAll(simTimer); - // - // Thread.sleep(20000); - // - // rtTimer.cancel(); - // executorService.shutdown(); - // } - // - // static class NamedTask extends TimerTask { - // String name; - // - // NamedTask(String name, TimerTrigger trigger) { - // super(trigger); - // this.name = name; - // } - // - // @Override - // public String toString() { - // return "NamedTask(" + name + ")"; - // } - // - // @Override - // protected void run(long runtime) { - // System.out.println(name + " ran at " + runtime); - // } - // } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SystemTimeSource.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SystemTimeSource.java deleted file mode 100644 index 3f377c1..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/SystemTimeSource.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.serotonin.timer; - -/** - * An implementation of TimeSource that returns the host time via System. - * - * @author Matthew Lohbihler - */ -public class SystemTimeSource implements TimeSource { - public long currentTimeMillis() { - return System.currentTimeMillis(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TaskQueue.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TaskQueue.java deleted file mode 100644 index 92cf612..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TaskQueue.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.serotonin.timer; - -import java.util.Arrays; - -class TaskQueue { - /** - * Priority queue represented as a balanced binary heap: the two children of queue[n] are queue[2*n] and - * queue[2*n+1]. The priority queue is ordered on the nextExecutionTime field: The TimerTask with the lowest - * nextExecutionTime is in queue[1] (assuming the queue is nonempty). For each node n in the heap, and each - * descendant of n, d, n.nextExecutionTime <= d.nextExecutionTime. - */ - private TimerTask[] queue = new TimerTask[128]; - - /** - * The number of tasks in the priority queue. (The tasks are stored in queue[1] up to queue[size]). - */ - private int size = 0; - - /** - * Returns the number of tasks currently on the queue. - */ - int size() { - return size; - } - - /** - * Adds a new task to the priority queue. - */ - void add(TimerTask task) { - // Grow backing store if necessary - if (size + 1 == queue.length) - queue = Arrays.copyOf(queue, 2 * queue.length); - - queue[++size] = task; - fixUp(size); - } - - /** - * Return the "head task" of the priority queue. (The head task is an task with the lowest nextExecutionTime.) - */ - TimerTask getMin() { - return queue[1]; - } - - /** - * Return the ith task in the priority queue, where i ranges from 1 (the head task, which is returned by getMin) to - * the number of tasks on the queue, inclusive. - */ - TimerTask get(int i) { - return queue[i]; - } - - /** - * Remove the head task from the priority queue. - */ - void removeMin() { - queue[1] = queue[size]; - queue[size--] = null; // Drop extra reference to prevent memory leak - fixDown(1); - } - - /** - * Removes the ith element from queue without regard for maintaining the heap invariant. Recall that queue is - * one-based, so 1 <= i <= size. - */ - void quickRemove(int i) { - assert i <= size; - - queue[i] = queue[size]; - queue[size--] = null; // Drop extra ref to prevent memory leak - } - - /** - * Sets the nextExecutionTime associated with the head task to the specified value, and adjusts priority queue - * accordingly. - */ - void rescheduleMin(long newTime) { - queue[1].trigger.nextExecutionTime = newTime; - fixDown(1); - } - - /** - * Returns true if the priority queue contains no elements. - */ - boolean isEmpty() { - return size == 0; - } - - /** - * Removes all elements from the priority queue. - */ - void clear() { - // Null out task references to prevent memory leak - for (int i = 1; i <= size; i++) - queue[i] = null; - - size = 0; - } - - /** - * Establishes the heap invariant (described above) assuming the heap satisfies the invariant except possibly for - * the leaf-node indexed by k (which may have a nextExecutionTime less than its parent's). - * - * This method functions by "promoting" queue[k] up the hierarchy (by swapping it with its parent) repeatedly until - * queue[k]'s nextExecutionTime is greater than or equal to that of its parent. - */ - private void fixUp(int k) { - while (k > 1) { - int j = k >> 1; - if (queue[j].trigger.nextExecutionTime <= queue[k].trigger.nextExecutionTime) - break; - TimerTask tmp = queue[j]; - queue[j] = queue[k]; - queue[k] = tmp; - k = j; - } - } - - /** - * Establishes the heap invariant (described above) in the subtree rooted at k, which is assumed to satisfy the heap - * invariant except possibly for node k itself (which may have a nextExecutionTime greater than its children's). - * - * This method functions by "demoting" queue[k] down the hierarchy (by swapping it with its smaller child) - * repeatedly until queue[k]'s nextExecutionTime is less than or equal to those of its children. - */ - private void fixDown(int k) { - int j; - while ((j = k << 1) <= size && j > 0) { - if (j < size && queue[j].trigger.nextExecutionTime > queue[j + 1].trigger.nextExecutionTime) - j++; // j indexes smallest kid - if (queue[k].trigger.nextExecutionTime <= queue[j].trigger.nextExecutionTime) - break; - TimerTask tmp = queue[j]; - queue[j] = queue[k]; - queue[k] = tmp; - k = j; - } - } - - /** - * Establishes the heap invariant (described above) in the entire tree, assuming nothing about the order of the - * elements prior to the call. - */ - void heapify() { - for (int i = size / 2; i >= 1; i--) - fixDown(i); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimeSource.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimeSource.java deleted file mode 100644 index 488fb87..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimeSource.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.serotonin.timer; - -/** - * An interface to abstract the source of current time away from System. This allows code to run in simulations where - * the time is controlled explicitly. - * - * @author Matthew Lohbihler - */ -public interface TimeSource { - long currentTimeMillis(); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimeoutTask.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimeoutTask.java deleted file mode 100644 index eb6d679..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimeoutTask.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.serotonin.timer; - -import java.util.Date; - -/** - * A simple way of creating a timeout. - * - * @author Matthew - */ -public class TimeoutTask extends TimerTask { - private final ScheduledRunnable client; - - public TimeoutTask(long delay, ScheduledRunnable client) { - this(new OneTimeTrigger(delay), client); - } - - public TimeoutTask(Date date, ScheduledRunnable client) { - this(new OneTimeTrigger(date), client); - } - - public TimeoutTask(TimerTrigger trigger, ScheduledRunnable client) { - super(trigger); - this.client = client; - } - - @Override - public void run(long runtime) { - client.run(runtime); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerTask.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerTask.java deleted file mode 100644 index 17648d8..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerTask.java +++ /dev/null @@ -1,167 +0,0 @@ -package com.serotonin.timer; - -import org.apache.commons.lang3.StringUtils; - -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -public abstract class TimerTask implements Runnable { - /** - * This object is used to control access to the TimerTask internals. - */ - Object lock = new Object(); - - /** - * The state of this task, chosen from the constants below. - */ - volatile int state = VIRGIN; - - /** - * This task has not yet been scheduled. - */ - static final int VIRGIN = 0; - - /** - * This task is scheduled for execution. If it is a non-repeating task, it has not yet been executed. - */ - static final int SCHEDULED = 1; - - /** - * This non-repeating task has already executed (or is currently executing) and has not been cancelled. - */ - static final int EXECUTED = 2; - - /** - * This task has been cancelled (with a call to TimerTask.cancel). - */ - static final int CANCELLED = 3; - - TimerTrigger trigger; - private final String name; - - /** - * Indicates that if the task is running at the moment it is cancelled, the cancellation should wait until the task - * is done. This is useful if the task uses resources that need to be shut down before the timer is shutdown. - */ - private boolean completeBeforeCancel; - - private final ReadWriteLock cancelLock = new ReentrantReadWriteLock(); - - public TimerTask(TimerTrigger trigger) { - this(trigger, null); - } - - public TimerTask(TimerTrigger trigger, String name) { - if (trigger == null) - throw new NullPointerException(); - this.trigger = trigger; - this.name = name; - } - - public boolean isCompleteBeforeCancel() { - return completeBeforeCancel; - } - - public void setCompleteBeforeCancel(boolean completeBeforeCancel) { - this.completeBeforeCancel = completeBeforeCancel; - } - - /** - * Cancels this timer task. If the task has been scheduled for one-time execution and has not yet run, or has not - * yet been scheduled, it will never run. If the task has been scheduled for repeated execution, it will never run - * again. (If the task is running when this call occurs, the task will run to completion, but will never run again.) - * - *

- * Note that calling this method from within the run method of a repeating timer task absolutely guarantees - * that the timer task will not run again. - * - *

- * This method may be called repeatedly; the second and subsequent calls have no effect. - * - * @return true if this task is scheduled for one-time execution and has not yet run, or this task is scheduled for - * repeated execution. Returns false if the task was scheduled for one-time execution and has already run, - * or if the task was never scheduled, or if the task was already cancelled. (Loosely speaking, this method - * returns true if it prevents one or more scheduled executions from taking place.) - */ - public boolean cancel() { - synchronized (lock) { - boolean result = (state == SCHEDULED); - - if (completeBeforeCancel) { - try { - cancelLock.writeLock().lock(); - state = CANCELLED; - } - finally { - cancelLock.writeLock().unlock(); - } - } - else - state = CANCELLED; - - return result; - } - } - - abstract public void run(long runtime); - - @Override - final public void run() { - // TODO if the task is not called quickly enough, the nextExecutionTime - // may have already been changed. It would - // be better to have the value assigned at the moment the task is - // submitted to the thread pool, but the - // interface doesn't allow it. For now, this will have to do. - long t; - synchronized (lock) { - t = trigger.mostRecentExecutionTime(); - } - - String originalName = null; - try { - if (!StringUtils.isBlank(name)) { - // This uses roughly the same code as in NamedRunnable to rename - // the thread for the duration of the task execution. - originalName = Thread.currentThread().getName(); - - // Append the given name to the original name. - Thread.currentThread().setName(originalName + " --> " + name); - } - - if (completeBeforeCancel) { - try { - cancelLock.readLock().lock(); - if (state != CANCELLED) - run(t); - } - finally { - cancelLock.readLock().unlock(); - } - } - else - // Ok, go ahead and run the thingy. - run(t); - } - finally { - if (originalName != null) - // Return the name to its original. - Thread.currentThread().setName(originalName); - } - } - - public boolean isCancelled() { - return state == CANCELLED; - } - - public long getNextExecutionTime() { - return trigger.nextExecutionTime; - } - - void setTimer(AbstractTimer timer) { - trigger.setTimer(timer); - } - - AbstractTimer getTimer() { - return trigger.getTimer(); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerThread.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerThread.java deleted file mode 100644 index 5c52599..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerThread.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.serotonin.timer; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.RejectedExecutionException; - -class TimerThread extends Thread { - private static final Log LOG = LogFactory.getLog(TimerThread.class); - - /** - * This flag is set to false by the reaper to inform us that there are no more live references to our Timer object. - * Once this flag is true and there are no more tasks in our queue, there is no work left for us to do, so we - * terminate gracefully. Note that this field is protected by queue's monitor! - */ - boolean newTasksMayBeScheduled = true; - - /** - * Our Timer's queue. We store this reference in preference to a reference to the Timer so the reference graph - * remains acyclic. Otherwise, the Timer would never be garbage-collected and this thread would never go away. - */ - private final TaskQueue queue; - - private final ExecutorService executorService; - private final TimeSource timeSource; - - TimerThread(TaskQueue queue, ExecutorService executorService, TimeSource timeSource) { - this.queue = queue; - this.executorService = executorService; - this.timeSource = timeSource; - } - - @Override - public void run() { - try { - mainLoop(); - } - catch (Throwable t) { - LOG.fatal("TimerThread failed", t); - } - finally { - // Someone killed this Thread, behave as if Timer was cancelled - synchronized (queue) { - newTasksMayBeScheduled = false; - queue.clear(); // Eliminate obsolete references - } - } - } - - void execute(Runnable command) { - executorService.execute(command); - } - - void execute(final ScheduledRunnable command, final long fireTime) { - executorService.execute(new Runnable() { - @Override - public void run() { - command.run(fireTime); - } - }); - } - - ExecutorService getExecutorService() { - return executorService; - } - - /** - * The main timer loop. (See class comment.) - */ - private void mainLoop() { - while (true) { - try { - TimerTask task; - boolean taskFired; - synchronized (queue) { - // Wait for queue to become non-empty - while (queue.isEmpty() && newTasksMayBeScheduled) - queue.wait(); - if (queue.isEmpty()) - break; // Queue is empty and will forever remain; die - - // Queue nonempty; look at first evt and do the right thing - long executionTime; - task = queue.getMin(); - synchronized (task.lock) { - if (task.state == TimerTask.CANCELLED) { - queue.removeMin(); - continue; // No action required, poll queue again - } - executionTime = task.trigger.nextExecutionTime; - if (taskFired = (executionTime <= timeSource.currentTimeMillis())) { - long next = task.trigger.calculateNextExecutionTime(); - if (next <= 0) { // Non-repeating, remove - queue.removeMin(); - task.state = TimerTask.EXECUTED; - } - else - // Repeating task, reschedule - queue.rescheduleMin(next); - } - } - if (!taskFired) {// Task hasn't yet fired; wait - long wait = executionTime - timeSource.currentTimeMillis(); - if (wait > 0) - queue.wait(wait); - } - } - if (taskFired) { - // Task fired; run it, holding no locks - try { - executorService.execute(task); - } - catch (RejectedExecutionException e) { - LOG.warn("Rejected task: " + task, e); - } - } - } - catch (InterruptedException e) { - // no op - } - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerTrigger.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerTrigger.java deleted file mode 100644 index be2e734..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/TimerTrigger.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.serotonin.timer; - -import java.util.Date; - -abstract public class TimerTrigger { - // The maximum time that a task can run late. If the next run time is calculated to be more than this in the past - // it will be adjusted to be more current. - private static final int MAX_TARDINESS = 1000 * 60 * 10; // 10 minutes. - - protected AbstractTimer timer; - - void setTimer(AbstractTimer timer) { - this.timer = timer; - } - - AbstractTimer getTimer() { - return timer; - } - - /** - * Next execution time for this task in the format returned by System.currentTimeMillis, assuming this task is - * scheduled for execution. For repeating tasks, this field is updated prior to each task execution. - */ - long nextExecutionTime; - - /** - * Returns the scheduled execution time of the most recent actual execution of this task. (If this - * method is invoked while task execution is in progress, the return value is the scheduled execution time of the - * ongoing task execution.) - * - *

- * This method is typically invoked from within a task's run method, to determine whether the current execution of - * the task is sufficiently timely to warrant performing the scheduled activity: - * - *

-     * public void run() {
-     *     if (System.currentTimeMillis() - scheduledExecutionTime() >= MAX_TARDINESS)
-     *         return; // Too late; skip this execution.
-     *     // Perform the task
-     * }
-     * 
- * - * This method is typically not used in conjunction with fixed-delay execution repeating tasks, as - * their scheduled execution times are allowed to drift over time, and so are not terribly significant. - * - * @return the time at which the most recent execution of this task was scheduled to occur, in the format returned - * by Date.getTime(). The return value is undefined if the task has yet to commence its first execution. - * @see Date#getTime() - */ - abstract public long mostRecentExecutionTime(); - - abstract protected long getFirstExecutionTime(); - - public long getNextExecutionTime() { - return nextExecutionTime; - } - - /** - * Return the time of the next execution, or -1 if there isn't one. - * - * @return - */ - protected final long calculateNextExecutionTime() { - long next = calculateNextExecutionTimeImpl(); - - // If the system time changes on the O/S (due to NTP, manual change, or some other reason) this calculation - // can cause a good amount of disturbance (either a schedule that doesn't run for a while, or one that runs - // repeatedly in order to catch up). We check here to assure that the next execution time is not entirely - // ridiculous, and adjust it if so. - long now = timer.currentTimeMillis(); - if (now - next >= MAX_TARDINESS) - next = calculateNextExecutionTimeImpl(now); - - return next; - } - - abstract protected long calculateNextExecutionTimeImpl(); - - abstract protected long calculateNextExecutionTimeImpl(long after); -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/AsyncJobSink.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/AsyncJobSink.java deleted file mode 100644 index b506920..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/AsyncJobSink.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.serotonin.timer.sync; - -import java.util.concurrent.ConcurrentLinkedQueue; - -public class AsyncJobSink implements Runnable { - private final ConcurrentLinkedQueue inbox = new ConcurrentLinkedQueue(); - - private Thread thread; - private volatile boolean running; - - public synchronized boolean initialize() { - if (thread == null) { - running = true; - thread = new Thread(this); - thread.start(); - return true; - } - return false; - } - - public synchronized void terminate() { - if (thread != null) { - running = false; - try { - thread.join(); - } - catch (InterruptedException e) { - // no op - } - thread = null; - } - } - - public boolean add(Event event) { - if (running) - return inbox.offer(event); - return false; - } - - @Override - public void run() { - int processed = 0; - - while (true) { - Event event = inbox.poll(); - if (event != null) { - System.out.println("Processed " + event.getId()); - processed++; - } - else if (!running) - break; - else { - System.out.println("null"); - try { - Thread.sleep(50); - } - catch (InterruptedException e) { - // no op - } - } - } - - System.out.println("Exiting having processed " + processed); - } - - static class Event { - static int nextId = 0; - - private final String id; - - public Event() { - id = Integer.toString(nextId++); - } - - public String getId() { - return id; - } - } - - public static void main(String[] args) throws Exception { - AsyncJobSink sink = new AsyncJobSink(); - sink.initialize(); - - long start = System.currentTimeMillis(); - - int failed = 0; - for (int i = 0; i < 100; i++) { - Event event = new Event(); - if (!sink.add(event)) - failed++; - } - - Thread.sleep(10000); - sink.terminate(); - - System.out.println("Failed to add " + failed); - System.out.println("Runtime: " + (System.currentTimeMillis() - start)); - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java deleted file mode 100644 index b087ad6..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/SingleExecutorSingleWaiter.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (C) 2006-2009 Serotonin Software Technologies Inc. - @author Matthew Lohbihler - */ -package com.serotonin.timer.sync; - -import com.serotonin.timer.AbstractTimer; - -/** - * This class is useful when an exclusive, long-running task gets called more often than is practical. For example, a - * large object needs to be persisted, but it changes fairly often. This class will execute the submitted runnable - * if there is currently nothing running. If another task is already running, the new task will wait. If there is - * already a task waiting, the new task will replace the waiting task. So, tasks that are started are always allowed to - * complete, but tasks that are no necessary to run are discarded. - * - * @author Matthew Lohbihler - */ -public class SingleExecutorSingleWaiter { - final AbstractTimer timer; - final Object lock = new Object(); - - Runnable executing; - Runnable waiting; - - public SingleExecutorSingleWaiter(AbstractTimer timer) { - this.timer = timer; - } - - public void execute(Runnable task) { - synchronized (lock) { - if (executing != null) { - waiting = task; - return; - } - - executing = task; - executeImpl(); - } - } - - void executeImpl() { - timer.execute(new TaskWrapper(executing)); - } - - class TaskWrapper implements Runnable { - private final Runnable command; - - public TaskWrapper(Runnable command) { - this.command = command; - } - - @Override - public void run() { - try { - command.run(); - } - finally { - synchronized (lock) { - if (waiting != null) { - executing = waiting; - waiting = null; - executeImpl(); - } - else - executing = null; - } - } - } - } - // - // public static void main(String[] args) throws Exception { - // ExecutorService executorService = Executors.newCachedThreadPool(); - // RealTimeTimer timer = new RealTimeTimer(); - // timer.init(executorService); - // - // SingleExecutorSingleWaiter e = new SingleExecutorSingleWaiter(timer); - // TestRunnable r1 = new TestRunnable(1); - // TestRunnable r2 = new TestRunnable(2); - // TestRunnable r3 = new TestRunnable(3); - // TestRunnable r4 = new TestRunnable(4); - // TestRunnable r5 = new TestRunnable(5); - // TestRunnable r6 = new TestRunnable(6); - // TestRunnable r7 = new TestRunnable(7); - // TestRunnable r8 = new TestRunnable(8); - // TestRunnable r9 = new TestRunnable(9); - // - // e.execute(r1); // 1 - // e.execute(r2); // 2 - // e.execute(r3); // 3 - // e.execute(r4); // 3 - // - // Thread.sleep(1000); - // e.execute(r5); // 3 - // - // Thread.sleep(1500); - // e.execute(r6); // 2 - // - // Thread.sleep(4000); - // e.execute(r7); // 1 - // e.execute(r8); // 2 - // e.execute(r9); // 3 - // - // // Running 1 - // // Finished 1 - // // Running 5 - // // Finished 5 - // // Running 6 - // // Finished 6 - // // Running 7 - // // Finished 7 - // // Running 9 - // // Finished 9 - // - // Thread.sleep(4000); - // timer.cancel(); - // executorService.shutdown(); - // } - // - // static class TestRunnable implements Runnable { - // int id; - // - // public TestRunnable(int id) { - // this.id = id; - // } - // - // @Override - // public void run() { - // System.out.println("Running " + id); - // try { - // Thread.sleep(2000); - // } - // catch (InterruptedException e) { - // } - // System.out.println("Finished " + id); - // } - // } -} diff --git a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/Synchronizer.java b/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/Synchronizer.java deleted file mode 100644 index 5a9e7c4..0000000 --- a/smtweb-framework/sw-framework-core/src/main/java/com/serotonin/timer/sync/Synchronizer.java +++ /dev/null @@ -1,235 +0,0 @@ -package com.serotonin.timer.sync; - -import com.serotonin.timer.AbstractTimer; -import com.serotonin.timer.RealTimeTimer; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * This class acts as a synchronizing monitor where an arbitrary number of tasks can be added with string identifiers. - * Then, the tasks can be executed using the provided executor and the calling thread will be blocked until they are all - * completed, after which then tasks can be asked for by name to get their results. - * - * This allows parts of processing that would benefit from being asynchronous - such as database concurrency - to easily - * be managed by a controlling thread. - * - * @author Matthew Lohbihler - * - * @param - * a task object that implements Runnable - */ -public class Synchronizer { - private final List tasks = new ArrayList(); - - // A lock that is used when there are more tasks to run than allowed concurrently. This monitor notifies the - // completion of any task. - final Object multiLock = new Object(); - - private final int maxConcurrent; - - public Synchronizer() { - this(0); - } - - public Synchronizer(int maxConcurrent) { - this.maxConcurrent = maxConcurrent; - } - - public void addTask(T task) { - addTask(null, task); - } - - public void addTask(String name, T task) { - tasks.add(new TaskWrapper(name, task)); - } - - public void executeAndWait(AbstractTimer timer) { - List running; - - if (maxConcurrent <= 0 || tasks.size() <= maxConcurrent) { - // Start all of the tasks. - for (TaskWrapper tw : tasks) - timer.execute(tw); - running = tasks; - } - else { - List remaining = new ArrayList(tasks); - running = new ArrayList(); - - // We have more tasks to run than we can run concurrently. We need a polling method to monitor the tasks. - while (!remaining.isEmpty()) { - // Start tasks - while (running.size() < maxConcurrent && !remaining.isEmpty()) { - TaskWrapper tw = remaining.remove(remaining.size() - 1); - timer.execute(tw); - running.add(tw); - } - - // Wait for completed tasks. - while (true) { - synchronized (multiLock) { - boolean completions = false; - for (int i = running.size() - 1; i >= 0; i--) { - TaskWrapper tw = running.get(i); - synchronized (tw) { - if (tw.isComplete()) { - running.remove(i); - completions = true; - } - } - } - - if (completions) - // Completed task(s) were found, so break. - break; - - // No tasks completed, so wait for a notification. - try { - multiLock.wait(); - } - catch (InterruptedException e) { - // no op - } - } - } - } - } - - // Wait for the tasks to complete. - for (TaskWrapper tw : running) { - synchronized (tw) { - try { - if (!tw.isComplete()) { - // System.out.println("Waiting on " + tw.task); - tw.wait(); - } - } - catch (InterruptedException e) { - // no op - } - } - } - } - - public T getTask(String name) { - for (TaskWrapper tw : tasks) { - if (StringUtils.equals(name, tw.name)) - return tw.task; - } - return null; - } - - public int getSize() { - return tasks.size(); - } - - public List getTasks() { - List result = new ArrayList(); - for (TaskWrapper tw : tasks) - result.add(tw.task); - return result; - } - - class TaskWrapper implements Runnable { - final String name; - final T task; - private volatile boolean complete; - - public TaskWrapper(String name, T task) { - this.name = name; - this.task = task; - } - - public String getName() { - return name; - } - - @Override - public void run() { - try { - task.run(); - } - finally { - synchronized (this) { - complete = true; - notify(); - } - synchronized (multiLock) { - multiLock.notify(); - } - } - } - - public boolean isComplete() { - return complete; - } - } - - public static void main(String[] args) { - Synchronizer synchronizer = new Synchronizer(20); - synchronizer.addTask("A", new TestTask("a", 4000)); - synchronizer.addTask("B", new TestTask("b", 5000)); - synchronizer.addTask("C", new TestTask("c", 10000)); - synchronizer.addTask("D", new TestTask("d", 3000)); - synchronizer.addTask("E", new TestTask("e", 1000)); - synchronizer.addTask("F", new TestTask("f", 70)); - synchronizer.addTask("G", new TestTask("g", 1)); - synchronizer.addTask("H", new TestTask("h", 10)); - synchronizer.addTask("I", new TestTask("i", 100)); - synchronizer.addTask("J", new TestTask("j", 800)); - synchronizer.addTask("K", new TestTask("k", 40)); - synchronizer.addTask("L", new TestTask("l", 250)); - synchronizer.addTask("M", new TestTask("m", 300)); - synchronizer.addTask("N", new TestTask("n", 700)); - synchronizer.addTask("O", new TestTask("o", 700)); - synchronizer.addTask("P", new TestTask("p", 700)); - synchronizer.addTask("Q", new TestTask("q", 4)); - synchronizer.addTask("R", new TestTask("r", 5)); - synchronizer.addTask("S", new TestTask("s", 6)); - synchronizer.addTask("T", new TestTask("t", 7)); - - RealTimeTimer timer = new RealTimeTimer(); - ExecutorService executor = Executors.newCachedThreadPool(); - timer.init(executor); - - System.out.println("*** Begin"); - synchronizer.executeAndWait(timer); - System.out.println("*** Done"); - - timer.cancel(); - executor.shutdown(); - } - - static long start = System.currentTimeMillis(); - - static class TestTask implements Runnable { - private final String id; - private final long sleepTime; - - public TestTask(String id, long sleepTime) { - this.id = id; - this.sleepTime = sleepTime; - } - - @Override - public void run() { - System.out.println((System.currentTimeMillis() - start) + ": started " + id); - try { - Thread.sleep(sleepTime); - } - catch (InterruptedException e) { - // no op - } - System.out.println((System.currentTimeMillis() - start) + ": ended " + id); - } - - @Override - public String toString() { - return id; - } - } -} diff --git a/smtweb-framework/sw-framework-core/src/main/resources/META-INF/spring.factories b/smtweb-framework/sw-framework-core/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 341ca1d..0000000 --- a/smtweb-framework/sw-framework-core/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - cc.smtweb.framework.core.CoreAutoConfiguration diff --git a/smtweb-framework/sw-framework-core/src/main/resources/config/application-dev.yaml b/smtweb-framework/sw-framework-core/src/main/resources/config/application-dev.yaml deleted file mode 100644 index bf8c0cf..0000000 --- a/smtweb-framework/sw-framework-core/src/main/resources/config/application-dev.yaml +++ /dev/null @@ -1,61 +0,0 @@ -smtweb: - machine-id: 1 - file: - local-path: /data/files/smart/ - host: http://127.0.0.1 - url: ${smtweb.file.host}:${server.port}${server.servlet.context-path}/${smtweb.file.local-path} - db: - type: mysql - default: - rule: - prefix: _smt_ - replace: smt_ -server: - port: 8888 - servlet: - context-path: / -logging: - level: - root: INFO - cc.smtweb: DEBUG -spring: - # 设置服务名 - application: - name: smtweb_core - main: - allow-bean-definition-overriding: true - mvc: - static-path-pattern: /static/** - redis: - name: ${smtweb.machine-id} - host: 127.0.0.1 - port: 6379 - password: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/smt_asp?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false - username: root - password: root - servlet: - multipart: - max-file-size: 104857600000 - max-request-size: 10485760000000 -# profiles: -# include: role - cache: - type: caffeine - cache-names: - - core - caffeine: - spec: maximumSize=1024,expireAfterWrite=2h -park: - secret: - key: null -# key: cmVmb3JtZXJyZWZvcm1lcg== -swagger: - name: smtweb-core - version: 2.0 - enabled: true - - - diff --git a/smtweb-framework/sw-framework-core/src/main/resources/config/application-prod.yaml b/smtweb-framework/sw-framework-core/src/main/resources/config/application-prod.yaml deleted file mode 100644 index eaed90b..0000000 --- a/smtweb-framework/sw-framework-core/src/main/resources/config/application-prod.yaml +++ /dev/null @@ -1,52 +0,0 @@ -sme: - machine-id: 1 - file-local-path: /data/files/smart/ - file-host: http://member.sumi168.cn - file-url: ${sme.file-host}:${server.port}${server.servlet.context-path}/${sme.file-local-path} - -server: - port: 10001 - servlet: - context-path: /user - -feign: - hystrix: - enabled: false -logging: - level: - smtweb: DEBUG - -spring: - # 设置服务名 - application: - name: smtweb-user - main: - allow-bean-definition-overriding: true - mvc: - static-path-pattern: /static/** - redis: - host: 127.0.0.1 - port: 6379 - datasource: - user: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/smt_user?useUnicode=true&characterEncoding=utf-8&useTimezone=true&serverTimezone=CTT&allowMultiQueries=true - username: smt - password: smt_123456 - - servlet: - multipart: - max-file-size: 104857600000 - max-request-size: 10485760000000 - -swagger: - name: smart - version: 1.0.1 - enabled: false - -weixin: - url: http://devpk.smart.smefdd.com - appId: wx8d11474c01b92378 - appSecret: e1fa7bcdf27b46e7d69edad68ea8724b - - diff --git a/smtweb-framework/sw-framework-core/src/main/resources/config/application.yaml b/smtweb-framework/sw-framework-core/src/main/resources/config/application.yaml deleted file mode 100644 index caf4dfc..0000000 --- a/smtweb-framework/sw-framework-core/src/main/resources/config/application.yaml +++ /dev/null @@ -1,3 +0,0 @@ -spring: - profiles: - active: dev \ No newline at end of file diff --git a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/DaoTransTest.java b/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/DaoTransTest.java deleted file mode 100644 index 0d227cf..0000000 --- a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/DaoTransTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.framework.test; - - -import cc.smtweb.framework.core.common.SwMap; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -@DisplayName("TransSql测试") -public class DaoTransTest { - - @Test - public void testSelect() { - - } - - @Test - public void testMapClass() { - boolean ret = call(SwMap.class); - - System.out.println(ret); - } - - private boolean call(Class clazz) { - if (java.util.Map.class.isAssignableFrom(clazz)) { - return true; - } - - return false; - } -} diff --git a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/JsonTest.java b/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/JsonTest.java deleted file mode 100644 index b2de949..0000000 --- a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/JsonTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package cc.smtweb.framework.test; - -import cc.smtweb.framework.core.util.JsonUtil; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import lombok.Data; -import org.junit.jupiter.api.Test; -import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; - -import java.util.ArrayList; -import java.util.List; - -public class JsonTest { - @Test - public void testList() throws JsonProcessingException { - { - List list = JsonUtil.OBJECT_MAPPER.readValue("[{ \"value\": 1 }, { \"value\": 2 }, { \"value\": 3 }]", ArrayList.class); - - System.out.println(list.get(0).getClass()); - } - - { - List list = JsonUtil.parseList("[{ \"value\": 1 }, { \"value\": 2 }, { \"value\": 3 }]", JsonItem.class); - - System.out.println(list.get(0).getClass()); - } - } -} - -@Data -class JsonItem { - private Integer value; -} diff --git a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/NamedJdbcTest.java b/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/NamedJdbcTest.java deleted file mode 100644 index fc2bfa6..0000000 --- a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/NamedJdbcTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.framework.test; - -import cc.smtweb.framework.core.CoreApplication; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 2022/4/24 14:58 - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = CoreApplication.class) -public class NamedJdbcTest { - @Test - public void testSelect() { - List list = DbEngine.getInstance().query("select * from asp_model_project", DefaultEntity.class); - System.out.println(list.size()); - Map params = new HashMap<>(); - params.put("id", 1); - list = DbEngine.getInstance().queryN("select * from asp_model_project where prj_id=:id", params, DefaultEntity.class); - System.out.println(list.size()); - } -} diff --git a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/SqlBuilderTest.java b/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/SqlBuilderTest.java deleted file mode 100644 index 8ad25ee..0000000 --- a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/SqlBuilderTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package cc.smtweb.framework.test; - - -import cc.smtweb.framework.core.db.sqlbuilder.SelectSqlBuilder; -import cc.smtweb.framework.core.db.sqlbuilder.SqlBuilder; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -@DisplayName("SqlBuilder测试") -public class SqlBuilderTest { - - @Test - public void select() { - SelectSqlBuilder sb = SqlBuilder.createSelect("sw_im_log.im_user_msg_log"); - sb.add("uml_Id,uml_content"); - sb.addWhereOrBegin(); - sb.addWhere("uml_small_uid", 1); - sb.addWhere("uml_big_uid", 2); - sb.addWhereOrEnd(); - - sb.exec((sql, params) -> { - Assertions.assertEquals("select uml_Id,uml_content from sw_im_log.im_user_msg_log where (uml_small_uid=? or uml_big_uid=?)", sql); - return true; - }); - - sb = SqlBuilder.createSelect("sw_im_log.im_user_msg_log"); - sb.add("uml_Id,uml_content"); - sb.addWhere("uml_time", 1); - sb.addWhereOrBegin(); - sb.addWhere("uml_small_uid", 2); - sb.addWhere("uml_big_uid", 3); - sb.addWhereOrEnd(); - sb.addWhere("uml_id", 4); - - sb.exec((sql, params) -> { - Assertions.assertEquals("select uml_Id,uml_content from sw_im_log.im_user_msg_log where uml_time=? and (uml_small_uid=? or uml_big_uid=?) and uml_id=?", sql); - return true; - }); - - sb = SqlBuilder.createSelect("sw_im_log.im_user_msg_log"); - sb.add("uml_Id,uml_content"); - sb.addWhere("uml_time", 1); - sb.addWhereOrBegin(); - sb.addWhere("uml_small_uid", 2); - sb.addWhere("uml_big_uid", 3); - sb.addWhereOrEnd(); - - sb.exec((sql, params) -> { - Assertions.assertEquals("select uml_Id,uml_content from sw_im_log.im_user_msg_log where uml_time=? and (uml_small_uid=? or uml_big_uid=?)", sql); - return true; - }); - - sb = SqlBuilder.createSelect("sw_im_log.im_user_msg_log"); - sb.add("uml_Id,uml_content"); - sb.addWhereOrBegin(); - sb.addWhere("uml_small_uid", 2); - sb.addWhere("uml_big_uid", 3); - sb.addWhereOrEnd(); - sb.addWhere("uml_id", 4); - - sb.exec((sql, params) -> { - Assertions.assertEquals("select uml_Id,uml_content from sw_im_log.im_user_msg_log where (uml_small_uid=? or uml_big_uid=?) and uml_id=?", sql); - return true; - }); - - } - -} diff --git a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/TestMain.java b/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/TestMain.java deleted file mode 100644 index 748ed58..0000000 --- a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/TestMain.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.smtweb.framework.test; - -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.util.JsonUtil; - -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 2021/12/25 22:21 - */ -public class TestMain { - - public static void main(String[] args) { - List list = DbEngine.getInstance().query("select * from asp_model_project", DefaultEntity.class); - System.out.println(list.size()); - /*ModelTable table = new ModelTable(); - table.setId(1); - table.setContent(s);*/ - } -} diff --git a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/ToolEnum2Js.java b/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/ToolEnum2Js.java deleted file mode 100644 index 0b3b1ed..0000000 --- a/smtweb-framework/sw-framework-core/src/test/java/cc/smtweb/framework/test/ToolEnum2Js.java +++ /dev/null @@ -1,118 +0,0 @@ -package cc.smtweb.framework.test; - - - -import cc.smtweb.framework.core.common.AbstractEnum; -import cc.smtweb.framework.core.common.IntEnum; -import cc.smtweb.framework.core.common.StrEnum; -import cc.smtweb.framework.core.common.SwEnum; -import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; - -import java.lang.reflect.Field; -import java.lang.reflect.Type; - -/** - * Created by Akmm at 2017/5/12 17:14 - * 枚举类转js定义 - */ -public class ToolEnum2Js { - public static void main(String[] args) throws Exception { - buildJs(SwEnum.class);//传枚举定义类 - } - - private static void buildJs(Class cls) throws Exception { - Class[] classes = cls.getDeclaredClasses();// 获得代表内部类的Class对象组成的数组 - StringBuilder sb = new StringBuilder(); - for (Class clazz : classes) {// 遍历Class对象数组 -// System.out.println("类的标准名称:" + clazz.getCanonicalName()); -// System.out.println("类的修饰符:" + Modifier.toString(clazz.getModifiers())); - Type superClass = clazz.getGenericSuperclass();// 获得直接父类 - -// System.out.print("类的直接继承类:"); - if (superClass.equals(IntEnum.class)) { - buildJsInt(clazz, sb); - }else if (superClass.equals(StrEnum.class)) { - buildJsStr(clazz, sb); - }else if (superClass.getTypeName().startsWith(AbstractEnum.class.getTypeName()+"<")){ - buildJsBean(clazz,sb); - } - - } - System.out.println(sb.substring(1)); - } - - private static void buildJsInt(Class clazz, StringBuilder sb) throws Exception { - IntEnum instance = (IntEnum) clazz.newInstance(); - Field[] fields = clazz.getDeclaredFields();// 获得该类对象的所有非继承域 - if (fields.length == 0) return; - StringBuilder sbc = new StringBuilder(128); - StringBuilder sbDefines = new StringBuilder(128); - for (Field field : fields) { - if (!field.getType().equals(AbstractEnum.IntEnumBean.class)) continue; - AbstractEnum.IntEnumBean value = (AbstractEnum.IntEnumBean) field.get(instance); - sbc.append(",\n").append(field.getName()).append(": ").append(value.value); - sbDefines.append(",\n").append("{ value: ").append(value.value).append(", label: \"").append(value.name).append("\" }"); - } - sb.append("\n").append("export const ").append(clazz.getSimpleName()).append(" = {\n").append(sbc.length()>2?sbc.substring(2):"").append(",\n...useEnumProps([\n").append(sbDefines.length()>2?sbDefines.substring(2):"").append("\n])").append("\n}"); - } - - private static void buildJsStr(Class clazz, StringBuilder sb) throws Exception { - StrEnum instance = (StrEnum) clazz.newInstance(); - Field[] fields = clazz.getDeclaredFields();// 获得该类对象的所有非继承域 - if (fields.length == 0) return; - StringBuilder sbc = new StringBuilder(128); - StringBuilder sbDefines = new StringBuilder(128); - for (Field field : fields) { - if (!field.getType().equals(AbstractEnum.StrEnumBean.class)) continue; - AbstractEnum.StrEnumBean value = (AbstractEnum.StrEnumBean) field.get(instance); - sbc.append(",\n").append(field.getName()).append(": \"").append(value.value).append("\""); - sbDefines.append(",\n").append("{ value: \"").append(value.value).append("\", label: \"").append(value.name).append("\" }"); - } - sb.append("\n").append("export const ").append(clazz.getSimpleName()).append(" = {\n").append(sbc.length()>2?sbc.substring(2):"").append(",\n...useEnumProps([\n").append(sbDefines.length()>2?sbDefines.substring(2):"").append("\n])").append("\n}"); - } - - private static void buildJsBean(Class clazz, StringBuilder sb)throws Exception{ - Object instance = clazz.newInstance(); - Field[] fields = clazz.getDeclaredFields();// 获得该类对象的所有非继承域 - Type type1 = ((ParameterizedTypeImpl) clazz.getGenericSuperclass()).getActualTypeArguments()[0]; - Type type2 = ((ParameterizedTypeImpl) clazz.getGenericSuperclass()).getActualTypeArguments()[1]; - if (fields.length == 0) return; - boolean isNumber = Integer.class.getTypeName().equals(type1.getTypeName()); - StringBuilder sbc = new StringBuilder(128); - StringBuilder sbDefines = new StringBuilder(128); - for (Field field : fields) { - if (!field.getType().equals(type2)) continue; - Object value = field.get(instance); - if (isNumber){ - AbstractEnum.IntEnumBean tempValue = (AbstractEnum.IntEnumBean) field.get(instance); - sbc.append(",\n").append(field.getName()).append(": ").append(tempValue.value); - sbDefines.append(",\n").append("{ value: ").append(tempValue.value).append(", label: \"").append(tempValue.name).append("\""); - }else { - AbstractEnum.StrEnumBean tempValue = (AbstractEnum.StrEnumBean) field.get(instance); - sbc.append(",\n").append(field.getName()).append(": \"").append(tempValue.value).append("\""); - sbDefines.append(",\n").append("{ value: \"").append(tempValue.value).append("\", label: \"").append(tempValue.name).append("\""); - } - // 处理bean - Field[] beanFields = value.getClass().getFields();// 获得该类对象的所有字段 - StringBuilder sbBean = new StringBuilder(); - sbBean.append(" bean: { "); - if(beanFields.length >0 ){ - for(Field beanField: beanFields){ - Object beanValue = beanField.get(value); - String name = beanField.getName(); - sbBean.append("name".equals(name)?"label":name).append(": ").append(formatValue(beanValue)).append(", "); - } - } - sbBean.append("}"); - sbDefines.append(",").append(sbBean.toString()).append(" }"); - } - sb.append("\n").append("export const ").append(clazz.getSimpleName()).append(" = {\n"). - append(sbc.length()>2?sbc.substring(2):"").append(",\n...useEnumProps([\n").append(sbDefines.length()>2?sbDefines.substring(2):"").append("\n])").append("\n}"); - } - private static String formatValue(Object obj){ - if(obj instanceof String){ - return "\""+obj.toString()+"\""; - } - return obj.toString(); - } -} diff --git a/smtweb-framework/sw-framework-core/target/classes/META-INF/spring.factories b/smtweb-framework/sw-framework-core/target/classes/META-INF/spring.factories deleted file mode 100644 index 341ca1d..0000000 --- a/smtweb-framework/sw-framework-core/target/classes/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - cc.smtweb.framework.core.CoreAutoConfiguration diff --git a/smtweb-framework/sw-framework-core/target/classes/config/application-dev.yaml b/smtweb-framework/sw-framework-core/target/classes/config/application-dev.yaml deleted file mode 100644 index bf8c0cf..0000000 --- a/smtweb-framework/sw-framework-core/target/classes/config/application-dev.yaml +++ /dev/null @@ -1,61 +0,0 @@ -smtweb: - machine-id: 1 - file: - local-path: /data/files/smart/ - host: http://127.0.0.1 - url: ${smtweb.file.host}:${server.port}${server.servlet.context-path}/${smtweb.file.local-path} - db: - type: mysql - default: - rule: - prefix: _smt_ - replace: smt_ -server: - port: 8888 - servlet: - context-path: / -logging: - level: - root: INFO - cc.smtweb: DEBUG -spring: - # 设置服务名 - application: - name: smtweb_core - main: - allow-bean-definition-overriding: true - mvc: - static-path-pattern: /static/** - redis: - name: ${smtweb.machine-id} - host: 127.0.0.1 - port: 6379 - password: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/smt_asp?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false - username: root - password: root - servlet: - multipart: - max-file-size: 104857600000 - max-request-size: 10485760000000 -# profiles: -# include: role - cache: - type: caffeine - cache-names: - - core - caffeine: - spec: maximumSize=1024,expireAfterWrite=2h -park: - secret: - key: null -# key: cmVmb3JtZXJyZWZvcm1lcg== -swagger: - name: smtweb-core - version: 2.0 - enabled: true - - - diff --git a/smtweb-framework/sw-framework-core/target/classes/config/application-prod.yaml b/smtweb-framework/sw-framework-core/target/classes/config/application-prod.yaml deleted file mode 100644 index eaed90b..0000000 --- a/smtweb-framework/sw-framework-core/target/classes/config/application-prod.yaml +++ /dev/null @@ -1,52 +0,0 @@ -sme: - machine-id: 1 - file-local-path: /data/files/smart/ - file-host: http://member.sumi168.cn - file-url: ${sme.file-host}:${server.port}${server.servlet.context-path}/${sme.file-local-path} - -server: - port: 10001 - servlet: - context-path: /user - -feign: - hystrix: - enabled: false -logging: - level: - smtweb: DEBUG - -spring: - # 设置服务名 - application: - name: smtweb-user - main: - allow-bean-definition-overriding: true - mvc: - static-path-pattern: /static/** - redis: - host: 127.0.0.1 - port: 6379 - datasource: - user: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/smt_user?useUnicode=true&characterEncoding=utf-8&useTimezone=true&serverTimezone=CTT&allowMultiQueries=true - username: smt - password: smt_123456 - - servlet: - multipart: - max-file-size: 104857600000 - max-request-size: 10485760000000 - -swagger: - name: smart - version: 1.0.1 - enabled: false - -weixin: - url: http://devpk.smart.smefdd.com - appId: wx8d11474c01b92378 - appSecret: e1fa7bcdf27b46e7d69edad68ea8724b - - diff --git a/smtweb-framework/sw-framework-core/target/classes/config/application.yaml b/smtweb-framework/sw-framework-core/target/classes/config/application.yaml deleted file mode 100644 index caf4dfc..0000000 --- a/smtweb-framework/sw-framework-core/target/classes/config/application.yaml +++ /dev/null @@ -1,3 +0,0 @@ -spring: - profiles: - active: dev \ No newline at end of file diff --git a/smtweb-framework/sw-framework-core/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/smtweb-framework/sw-framework-core/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst deleted file mode 100644 index a60fe75..0000000 --- a/smtweb-framework/sw-framework-core/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ /dev/null @@ -1,296 +0,0 @@ -cc\smtweb\framework\core\common\SwEnum$DatasetType.class -cc\smtweb\framework\core\common\SwEnum$DataType.class -cc\smtweb\framework\core\db\impl\DefaultDatabaseInfoImpl$1.class -cc\smtweb\framework\core\common\SwEnum$OptType.class -cc\smtweb\framework\core\mvc\controller\scan\ScanContext.class -cc\smtweb\framework\core\mvc\controller\access\SingletonFieldAccess.class -cc\smtweb\framework\core\common\SwEnum$EditorType.class -cc\smtweb\framework\core\db\cache\ModelTableCache$1.class -cc\smtweb\framework\core\db\cache\ModelTableCache.class -cc\smtweb\framework\core\util\jackson\LongDeserializer.class -cc\smtweb\framework\core\mvc\service\IWorker.class -cc\smtweb\framework\core\systask\TaskStartEvent.class -cc\smtweb\framework\core\cache\AbstractCache$IGetBeanKeys.class -cc\smtweb\framework\core\mvc\controller\binder\bean\UserSessionEditor.class -cc\smtweb\framework\core\cache\redis\RedisSysTask.class -cc\smtweb\framework\core\db\jdbc\BaseBeanPropertyRowMapper.class -cc\smtweb\framework\core\util\jackson\NullSerializer.class -com\serotonin\timer\sync\Synchronizer$TaskWrapper.class -cc\smtweb\framework\core\common\AbstractEnum$IntEnumBean.class -cc\smtweb\framework\core\mvc\controller\access\ControllerAccess.class -cc\smtweb\framework\core\common\SwEnum$TableType.class -cc\smtweb\framework\core\mvc\scheduler\job\GroupJobQueue.class -cc\smtweb\framework\core\util\jackson\DateSerializer.class -cc\smtweb\framework\core\CoreApplicationStartedListener.class -cc\smtweb\framework\core\mvc\controller\binder\param\AbstractRequestEditor.class -cc\smtweb\framework\core\mvc\controller\MethodAccessManager.class -cc\smtweb\framework\core\mvc\controller\binder\param\CharEditor.class -cc\smtweb\framework\core\common\SwEnum.class -cc\smtweb\framework\core\db\cache\EntityCache.class -cc\smtweb\framework\core\mvc\scheduler\job\SimpleJob.class -com\serotonin\timer\OneTimeTrigger.class -cc\smtweb\framework\core\mvc\variable\SwVariable.class -cc\smtweb\framework\core\util\kryo\KryoTool.class -cc\smtweb\framework\core\mvc\controller\scan\IScanActionBuilder.class -cc\smtweb\framework\core\mvc\realm\exception\AuthorizationException.class -cc\smtweb\framework\core\mvc\service\AbstractSaveHandler$1.class -cc\smtweb\framework\core\mvc\controller\binder\BeanContext.class -cc\smtweb\framework\core\mvc\service\AbstractCompProvider.class -cc\smtweb\framework\core\db\vo\ModelCache.class -cc\smtweb\framework\core\mvc\controller\access\MethodParamAccess.class -cc\smtweb\framework\core\db\sqlbuilder\InsertSqlBuilder.class -cc\smtweb\framework\core\mvc\service\DefaultSaveHandler.class -com\serotonin\timer\NonConcurrentTask.class -cc\smtweb\framework\core\mvc\controller\scan\PackageScanner.class -cc\smtweb\framework\core\common\AbstractEnum$EnumBean.class -cc\smtweb\framework\core\mvc\scheduler\job\SimpleJobQueue.class -com\serotonin\timer\TimeoutTask.class -cc\smtweb\framework\core\mvc\service\AbstractLoadHandler.class -cc\smtweb\framework\core\mvc\service\DefaultDelHandler.class -cc\smtweb\framework\core\util\NumberUtil.class -cc\smtweb\framework\core\db\jdbc\IdGenerator.class -com\serotonin\timer\TimerThread.class -cc\smtweb\framework\core\mvc\controller\access\IMethodAccess.class -com\serotonin\timer\sync\Synchronizer$TestTask.class -cc\smtweb\framework\core\exception\BindBeanException.class -cc\smtweb\framework\core\mvc\controller\binder\param\LongEditor.class -cc\smtweb\framework\core\CoreAutoConfiguration.class -cc\smtweb\framework\core\session\SessionManager.class -com\serotonin\timer\ScheduledRunnable.class -cc\smtweb\framework\core\mvc\controller\access\FieldAccess.class -com\serotonin\timer\ModelTimeoutTask.class -cc\smtweb\framework\core\db\vo\ModelIndex.class -cc\smtweb\framework\core\mvc\controller\binder\bean\HttpServletRequestEditor.class -cc\smtweb\framework\core\mvc\realm\service\PermChecker.class -com\serotonin\timer\TimerTrigger.class -cc\smtweb\framework\core\db\sqlbuilder\SelectSqlBuilder.class -cc\smtweb\framework\core\util\jackson\LongSerializer.class -com\serotonin\timer\SimulationTimer.class -cc\smtweb\framework\core\annotation\SwAction.class -cc\smtweb\framework\core\systask\WebStartedEvent.class -com\serotonin\timer\AbstractTimer.class -cc\smtweb\framework\core\cache\CacheManager.class -cc\smtweb\framework\core\systask\ISysTask.class -com\serotonin\timer\SystemTimeSource.class -cc\smtweb\framework\core\mvc\config\GlobalExceptionHandler.class -cc\smtweb\framework\core\db\jdbc\SwMapPropertyRowMapper.class -cc\smtweb\framework\core\util\IpAddrUtil.class -cc\smtweb\framework\core\util\MapUtil.class -cc\smtweb\framework\core\mvc\service\AbstractCompService.class -cc\smtweb\framework\core\mvc\controller\binder\param\DoubleEditor.class -cc\smtweb\framework\core\mvc\service\SwListData.class -cc\smtweb\framework\core\mvc\controller\binder\param\FloatEditor.class -cc\smtweb\framework\core\common\SwEnum$DataTypeBean.class -cc\smtweb\framework\core\mvc\scheduler\job\GroupJob.class -cc\smtweb\framework\core\db\DbEngine.class -cc\smtweb\framework\core\db\impl\UtilTime.class -cc\smtweb\framework\core\annotation\SwTable.class -cc\smtweb\framework\core\db\sqlbuilder\DirectSelectSqlBuilder.class -cc\smtweb\framework\core\cache\ISwCache.class -cc\smtweb\framework\core\db\cache\ModelDatabaseCache.class -cc\smtweb\framework\core\db\sqlbuilder\SqlBuilder.class -cc\smtweb\framework\core\session\SessionUtil.class -cc\smtweb\framework\core\util\jackson\TimestampDeserializer.class -cc\smtweb\framework\core\util\DateUtil.class -cc\smtweb\framework\core\exception\JsonParseException.class -cc\smtweb\framework\core\mvc\controller\binder\param\ShortEditor.class -cc\smtweb\framework\core\mvc\scheduler\AbstractJobExecutor.class -cc\smtweb\framework\core\mvc\service\AbstractDelHandler$1.class -cc\smtweb\framework\core\db\EntityHelper.class -cc\smtweb\framework\core\db\EntityDao.class -cc\smtweb\framework\core\db\vo\ModelDatabase.class -cc\smtweb\framework\core\cache\AbstractEntityCache.class -cc\smtweb\framework\core\common\AbstractEnum$IEnumWorker.class -com\serotonin\timer\sync\AsyncJobSink.class -cc\smtweb\framework\core\mvc\service\AbstractDelHandler.class -cc\smtweb\framework\core\mvc\controller\binder\bean\BeanEditor.class -cc\smtweb\framework\core\mvc\SchedulerManager.class -cc\smtweb\framework\core\cache\AbstractCache.class -cc\smtweb\framework\core\db\jdbc\JdbcTrans.class -com\serotonin\timer\ValueSet.class -cc\smtweb\framework\core\mvc\controller\DefaultPageController.class -cc\smtweb\framework\core\db\impl\DefaultDatabaseInfoImpl$2.class -cc\smtweb\framework\core\cache\redis\RedisManager.class -cc\smtweb\framework\core\mvc\controller\ApiController.class -cc\smtweb\framework\core\common\SwEnum$FieldType.class -cc\smtweb\framework\core\mvc\controller\binder\param\BeanTypeEditor.class -cc\smtweb\framework\core\annotation\SwService.class -cc\smtweb\framework\core\common\SwEnum$FieldTypeBean.class -cc\smtweb\framework\core\annotation\SwConstruct.class -com\serotonin\timer\TaskQueue.class -com\serotonin\timer\TimerTask.class -cc\smtweb\framework\core\db\config\DbEngineConfiguration.class -cc\smtweb\framework\core\util\VariableUtil.class -cc\smtweb\framework\core\mvc\realm\exception\AuthenticationException.class -cc\smtweb\framework\core\db\impl\IDatabaseInfo$TableCheckInfo.class -cc\smtweb\framework\core\annotation\SwHeaderParam.class -cc\smtweb\framework\core\db\sqlbuilder\AbstractUpdateSqlBuilder.class -cc\smtweb\framework\core\common\SwEnum$IndexType.class -cc\smtweb\framework\core\annotation\SwAttr.class -cc\smtweb\framework\core\db\impl\DefaultDatabaseInfoImpl.class -cc\smtweb\framework\core\cache\SessionCache.class -cc\smtweb\framework\core\common\SwEnum$SummaryType.class -cc\smtweb\framework\core\db\jdbc\AbsDbWorker.class -cc\smtweb\framework\core\mvc\controller\access\SchedulerMethodAccess.class -cc\smtweb\framework\core\mvc\controller\scan\UrlMaker.class -cc\smtweb\framework\core\exception\BindParamException.class -cc\smtweb\framework\core\exception\ExceptionMessage.class -cc\smtweb\framework\core\mvc\controller\binder\bean\SwIpAddrEditor.class -cc\smtweb\framework\core\CoreApplication.class -cc\smtweb\framework\core\mvc\service\IDataProvider.class -cc\smtweb\framework\core\db\sqlbuilder\UpdateSqlBuilder.class -cc\smtweb\framework\core\mvc\controller\scan\BeanManager.class -cc\smtweb\framework\core\util\jackson\BaseBeanSerializer.class -cc\smtweb\framework\core\db\sqlbuilder\SqlWhereValue.class -cc\smtweb\framework\core\util\SqlUtil.class -cc\smtweb\framework\core\common\AbstractEnum$StrEnumBean.class -cc\smtweb\framework\core\mvc\controller\binder\param\TimestampEditor.class -cc\smtweb\framework\core\common\SwConsts.class -cc\smtweb\framework\core\annotation\SwPerm.class -cc\smtweb\framework\core\mvc\controller\binder\path\PathParamEditor.class -com\serotonin\timer\TimerThread$1.class -cc\smtweb\framework\core\mvc\variable\ICalcVar.class -cc\smtweb\framework\core\mvc\controller\binder\body\BeanUtil.class -cc\smtweb\framework\core\mvc\controller\binder\body\SwMapBodyEditor.class -cc\smtweb\framework\core\mvc\scheduler\CronTimerTask.class -cc\smtweb\framework\core\mvc\scheduler\AbstractJob.class -cc\smtweb\framework\core\mvc\ISchedulerWakeup.class -cc\smtweb\framework\core\db\sqlbuilder\DeleteSqlBuilder.class -cc\smtweb\framework\core\db\impl\DefaultEntity.class -cc\smtweb\framework\core\util\SpringUtil.class -cc\smtweb\framework\core\mvc\service\AbstractSaveHandler.class -cc\smtweb\framework\core\mvc\service\DefaultLoadHandler.class -cc\smtweb\framework\core\mvc\scheduler\job\RedisJobExecutor.class -cc\smtweb\framework\core\mvc\service\SqlPara.class -cc\smtweb\framework\core\mvc\scheduler\FixedTimerTask.class -cc\smtweb\framework\core\common\AbstractEnum.class -cc\smtweb\framework\core\mvc\config\SettingsEnvironmentPostProcessor.class -cc\smtweb\framework\core\cache\redis\RedisSysTask$1.class -cc\smtweb\framework\core\db\vo\ModelField.class -com\serotonin\timer\AbstractTimerTrigger.class -com\serotonin\timer\RealTimeTimer.class -cc\smtweb\framework\core\db\impl\DatabaseUtil.class -cc\smtweb\framework\core\common\SwEnum$FilterType.class -cc\smtweb\framework\core\mvc\controller\binder\attr\BeanAttrEditor.class -cc\smtweb\framework\core\mvc\controller\access\MethodAccess.class -com\serotonin\timer\TimeSource.class -cc\smtweb\framework\core\annotation\SwBody.class -cc\smtweb\framework\core\mvc\scheduler\SchedulerPoint.class -cc\smtweb\framework\core\mvc\controller\access\IBeanAccess.class -cc\smtweb\framework\core\common\IntEnum.class -cc\smtweb\framework\core\cache\redis\config\RedisConfig.class -cc\smtweb\framework\core\mvc\service\AbstractHandler.class -com\serotonin\timer\FixedRateTrigger.class -cc\smtweb\framework\core\mvc\realm\exception\UnauthenticatedException.class -cc\smtweb\framework\core\cache\redis\RedisBroadcastEvent.class -cc\smtweb\framework\core\mvc\realm\interceptor\AuthorizationInterceptor.class -cc\smtweb\framework\core\mvc\scheduler\job\LocalJobExecutor.class -com\serotonin\timer\NamedRunnable.class -cc\smtweb\framework\core\mvc\controller\ApiConfigBean.class -cc\smtweb\framework\core\exception\DbException.class -cc\smtweb\framework\core\mvc\realm\exception\UnknownAccountException.class -com\serotonin\timer\ScheduledNamedRunnable.class -cc\smtweb\framework\core\mvc\controller\IBeanContext.class -cc\smtweb\framework\core\db\DbEngine$1.class -cc\smtweb\framework\core\db\sqlbuilder\SqlJoinField.class -cc\smtweb\framework\core\mvc\controller\binder\param\BooleanEditor.class -cc\smtweb\framework\core\exception\SwException.class -cc\smtweb\framework\core\systask\SysTaskManager.class -cc\smtweb\framework\core\util\CommUtil.class -cc\smtweb\framework\core\common\R.class -cc\smtweb\framework\core\db\jdbc\IDbWorker.class -com\serotonin\timer\sync\Synchronizer.class -cc\smtweb\framework\core\annotation\SwBean.class -cc\smtweb\framework\core\db\impl\IDatabaseInfo$ColumnCheckInfo.class -cc\smtweb\framework\core\annotation\SwCache.class -com\serotonin\timer\sync\SingleExecutorSingleWaiter$TaskWrapper.class -cc\smtweb\framework\core\db\sqlbuilder\SqlFieldValue.class -cc\smtweb\framework\core\mvc\service\AbstractListHandler.class -com\serotonin\timer\ModelTimeoutClient.class -cc\smtweb\framework\core\mvc\controller\scan\ApplicationScanner.class -cc\smtweb\framework\core\mvc\service\DefaultSaveHandler$1.class -cc\smtweb\framework\core\db\sqlbuilder\SqlJoinTable.class -cc\smtweb\framework\core\util\jackson\DateDeserializer.class -cc\smtweb\framework\core\mvc\controller\binder\param\DateEditor.class -cc\smtweb\framework\core\annotation\SwColumnForeign.class -com\serotonin\timer\sync\AsyncJobSink$Event.class -cc\smtweb\framework\core\mvc\controller\scan\ClassParser.class -cc\smtweb\framework\core\mvc\realm\IRealmLoader.class -cc\smtweb\framework\core\mvc\controller\binder\param\TimeEditor.class -cc\smtweb\framework\core\util\jackson\TimeSerializer.class -cc\smtweb\framework\core\db\dao\AbstractEntityDao.class -cc\smtweb\framework\core\db\sqlbuilder\AbstractSelectSqlBuilder.class -cc\smtweb\framework\core\db\vo\ModelProject.class -cc\smtweb\framework\core\mvc\controller\scan\MethodParser.class -cc\smtweb\framework\core\mvc\realm\exception\ForbiddenException.class -cc\smtweb\framework\core\mvc\service\DefaultComboHandler.class -com\serotonin\timer\FixedDelayTrigger.class -cc\smtweb\framework\core\annotation\SwColumn$Type.class -cc\smtweb\framework\core\annotation\SwPathParam.class -cc\smtweb\framework\core\common\SwIpAddr.class -cc\smtweb\framework\core\db\jdbc\JdbcEngine.class -cc\smtweb\framework\core\mvc\controller\binder\body\StringBodyEditor.class -cc\smtweb\framework\core\mvc\controller\binder\param\AbstractParameterEditor.class -cc\smtweb\framework\core\db\dao\EntityColumnForeign.class -cc\smtweb\framework\core\mvc\controller\binder\param\IntegerEditor.class -cc\smtweb\framework\core\db\config\YamlPropertyLoaderFactory.class -cc\smtweb\framework\core\mvc\service\SqlNamedPara.class -cc\smtweb\framework\core\mvc\service\DefaultListHandler.class -cc\smtweb\framework\core\mvc\controller\binder\param\StringEditor.class -cc\smtweb\framework\core\mvc\scheduler\SchedulerTaskManager.class -com\serotonin\timer\CronExpression.class -cc\smtweb\framework\core\cache\redis\RedisConnection.class -cc\smtweb\framework\core\mvc\controller\binder\param\AbstractNumberEditor.class -cc\smtweb\framework\core\mvc\controller\IActionManager.class -cc\smtweb\framework\core\db\impl\BaseBean.class -cc\smtweb\framework\core\mvc\config\ControllerConfig.class -com\serotonin\timer\SimulationTimer$1.class -cc\smtweb\framework\core\mvc\variable\SwVariableFactory.class -cc\smtweb\framework\core\util\JsonUtil.class -com\serotonin\timer\ExecutionRejectedException.class -cc\smtweb\framework\core\mvc\controller\binder\CacheEditor.class -cc\smtweb\framework\core\cache\AbstractCache$IGetBeanKey.class -cc\smtweb\framework\core\cache\SessionCacheFactory.class -cc\smtweb\framework\core\mvc\controller\binder\param\ByteEditor.class -cc\smtweb\framework\core\annotation\SwScheduling.class -cc\smtweb\framework\core\mvc\controller\binder\param\IEditorValue.class -cc\smtweb\framework\core\mvc\controller\binder\WebDataBinder.class -cc\smtweb\framework\core\db\vo\ModelLinkName.class -cc\smtweb\framework\core\mvc\service\TreeHelper.class -cc\smtweb\framework\core\common\SwEnum$IndexTypeBean.class -cc\smtweb\framework\core\common\SwEnum$FormType.class -cc\smtweb\framework\core\common\SwEnum$WidgetType.class -com\serotonin\timer\sync\SingleExecutorSingleWaiter.class -cc\smtweb\framework\core\mvc\service\AbstractTreeHandler.class -cc\smtweb\framework\core\mvc\controller\binder\body\BeanBodyEditor.class -cc\smtweb\framework\core\mvc\realm\interceptor\PermInterceptor.class -com\serotonin\timer\CronTimerTrigger.class -cc\smtweb\framework\core\mvc\service\DefaultProvider.class -cc\smtweb\framework\core\db\vo\ModelCatalog.class -cc\smtweb\framework\core\mvc\controller\scan\IScanAction.class -cc\smtweb\framework\core\mvc\controller\access\BindFieldAccess.class -cc\smtweb\framework\core\mvc\controller\scan\BeanManager$OrderMethodAccess.class -cc\smtweb\framework\core\db\jdbc\MapPropertyRowMapper.class -cc\smtweb\framework\core\common\SwMap.class -cc\smtweb\framework\core\mvc\controller\IEditor.class -cc\smtweb\framework\core\mvc\controller\binder\ParamEditor.class -cc\smtweb\framework\core\session\UserSession.class -cc\smtweb\framework\core\mvc\controller\binder\bean\NullEditor.class -cc\smtweb\framework\core\db\dao\EntityColumn.class -cc\smtweb\framework\core\cache\redis\RedisPooledObjectFactory.class -cc\smtweb\framework\core\db\vo\ModelTable.class -cc\smtweb\framework\core\mvc\realm\service\PermCheckItem.class -com\serotonin\timer\SimulationTimeSource.class -cc\smtweb\framework\core\annotation\SwDestroy.class -cc\smtweb\framework\core\mvc\controller\binder\attr\AbstractAttrEditor.class -cc\smtweb\framework\core\mvc\scheduler\AbstractJobQueue.class -cc\smtweb\framework\core\db\impl\IDatabaseInfo.class -cc\smtweb\framework\core\mvc\realm\interceptor\AbstractPermInterceptor.class -cc\smtweb\framework\core\annotation\SwColumn.class -cc\smtweb\framework\core\exception\BizException.class -cc\smtweb\framework\core\mvc\controller\binder\bean\AbstractContextEditor.class -cc\smtweb\framework\core\annotation\SwParam.class -cc\smtweb\framework\core\mvc\service\list\FooterField.class -cc\smtweb\framework\core\common\StrEnum.class -cc\smtweb\framework\core\mvc\config\WebMvcConfig.class -cc\smtweb\framework\core\session\UserSessionArgumentResolver.class diff --git a/smtweb-framework/sw-framework-core/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/smtweb-framework/sw-framework-core/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index f17edd0..0000000 --- a/smtweb-framework/sw-framework-core/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,256 +0,0 @@ -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwParam.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\DirectSelectSqlBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\ExecutionRejectedException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\AbstractJob.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\FixedTimerTask.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\systask\TaskStartEvent.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\variable\ICalcVar.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\bean\AbstractContextEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\InsertSqlBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\AbstractTreeHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwAction.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\exception\AuthorizationException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\jackson\DateDeserializer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwService.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\TimestampEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\config\YamlPropertyLoaderFactory.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\SchedulerPoint.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\session\SessionUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\common\IntEnum.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\CoreApplicationStartedListener.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\vo\ModelIndex.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\jackson\DateSerializer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\jdbc\MapPropertyRowMapper.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\vo\ModelCatalog.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\MethodAccessManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\BeanManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\DefaultComboHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\BooleanEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\FloatEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\SchedulerTaskManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\redis\RedisBroadcastEvent.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\PackageScanner.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\jdbc\BaseBeanPropertyRowMapper.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\IDataProvider.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\DefaultPageController.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\AbstractCompProvider.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\config\GlobalExceptionHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwPerm.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\jackson\LongDeserializer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\AbstractSaveHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\common\AbstractEnum.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\common\SwMap.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\vo\ModelTable.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\bean\HttpServletRequestEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\DateEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\list\FooterField.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\SchedulerMethodAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\exception\UnauthenticatedException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\redis\RedisPooledObjectFactory.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\bean\NullEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\interceptor\PermInterceptor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\TimerTrigger.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\StringEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\SqlJoinField.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\dao\EntityColumnForeign.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\exception\ExceptionMessage.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwAttr.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\EntityDao.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\SessionCacheFactory.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\BeanTypeEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\vo\ModelLinkName.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\jackson\LongSerializer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\impl\DefaultDatabaseInfoImpl.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\AbstractEntityCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\MethodParser.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\exception\SwException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\exception\DbException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\jdbc\AbsDbWorker.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\cache\EntityCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\SpringUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\UrlMaker.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\AbstractDelHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\IBeanAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\impl\IDatabaseInfo.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\attr\AbstractAttrEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\job\GroupJobQueue.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\session\SessionManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\impl\DatabaseUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\sync\Synchronizer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\session\UserSession.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\jdbc\IDbWorker.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\BeanContext.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\IScanActionBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\AbstractHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\IEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\exception\ForbiddenException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\AbstractLoadHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\ShortEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\LongEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\DefaultSaveHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\SqlBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\WebDataBinder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\jackson\BaseBeanSerializer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\jackson\TimeSerializer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\SqlNamedPara.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\AbstractCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\ParamEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\bean\BeanEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\exception\BindParamException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\DefaultListHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\ApiController.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\redis\RedisConnection.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwBody.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwHeaderParam.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\AbstractSelectSqlBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\ScheduledNamedRunnable.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\EntityHelper.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwDestroy.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\config\DbEngineConfiguration.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\bean\SwIpAddrEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\SimulationTimer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\ScanContext.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwConstruct.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\SingletonFieldAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\ClassParser.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\vo\ModelCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\config\SettingsEnvironmentPostProcessor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\sync\AsyncJobSink.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\common\StrEnum.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\ApiConfigBean.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\AbstractJobExecutor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\sync\SingleExecutorSingleWaiter.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\body\StringBodyEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\FixedDelayTrigger.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\TimerTask.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\common\SwIpAddr.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\ByteEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\body\SwMapBodyEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\systask\WebStartedEvent.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\SqlPara.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\exception\AuthenticationException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\DateUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\SqlUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\vo\ModelField.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\impl\BaseBean.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\SchedulerManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\TimerThread.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\CacheEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\redis\RedisManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\VariableUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwColumnForeign.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\CharEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwColumn.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\interceptor\AbstractPermInterceptor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\TreeHelper.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\ISchedulerWakeup.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\CronTimerTask.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\BindFieldAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\SystemTimeSource.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\systask\ISysTask.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\service\PermChecker.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\UpdateSqlBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\session\UserSessionArgumentResolver.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwScheduling.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\AbstractTimerTrigger.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\cache\ModelDatabaseCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\bean\UserSessionEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\impl\UtilTime.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\RealTimeTimer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\jdbc\IdGenerator.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\SqlWhereValue.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\DeleteSqlBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\IBeanContext.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\service\PermCheckItem.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\JsonUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\job\LocalJobExecutor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\job\GroupJob.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\jackson\TimestampDeserializer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\SelectSqlBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\vo\ModelDatabase.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\kryo\KryoTool.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\DefaultLoadHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\SessionCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\DefaultProvider.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\AbstractNumberEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\exception\JsonParseException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\IActionManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\CommUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwTable.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\cache\ModelTableCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\AbstractRequestEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\NumberUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\dao\AbstractEntityDao.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\AbstractParameterEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\DefaultDelHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\TimeoutTask.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\IntegerEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\MapUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\CoreApplication.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\vo\ModelProject.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\CacheManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\AbstractCompService.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\FieldAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\body\BeanUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\common\R.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\AbstractListHandler.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\job\SimpleJob.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\common\SwEnum.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\DbEngine.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\redis\RedisSysTask.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\IWorker.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\jackson\NullSerializer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\FixedRateTrigger.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\AbstractUpdateSqlBuilder.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\variable\SwVariable.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\AbstractJobQueue.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\jdbc\JdbcEngine.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\AbstractTimer.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\OneTimeTrigger.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\job\SimpleJobQueue.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\impl\DefaultEntity.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwBean.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\annotation\SwPathParam.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\NonConcurrentTask.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\ApplicationScanner.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\TaskQueue.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\TimeSource.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\SqlJoinTable.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\CronTimerTrigger.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\jdbc\SwMapPropertyRowMapper.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\config\WebMvcConfig.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\exception\UnknownAccountException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\ScheduledRunnable.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\common\SwConsts.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\ISwCache.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\MethodAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\scan\IScanAction.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\scheduler\job\RedisJobExecutor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\DoubleEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\variable\SwVariableFactory.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\IMethodAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\interceptor\AuthorizationInterceptor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\util\IpAddrUtil.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\CronExpression.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\ModelTimeoutTask.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\ModelTimeoutClient.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\jdbc\JdbcTrans.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\config\ControllerConfig.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\param\TimeEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\SimulationTimeSource.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\exception\BindBeanException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\CoreAutoConfiguration.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\path\PathParamEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\sqlbuilder\SqlFieldValue.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\systask\SysTaskManager.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\db\dao\EntityColumn.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\realm\IRealmLoader.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\service\SwListData.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\attr\BeanAttrEditor.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\ControllerAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\exception\BizException.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\com\serotonin\timer\NamedRunnable.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\access\MethodParamAccess.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\cache\redis\config\RedisConfig.java -E:\jujia\git\6.0\smtweb2\smtweb-framework\sw-framework-core\src\main\java\cc\smtweb\framework\core\mvc\controller\binder\body\BeanBodyEditor.java diff --git a/smtweb-framework/sw-system-bpm/.gitignore b/smtweb-framework/sw-system-bpm/.gitignore deleted file mode 100644 index 29fde54..0000000 --- a/smtweb-framework/sw-system-bpm/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# ---> Java -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -.idea/ -*.iml -target diff --git a/smtweb-framework/sw-system-bpm/doc/SwBody.puml b/smtweb-framework/sw-system-bpm/doc/SwBody.puml deleted file mode 100644 index 27862c3..0000000 --- a/smtweb-framework/sw-system-bpm/doc/SwBody.puml +++ /dev/null @@ -1,10 +0,0 @@ -@startuml -(*) --> "check input" -If "input is verbose" then ---> [Yes] "turn on verbosity" ---> "run command" -else ---> "run command" -Endif ---> (*) -@enduml diff --git a/smtweb-framework/sw-system-bpm/doc/TODO.md b/smtweb-framework/sw-system-bpm/doc/TODO.md deleted file mode 100644 index 4160543..0000000 --- a/smtweb-framework/sw-system-bpm/doc/TODO.md +++ /dev/null @@ -1,4 +0,0 @@ -[db design] -1. 同步数据库时返回需要手段删除的字段和表 -2. 导出和导入数据结构 -3. 数据库名不允许重复 diff --git a/smtweb-framework/sw-system-bpm/doc/TODO20210714.md b/smtweb-framework/sw-system-bpm/doc/TODO20210714.md deleted file mode 100644 index 42998d4..0000000 --- a/smtweb-framework/sw-system-bpm/doc/TODO20210714.md +++ /dev/null @@ -1,11 +0,0 @@ -[ui design] -1. 数据库源字段有多个N:N非ID字段取值的情况,避免重复取值的情况 -2. bug outline-panel上下移动 -3. panel 调整方向后没有重新计算位置 -4. redo/undo -[bpm] -1. ** 后台检测数据集需要配置ID作用字段 -2. 后台检测数据集必须配置idField -3. 后台验证和前台统一 -4. PO代码生成加字段注解 -5. ** 卡片保存时未返回id值 diff --git a/smtweb-framework/sw-system-bpm/doc/smt_asp20201229.txt b/smtweb-framework/sw-system-bpm/doc/smt_asp20201229.txt deleted file mode 100644 index ce4160c..0000000 --- a/smtweb-framework/sw-system-bpm/doc/smt_asp20201229.txt +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE `asp_model` - ADD COLUMN `mode_md_id` BIGINT(20) NULL DEFAULT NULL COMMENT '����ģ��id, asp_model_delply.md_id' AFTER `model_order`; - -ALTER TABLE `asp_model` - ADD CONSTRAINT `FK_asp_model_asp_model_deploy` FOREIGN KEY (`mode_md_id`) REFERENCES `asp_model_deploy` (`md_id`); - diff --git a/smtweb-framework/sw-system-bpm/doc/trans.sql b/smtweb-framework/sw-system-bpm/doc/trans.sql deleted file mode 100644 index c4fb911..0000000 --- a/smtweb-framework/sw-system-bpm/doc/trans.sql +++ /dev/null @@ -1,26 +0,0 @@ --- 用户中心迁移数据 - -INSERT INTO sys_area(area_id, area_code, area_full_code, area_order, area_name, area_full_name, area_type, area_province_name, area_city_name, area_town_name, - area_town_full_name, area_village_name, area_village_full_name, area_community_name, area_community_full_name, - area_tree_level, area_parent_id, area_parent_id_list, area_status, area_stop_desc, area_desc, area_last_time, area_create_party_id - ) SELECT `area_id`, `area_code`, `area_code_12`, `sequence_code`, `area_name`, `area_full_name`, `area_type`, `area_name_shengshi`, `area_name_dishi`, `area_name_quxian`, `area_full_name_quxian`, `area_name_xiangz`, `area_full_name_xiangz`, `area_name_chun`, `area_full_name_chun`, `tree_level`, `parent_id`, `parent_id_list`, `statu`, `stop_desc`, `description`, `last_time`, `create_party_id` FROM tb_sys_area; - - -INSERT INTO sw_user.sys_user(user_id, user_code, user_nick_code, user_nick_name, user_kind, user_sex, user_head, user_signature, user_phone, user_email, - user_pwd, user_score, user_level, user_otp_id, user_err_count, user_lock_time, user_stop_info, user_pwd_time, user_last_time, user_last_ip, - user_last_info, user_status, user_create_party_id, user_create_time) -SELECT user_id, user_code, nick_code, nick_name, user_kind, user_sex, user_head, user_signature, user_phone, user_email, - user_pwd, user_score, user_level, otp_id, err_count, lock_time, stop_info, pwd_time, last_time, last_ip, - last_info, statu, create_party_id, last_time FROM demo.tb_sys_user_base; - -INSERT INTO sw_user.sys_user_card(uc_id, uc_card_name, uc_card_type, uc_card_number, uc_card_pic_url, uc_card_from_time, - uc_card_end_time, uc_card_authority, uc_card_addr, uc_id_status, uc_status, uc_desc, uc_last_time, uc_create_party_id) -SELECT user_id, user_name, card_type, card_number, card_pic_url, card_from, - card_end, id_authority, id_addr, id_statu, statu, remarks, last_time, create_party_id -FROM demo.tb_sys_user_card; - -INSERT INTO sw_user.sys_user_ex (ue_id, ue_cert_id, ue_party_id, ue_dept_id, ue_portal_id, - ue_portal_type, ue_portal_bi_url, ue_station, ue_tel, ue_otp_id, ue_is_fix, ue_msspid, ue_photo_id, ue_last_time, ue_create_party_id) -SELECT user_id, user_cert_id, party_id, department_id, portal_id, - portal_type, portal_bi_url, station, tel, otp_id, is_fix, msspid, photo_id, last_time, create_party_id -FROM demo.tb_sys_user_ex; diff --git a/smtweb-framework/sw-system-bpm/doc/update20210907.sql b/smtweb-framework/sw-system-bpm/doc/update20210907.sql deleted file mode 100644 index 9d0ac10..0000000 --- a/smtweb-framework/sw-system-bpm/doc/update20210907.sql +++ /dev/null @@ -1,75 +0,0 @@ -CREATE TABLE `bpm_model` ( - `model_id` BIGINT(20) NOT NULL, - `model_full_name` VARCHAR(64) NULL DEFAULT NULL COMMENT '用.连接唯一地址:模块名+全路径名称' COLLATE 'utf8_unicode_ci', - `model_name` VARCHAR(200) NOT NULL COMMENT '名称' COLLATE 'utf8_unicode_ci', - `model_type` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '模型类型: 1 数据模型,2 工作流模型,3 PC界面,4 手机界面', - `model_content` MEDIUMTEXT NULL DEFAULT NULL COMMENT '内容,json格式' COLLATE 'utf8_unicode_ci', - `model_content_sign` VARCHAR(100) NULL DEFAULT NULL COMMENT 'sha256(内容),内容长度', - `model_status` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '状态:0 启用,1 禁用', - `model_version` INT(11) NOT NULL DEFAULT '0' COMMENT '版本', - `model_order` INT(11) NOT NULL DEFAULT '0' COMMENT '排序', - `model_site_id` BIGINT(20) NULL DEFAULT NULL COMMENT '站点ID', - `model_create_time` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '创建时间', - `model_last_time` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '更新时间', - PRIMARY KEY (`model_id`) USING BTREE, - UNIQUE INDEX `model_full_name` (`model_full_name`) USING BTREE -) -COMMENT='应用支撑平台模型定义' -COLLATE='utf8_unicode_ci' -ENGINE=InnoDB -ROW_FORMAT=DYNAMIC -; - -ALTER TABLE `asp_model` - CHANGE COLUMN `model_create_at` `model_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `model_update_uid`, - CHANGE COLUMN `model_update_at` `model_last_time` BIGINT NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `model_create_time`; - -ALTER TABLE `asp_model_catalog` - CHANGE COLUMN `mc_create_at` `mc_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `mc_module`, - CHANGE COLUMN `mc_update_at` `mc_last_time` BIGINT NOT NULL DEFAULT 0 AFTER `mc_create_time`; - -ALTER TABLE `asp_model_deploy` - CHANGE COLUMN `md_create_at` `md_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `md_update_uid`, - CHANGE COLUMN `md_update_at` `md_last_time` BIGINT NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `md_create_time`; - -ALTER TABLE `bpm_dyn_form_log` - CHANGE COLUMN `dfl_create_at` `dfl_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `dfl_lock_rev`, - CHANGE COLUMN `dfl_update_at` `dfl_last_time` BIGINT NOT NULL DEFAULT 0 AFTER `dfl_create_time`; - -ALTER TABLE `bpm_node_log` - CHANGE COLUMN `nl_create_at` `nl_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `nl_duration`; - -ALTER TABLE `bpm_process` - CHANGE COLUMN `process_create_at` `process_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `process_route`, - CHANGE COLUMN `process_update_at` `process_last_time` BIGINT NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `process_create_time`; - -ALTER TABLE `bpm_process_user` - CHANGE COLUMN `pu_create_at` `pu_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `pu_type`, - CHANGE COLUMN `pu_update_at` `pu_last_time` BIGINT NOT NULL DEFAULT 0 AFTER `pu_create_time`; - -ALTER TABLE `bpm_task` - CHANGE COLUMN `task_create_at` `task_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `task_due_time`, - CHANGE COLUMN `task_update_at` `task_last_time` BIGINT NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `task_create_time`; - -ALTER TABLE `bpm_process_log` - CHANGE COLUMN `pl_create_at` `pl_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `pl_route`; - -ALTER TABLE `bpm_process_attachment_log` - CHANGE COLUMN `pal_create_at` `pal_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `pal_type`; - -ALTER TABLE `bpm_process_comment_log` - CHANGE COLUMN `pcl_create_at` `pcl_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `pcl_content`; - -ALTER TABLE `bpm_process_detail_log` - CHANGE COLUMN `pdl_create_at` `pdl_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `pdl_lock_rev`, - CHANGE COLUMN `pdl_update_at` `pdl_last_time` BIGINT NOT NULL DEFAULT 0 AFTER `pdl_create_time`; - -ALTER TABLE `bpm_task_log` - CHANGE COLUMN `tl_create_at` `tl_create_time` BIGINT NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `tl_claim_time`; - -ALTER TABLE `bpm_variable` - CHANGE COLUMN `var_create_at` `var_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `var_lock_rev`, - CHANGE COLUMN `var_update_at` `var_update_time` BIGINT NOT NULL DEFAULT 0 AFTER `var_create_time`; - -ALTER TABLE `bpm_variable_log` - CHANGE COLUMN `vl_create_at` `vl_create_time` BIGINT NOT NULL DEFAULT 0 AFTER `vl_lock_rev`; diff --git a/smtweb-framework/sw-system-bpm/doc/update20211122.sql b/smtweb-framework/sw-system-bpm/doc/update20211122.sql deleted file mode 100644 index d87633b..0000000 --- a/smtweb-framework/sw-system-bpm/doc/update20211122.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE `asp_model` - ADD COLUMN `model_sub_type` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '模型子类型:0 默认 1 页面 2 子页面 3 目录' AFTER `model_type`; -ALTER TABLE `asp_model` - ADD COLUMN `model_icon` VARCHAR(50) NULL COMMENT '图标' AFTER `model_sub_type`; -ALTER TABLE `asp_model_catalog` - ADD COLUMN `mc_icon` VARCHAR(50) NOT NULL COMMENT '项目图标' AFTER `mc_name`; diff --git a/smtweb-framework/sw-system-bpm/doc/版本修改说明.md b/smtweb-framework/sw-system-bpm/doc/版本修改说明.md deleted file mode 100644 index d1c430f..0000000 --- a/smtweb-framework/sw-system-bpm/doc/版本修改说明.md +++ /dev/null @@ -1,8 +0,0 @@ -2.1.0 break changes -1. 数据库升级 update20210907 - smt_ => sw_ -2. 必填和验证规则设置到数据集里面了 -3. 移除数据集的表类型属性tableType, 添加 initData - - -后台写 defaultEvent.js 后台 ctrl+shift+f9 diff --git a/smtweb-framework/sw-system-bpm/pom.xml b/smtweb-framework/sw-system-bpm/pom.xml deleted file mode 100644 index 150d9ad..0000000 --- a/smtweb-framework/sw-system-bpm/pom.xml +++ /dev/null @@ -1,216 +0,0 @@ - - - 4.0.0 - - sw-system-bpm - cc.smtweb - 3.1.0-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-parent - 2.5.6 - - - - - 1.8 - 1.8 - - - - - org.springframework.boot - spring-boot-starter-web - - - cc.smtweb - sw-framework-core - 3.1.0-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-freemarker - - - net.coobird - thumbnailator - [0.4, 0.5) - - - org.jclarion - image4j - 0.7 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.11.0 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-xml - 2.11.0 - - - - - - - - - org.apache.velocity - velocity-engine-core - 2.3 - compile - - - org.springframework.boot - spring-boot-test - test - - - - org.junit.platform - junit-platform-launcher - 1.6.2 - test - - - - org.junit.jupiter - junit-jupiter-api - 5.6.2 - test - - - - org.junit.jupiter - junit-jupiter-engine - 5.6.2 - test - - - org.junit.vintage - junit-vintage-engine - 5.6.2 - test - - - org.junit.jupiter - junit-jupiter-params - 5.6.2 - test - - - - - - - - - - - - org.mockito - mockito-all - 1.10.19 - test - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - verify - - jar-no-fork - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - config/application.yaml - config/application-dev.yaml - config/application-prod.yaml - - - - - - - - E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-ui-design-vue/dist/ - ${basedir}/target/classes/static/design/ui - - - - E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-db-design-vue/dist/ - ${basedir}/target/classes/static/design/db - - - - E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-flow-design-vue/dist/ - ${basedir}/target/classes/static/design/flow - - - - E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-framework-widget-vue/dist/ - ${basedir}/target/classes/static/design/preview - - - - src/main/resources - - - - - - - nexus-releases - Nexus Release Repository - http://47.92.149.153:7000/repository/maven-releases/ - - - nexus-snapshots - Nexus Snapshot Repository - http://47.92.149.153:7000/repository/maven-snapshots/ - - - diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java deleted file mode 100644 index 3c3543b..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.smtweb.system.bpm.spring; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * @author xkliu - */ -@SpringBootApplication -public class BpmApplication { - public static void main(String[] args) { - SpringApplication.run(BpmApplication.class, args); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java deleted file mode 100644 index 211a8f7..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.smtweb.system.bpm.spring; - -import cc.smtweb.framework.core.mvc.config.ControllerConfig; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -/** - * @author kevin - */ -@Configuration -@ComponentScan -public class BpmAutoConfiguration { - /** 配置自定义service扫描路径 {module}/{service}/{method} */ - @Bean - public ControllerConfig bpmControllerConfig() { - return new ControllerConfig("bpm", "cc.smtweb.system.bpm.web", null); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java deleted file mode 100644 index 454e6ff..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.smtweb.system.bpm.spring; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -@Component -@ConfigurationProperties(prefix = "smtweb.bpm") -@Data -public class BpmConfigBean { - // 是否debug模式 - private boolean debug; - private String codeJavaPath; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java deleted file mode 100644 index 19475c5..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java +++ /dev/null @@ -1,26 +0,0 @@ -package cc.smtweb.system.bpm.spring.config; - -import cc.smtweb.system.bpm.util.FilePathGenerator; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import cc.smtweb.framework.core.db.jdbc.IdGenerator; - -/** - * 微服务框架封装自动配置类 - */ -@Configuration -public class FileConfig { - // 文件本地存储配置 - @Value("${smtweb.file.local-path}") - private String fileLocalPath; - - // 文件请求URL路径配置 http://127.0.0.1:${server.port}/${server.servlet.context-path}/files/ - @Value("${smtweb.file.url}") - private String fileUrl; - - @Bean - public FilePathGenerator filePathGenerator(IdGenerator idGenerator) { - return new FilePathGenerator(fileLocalPath, fileUrl, idGenerator); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java deleted file mode 100644 index 40e6795..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java +++ /dev/null @@ -1,185 +0,0 @@ -package cc.smtweb.system.bpm.spring.controller; - -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.session.SessionUtil; -import cc.smtweb.system.bpm.util.FilePathGenerator; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.DateUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.InputStreamResource; -import org.springframework.http.*; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.util.concurrent.TimeUnit; - -@RestController -public class FileDownloadController { - private static final MediaType APPLICATION_JAVASCRIPT = new MediaType("application", "javascript"); - @Value("${smtweb.static.local-path:}") - private String staticLocalPath; - - @Autowired - private FilePathGenerator filePathGenerator; - - @Autowired - private RedisManager redisManager; - - /** path方式下载文件 */ - @GetMapping("/fs/files/**") - public ResponseEntity files(@RequestParam(value="name", required=false) String name, - @RequestParam(value="noCache", required=false) Boolean noCache, - HttpServletRequest request - ) throws FileNotFoundException { - String filePath = request.getRequestURI().substring(10); - return download(filePath, name, noCache, request); - } - - /** 参数方式下载文件 */ - @GetMapping("/fs/download") - public ResponseEntity download(@RequestParam(value="path") String path, - @RequestParam(value="name", required=false) String name, - @RequestParam(value="noCache", required=false) Boolean noCache, - HttpServletRequest request - ) throws FileNotFoundException { - SessionUtil.checkSession(request, redisManager); - - File file = new File(filePathGenerator.getFileDiskPath(path)); - - if (!file.exists()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); - } - - if (StringUtils.isBlank(name)) { - name = file.getName(); - } - - HttpHeaders headers = new HttpHeaders(); - if (Boolean.TRUE.equals(noCache)) { - headers.setCacheControl("no-cache, no-store, must-revalidate"); - headers.setPragma("no-cache"); - headers.setExpires(0); - } - - headers.setLastModified(file.lastModified()); - headers.add("Content-Disposition", - String.format("attachment; filename=\"%s\"", new String(name.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1))); - - return ResponseEntity.ok() - .headers(headers) - .contentLength(file.length()) - .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(new InputStreamResource(new FileInputStream(file))); - } - - /** path方式读取静态目录文件 */ - @GetMapping("/fs/static/**") - public ResponseEntity resource(@RequestParam(value="default", required=false) String defaultPath, - @RequestParam(value="noCache", required=false) Boolean noCache, - @RequestHeader(value="If-Modified-Since", required = false) String ifModifiedSince, - HttpServletRequest request) throws FileNotFoundException { - String filePath = request.getRequestURI().substring(11); - - HttpHeaders headers = new HttpHeaders(); - - if (Boolean.TRUE.equals(noCache)) { - headers.setCacheControl("no-cache, no-store, must-revalidate"); - headers.setPragma("no-cache"); - headers.setExpires(0); - } else { - // 暂时缓存1天 - headers.setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)); - headers.setExpires(Instant.ofEpochMilli(System.currentTimeMillis() + DateUtils.MILLIS_PER_DAY)); - } - - String name = getFileName(filePath); - headers.add("Content-Disposition", - String.format("attachment; filename=\"%s\"", new String(name.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1))); - - MediaType contentType = getContentType(filePath); - // 先找文件 - if (StringUtils.isNotBlank(staticLocalPath)) { - File file = new File(staticLocalPath + filePath); - - if (file.exists()) { - headers.setLastModified(file.lastModified()); - - return ResponseEntity.ok() - .headers(headers) - .contentLength(file.length()) - .contentType(contentType) - .body(new InputStreamResource(new FileInputStream(file))); - } - } - - // 再找资源目录 - InputStream inputStream = getClass().getResourceAsStream("/static/" + filePath); - if (inputStream != null) { - return buildResource(inputStream, contentType, headers); - } else if (StringUtils.isNotBlank(defaultPath)) { - inputStream = getClass().getResourceAsStream("/static/" + defaultPath); - if (inputStream != null) { - return buildResource(inputStream, contentType, headers); - } - } - - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); - } - - private String getFileName(String filePath) { - int pos = filePath.lastIndexOf("/"); - if (pos >= 0) { - return filePath.substring(pos + 1); - } - - return filePath; - } - - private ResponseEntity buildResource(InputStream inputStream, MediaType contentType, HttpHeaders headers) { - return ResponseEntity.ok() - .headers(headers) -// .contentLength(file.length()) - .contentType(contentType) - .body(new InputStreamResource(inputStream)); - } - - private static MediaType getContentType(String filePath) { - int pos = filePath.lastIndexOf("."); - - if (pos >= 0) { - String fileExt = filePath.substring(pos + 1).toLowerCase(); - switch (fileExt) { - case "htm": - case "html": - case "css": - return MediaType.TEXT_HTML; - case "js": - return APPLICATION_JAVASCRIPT; - case "txt": - return MediaType.TEXT_PLAIN; - case "pdf": - return MediaType.APPLICATION_PDF; - case "xml": - return MediaType.TEXT_XML; - case "gif": - return MediaType.IMAGE_GIF; - case "jpeg": - case "jpg": - return MediaType.IMAGE_JPEG; - case "png": - return MediaType.IMAGE_PNG; - default: - return MediaType.APPLICATION_OCTET_STREAM; - } - } - - return MediaType.APPLICATION_OCTET_STREAM; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java deleted file mode 100644 index b0f1404..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java +++ /dev/null @@ -1,157 +0,0 @@ -package cc.smtweb.system.bpm.spring.controller; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.cache.redis.RedisManager; -import cc.smtweb.framework.core.session.SessionUtil; -import cc.smtweb.system.bpm.spring.dao.ImageAttachDao; -import cc.smtweb.system.bpm.util.FilePathGenerator; -import cc.smtweb.system.bpm.util.FilePathInfo; -import cc.smtweb.system.bpm.util.MemMultipartFile; -import cc.smtweb.system.bpm.util.ThumbImage; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.FileCopyUtils; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; -import cc.smtweb.system.bpm.spring.entity.FileDataVO; -import cc.smtweb.system.bpm.spring.entity.UploadDataVO; - -import javax.servlet.http.HttpServletRequest; -import java.io.*; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; - -@RestController -public class FileUploadController { - @Autowired - private FilePathGenerator filePathGenerator; - - @Autowired - private DbEngine dbEngine; - - @Autowired - private RedisManager redisManager; - - @Autowired - private ImageAttachDao imageAttachDao; - - // TODO: 权限处理,临时文件处理 - @PostMapping("/fs/upload/{path}") - public R upload(@RequestParam("file") MultipartFile file, @PathVariable("path") String path, - @RequestParam(value="thumb", required=false) String thumb, - @RequestParam(value="thumbHeight", required=false) Integer thumbHeight, - @RequestParam(value="commit", required=false) Boolean insert, - @RequestParam(value="keepName", required=false) Boolean keepName, - HttpServletRequest request - ) { - SessionUtil.checkSession(request, redisManager); - return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, insert, keepName); - } - - @PostMapping("/fs/uploadImage/{path}") - public R upload(@RequestBody FileDataVO data, @PathVariable("path") String path, - @RequestParam(value="thumb", required=false) String thumb, - @RequestParam(value="thumbHeight", required=false) Integer thumbHeight, - @RequestParam(value="commit", required=false) Boolean insert, - HttpServletRequest request) { - SessionUtil.checkSession(request, redisManager); - - MultipartFile file = MemMultipartFile.build(data.getData()); - if (file == null) { - return R.error("数据内容格式有错"); - } - - return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, insert, false); - } - - @PostMapping("/fs/uploadAvatar/{path}") - public R uploadAvatar(@RequestParam("file") MultipartFile file, @PathVariable("path") String path, - @RequestParam(value="size", required=false) Integer size, - @RequestParam(value="commit", required=false) Boolean insert, - @RequestParam(value="keepName", required=false) Boolean keepName, - HttpServletRequest request) { - SessionUtil.checkSession(request, redisManager); - return uploadFile(path, file, ThumbImage.TYPE_AVATAR, size, insert, keepName); - } - - // 保存文件和插入数据库数据 - @PostMapping("/fs/commit/{path}") - public R commit(@RequestParam("file") MultipartFile file, @PathVariable("path") String path, - @RequestParam(value="thumb", required=false) String thumb, - @RequestParam(value="thumbHeight", required=false) Integer thumbHeight, - @RequestParam(value="keepName", required=false) Boolean keepName, - HttpServletRequest request) { - SessionUtil.checkSession(request, redisManager); - return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, true, keepName); - } - - private R uploadFile(String path, MultipartFile file, int type, Integer size, Boolean insert, Boolean keepName) { - //获取上传时的文件名 - String fileName = file.getOriginalFilename(); - - //判断文件是否为空 - if(file.isEmpty() && fileName != null){ - return R.error("文件为空"); - } - - // 判断保持文件名不变 - FilePathInfo fileInfo = filePathGenerator.make(path, fileName, Boolean.TRUE.equals(keepName)); - - // 注意是路径+文件名 - File targetFile = new File(fileInfo.getFullFileName()); - - try(InputStream inputStream = file.getInputStream(); OutputStream outputStream = new FileOutputStream(targetFile)) { - // 最后使用资源访问器FileCopyUtils的copy方法拷贝文件 - FileCopyUtils.copy(inputStream, outputStream); - } catch (IOException e) { - //出现异常,则告诉页面失败 - return R.error("上传失败", e); - } - - // 生成缩略图 -// String contentType = file.getContentType(); - UploadDataVO data = new UploadDataVO(); - - data.setPath(fileInfo.getMysqlFilePath()); - data.setName(fileName); - data.setSize(file.getSize()); - data.setContentType(file.getContentType()); - data.setUrl(filePathGenerator.getFileUrl(fileInfo.getMysqlFilePath())); - - if (type == ThumbImage.TYPE_THUMB || type == ThumbImage.TYPE_AVATAR) { - try { - imageAttachDao.makeThumb(data, type == ThumbImage.TYPE_THUMB, targetFile, size); - } catch (IOException e) { - return R.error("生成缩略图失败", e); - } - } - - if (Boolean.TRUE.equals(insert)) { - Long id = dbEngine.nextId(); - Timestamp now = new Timestamp(System.currentTimeMillis()); - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); - - dbEngine.update("insert into sw_user.sys_attach(attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time) values(?, ?, ?, ?, ?, ?)", - id, data.getName(), data.getPath(), data.getContentType(), data.getSize(), sdf.format(now)); - - data.setId(id); - } - - return R.success(data); - } - - // TODO: 修改为安全的后台删除方式 - @PostMapping("/fs/remove") - public R remove(@RequestParam(value="filePath") String filePath, HttpServletRequest request) { - SessionUtil.checkSession(request, redisManager); - - File file = new File(filePathGenerator.getFileDiskPath(filePath)); - if (file.exists() && file.isFile()) { - if (file.delete()) { - R.success(filePath); - } - } - - return R.success(); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java deleted file mode 100644 index 322d293..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java +++ /dev/null @@ -1,63 +0,0 @@ -package cc.smtweb.system.bpm.spring.dao; - -import cc.smtweb.system.bpm.util.ThumbImage; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Service; -import cc.smtweb.system.bpm.spring.entity.UploadDataVO; - -import java.io.File; -import java.io.IOException; - -@Service -public class ImageAttachDao { - public static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; - - public void makeThumb(UploadDataVO data, boolean isThumb, File targetFile, Integer size) throws IOException { - boolean imageType = false; - String fileName = data.getName(); - String contentType = data.getContentType(); - - if (contentType.startsWith("image/")) { - imageType = true; - } else if (contentType.equals(APPLICATION_OCTET_STREAM)) { - String fileExt = fileName.substring(fileName.lastIndexOf(".")); - - if (StringUtils.isNotEmpty(fileExt)) { - switch (fileExt.toLowerCase()) { - case ".jpg": - case ".jpeg": - contentType = "image/jpg"; - imageType = true; - break; - case ".gif": - contentType = "image/gif"; - imageType = true; - break; - case ".png": - contentType = "image/png"; - imageType = true; - break; - default: - break; - } - - if (imageType) { - data.setContentType(contentType); - } - } - } - - if (imageType) { - int thumbHeight = 80; - if (size != null) { - thumbHeight = (size > 500) ? 500 : size; - } - - ThumbImage thumbImage = new ThumbImage(); - - thumbImage.makeThumb(isThumb, targetFile, thumbHeight); - data.setWidth(thumbImage.getImageWidth()); - data.setHeight(thumbImage.getImageHeight()); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java deleted file mode 100644 index 166e76b..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java +++ /dev/null @@ -1,114 +0,0 @@ -package cc.smtweb.system.bpm.spring.dao; - -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.system.bpm.spring.entity.AttachPathPO; -import cc.smtweb.system.bpm.util.FilePathGenerator; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.yaml.snakeyaml.util.UriEncoder; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Service -public class SysAttachDao { - @Autowired - private FilePathGenerator filePathGenerator; - - @Autowired - private DbEngine dbEngine; - - /** - * 获取文件本地文件路径 - * - * @param filePath 相对路径 - * @return 本地文件全路径 - */ - public String getDiskPath(String filePath) { - return filePathGenerator.getFileDiskPath(filePath); - } - - /** - * 获取访问文件的URL地址 - * - * @param filePath 文件相对路径 - * @return 文件URL地址 - */ - public String getFileUrl(String filePath) { - return filePathGenerator.getFileUrl(filePath); - } - - /** - * 获取访问文件的URL地址 - * - * @param filePath 文件相对路径 - * @param filePath 文件名 - * @return 文件URL地址 - */ - public String getFileUrl(String filePath, String fileName) { - return "/fs/download?path=" + UriEncoder.encode(filePath) + "&name=" + UriEncoder.encode(fileName); - } - - public AttachPathPO get(Long id) { - if (id != null) { - return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?", - AttachPathPO.class, id); - } - - return null; - } - - // 删除文件记录和文件 - public void remove(Long fileId) { -// if (id != null) { -// return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?", -// AttachPathPO.class, id); -// } -// -// return null; - } - - // 删除文件 - public void remove(String filePath) { -// if (id != null) { -// return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?", -// AttachPathPO.class, id); -// } -// -// return null; - } - - public List list(Long[] ids) { - if (ids != null && ids.length > 0) { - return dbEngine.query("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id in( " - + StringUtils.join(ids, ",") + ")", - AttachPathPO.class); - } - - return null; - } - - public Map map(Long[] ids) { - List list = list(ids); - if (list != null && !list.isEmpty()) { - Map map = new HashMap<>(list.size()); - list.forEach((item) -> map.put(item.getAttachId(), item)); - - return map; - } - - return null; - } - - // 保持文件,删除临时文件记录,避免被定时删除 - public void retain(String filePath) { - - } - - // 保持文件,删除临时文件记录,避免被定时删除 - public void retain(Long fileId) { - - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java deleted file mode 100644 index 399bfc7..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java +++ /dev/null @@ -1,13 +0,0 @@ -package cc.smtweb.system.bpm.spring.entity; - -import lombok.Data; - -@Data -public class AttachPathPO { - private Long attachId; - private String attachName; - private String attachPath; - private String attachContentType; - private Long attachSize; - private Long attachCreate; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java deleted file mode 100644 index 5754e26..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java +++ /dev/null @@ -1,8 +0,0 @@ -package cc.smtweb.system.bpm.spring.entity; - -import lombok.Data; - -@Data -public class FileDataVO { - private String data; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java deleted file mode 100644 index d67aeb4..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.smtweb.system.bpm.spring.entity; - -import lombok.Data; - -@Data -public class UploadDataVO { - private Long id; - private Integer height; - private Integer width; - private long size; - private String path; - private String name; - private String contentType; - private String url; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java deleted file mode 100644 index 4dbeabb..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java +++ /dev/null @@ -1,120 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.FatalBeanException; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -import java.beans.PropertyDescriptor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class BeanUtil { - private BeanUtil() {} - - public static void mapToBean(SwMap source, Object target) { - mapToBean(source, target, null); - } - - private static void mapToBean(SwMap source, Object target, @Nullable Class editable, - @Nullable String... ignoreProperties) throws BeansException { - Assert.notNull(source, "Source must not be null"); - Assert.notNull(target, "Target must not be null"); - - Class actualEditable = target.getClass(); - if (editable != null) { - if (!editable.isInstance(target)) { - throw new IllegalArgumentException("Target class [" + target.getClass().getName() + - "] not assignable to Editable class [" + editable.getName() + "]"); - } - actualEditable = editable; - } - PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable); - List ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null); - - for (PropertyDescriptor targetPd : targetPds) { - Method writeMethod = targetPd.getWriteMethod(); - if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) { - Object value = source.get(targetPd.getName()); - - if (value == null || ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], value.getClass())) { - try { - if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { - writeMethod.setAccessible(true); - } - writeMethod.invoke(target, value); - } catch (Throwable ex) { - throw new FatalBeanException( - "Could not copy property '" + targetPd.getName() + "' from source to target", ex); - } - } - } - } - } - - public static void beanToMap(Object source, SwMap target, @Nullable String... ignoreProperties) throws BeansException { - Assert.notNull(source, "Source must not be null"); - Assert.notNull(target, "Target must not be null"); - - List ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null); - - PropertyDescriptor[] sourcePds = BeanUtils.getPropertyDescriptors(source.getClass()); - - for (PropertyDescriptor sourcePd: sourcePds) { - if (ignoreList == null || !ignoreList.contains(sourcePd.getName())) { -// PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getKey()); -// if (sourcePd != null) { - Method readMethod = sourcePd.getReadMethod(); - if (readMethod != null) { - try { - if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { - readMethod.setAccessible(true); - } - Object value = readMethod.invoke(source); - target.put(sourcePd.getName(), value); - } - catch (Throwable ex) { - throw new FatalBeanException( - "Could not copy property '" + sourcePd.getName() + "' from source to target", ex); - } - } -// } - } - } - } - - public static List toBeanList(List bodyList, Class clazz) { - List beans = new ArrayList<>(bodyList.size()); - try { - for (SwMap body: bodyList) { - Object bean = clazz.newInstance(); - BeanUtil.mapToBean(body, bean); - beans.add(bean); - } - } catch (InstantiationException | IllegalAccessException e) { - throw new SwException(e); - } - return beans; - } - - public static List toMapList(List beans) { - List bodyList = null; - if (beans != null) { - bodyList = new ArrayList<>(beans.size()); - for (Object bean: beans) { - SwMap body = new SwMap(); - beanToMap(bean, body); - bodyList.add(body); - } - } - - return bodyList; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenUtil.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenUtil.java deleted file mode 100644 index c930682..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenUtil.java +++ /dev/null @@ -1,111 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import org.apache.commons.lang3.StringUtils; - -public class CodeGenUtil { - private CodeGenUtil() { - } - - /*** - * 下划线命名转为驼峰命名 - * - * @param para - * 下划线命名的字符串 - */ - public static String underlineToHump(String para) { - StringBuilder result = new StringBuilder(); - String[] a = para.split("_"); - for (String s : a) { - if (result.length() == 0) { - result.append(s.toLowerCase()); - } else { - result.append(s.substring(0, 1).toUpperCase()); - result.append(s.substring(1).toLowerCase()); - } - } - return result.toString(); - } - - /*** - * 下划线命名转为大写驼峰命名 - * 大驼峰式命名法(upper camel case) - * - * @param para - * 下划线命名的字符串 - */ - public static String underlineToUpperHump(String para) { - StringBuilder result = new StringBuilder(); - String[] a = para.split("_"); - for (String s : a) { - result.append(s.substring(0, 1).toUpperCase()); - result.append(s.substring(1).toLowerCase()); - } - return result.toString(); - } - - /*** - * 驼峰命名转为下划线命名 - * - * @param para - * 驼峰命名的字符串 - */ - public static String humpToUnderline(String para) { - return humpTo(para, "_"); - } - - private static String humpTo(String para, String splitChar) { - StringBuilder sb = new StringBuilder(para); - //偏移量,第i个下划线的位置是 当前的位置+ 偏移量(i-1),第一个下划线偏移量是0 - int temp = 0; - for (int i = 0; i < para.length(); i++) { - if (Character.isUpperCase(para.charAt(i))) { - sb.insert(i + temp, splitChar); - temp += 1; - } - } - return sb.toString().toLowerCase(); - } - - /*** - * 驼峰命名转为横线线命名 - * - * @param para - * 驼峰命名的字符串 - */ - public static String humpToDash(String para) { - return humpTo(para, "-"); - } - - /** - * 大驼峰转小驼峰 - */ - public static String toLowerHump(String name) { - if (StringUtils.isNotBlank(name)) { - return Character.toLowerCase(name.charAt(0)) + name.substring(1); - } - - return ""; - } - - /** - * 小驼峰转大驼峰 - */ - public static String toUpperHump(String name) { - if (StringUtils.isNotBlank(name)) { - return Character.toUpperCase(name.charAt(0)) + name.substring(1); - } - - return ""; - } - - public static String getBeanName(String tableName) { - StringBuilder result = new StringBuilder(); - String[] a = tableName.split("_"); - for (int i = 1, len = a.length; i < len; i++) { - String s = a[i]; - result.append(s.substring(0, 1).toUpperCase()); - result.append(s.substring(1).toLowerCase()); - } - return result.toString(); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java deleted file mode 100644 index c8a0fbf..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java +++ /dev/null @@ -1,201 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import freemarker.template.Configuration; -import freemarker.template.Template; -import freemarker.template.TemplateMethodModelEx; -import freemarker.template.TemplateModelException; -import org.apache.commons.io.IOUtils; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 2022/6/8 15:36 - * 模板生成代码 - */ -public class CodeGenerator { - private final static String KEY_MODEL = "model"; - private final static String TEMPLATE_JAVA_BEAN = "java_bean"; - private final static String TEMPLATE_JAVA_CACHE = "java_cache"; - private final static String TEMPLATE_JAVA_SERVICE = "java_service"; - private final static String TEMPLATE_JS_EVENT = "js_event"; - private static CodeGenerator instance = null; - - private Configuration configuration = null; - - private final String encode = org.apache.commons.codec.CharEncoding.UTF_8; - //模板文件所在目录 -// private String templatesDir; - - //模板信息 - private SwMap mapTemplate; - - protected CodeGenerator() { -// templatesDir = this.getClass().getResource("/static/template").getPath(); - mapTemplate = YamlUtil.readValue(this.getClass().getResourceAsStream("/static/template/index.yaml"), SwMap.class); - configuration = new Configuration(Configuration.VERSION_2_3_31); - try { - configuration.setClassForTemplateLoading(this.getClass(), "/static/template/"); -// configuration.setDirectoryForTemplateLoading(new File(templatesDir)); - configuration.setClassicCompatible(true); - configuration.setDefaultEncoding(encode); - configuration.setOutputEncoding(encode); - } catch (Exception e) { - e.printStackTrace(); - throw new SwException(e); - } - } - - //页面设计的模板信息 - public List> getModelTemplates() { - return (List>)mapTemplate.get(KEY_MODEL); - } - - private void initModel(Map model) { - model.put("newId", new PKGenerator()); - } - - public void generate(Map model, String templateName, Writer writer) { - try { - initModel(model); - Template template = configuration.getTemplate(templateName, encode); - template.setOutputEncoding(encode); - template.process(model, writer); - writer.close(); - } catch (Exception e) { - e.printStackTrace(); - throw new SwException(e); - } - } - - - public void generate(Map model, String templateName, String fileName) { - File file = new File(fileName); - if (file.exists()) file.delete(); - FileOutputStream out = null; - try { - file.createNewFile(); - out = new FileOutputStream(fileName); - - initModel(model); - Template template = configuration.getTemplate(templateName + ".ftl", StandardCharsets.UTF_8.toString()); - template.setOutputEncoding(encode); - template.process(model, new OutputStreamWriter(out, encode)); - out.flush(); - } catch (Exception e) { - throw new SwException("生成代码失败!", e); - } finally { - IOUtils.closeQuietly(out); - } - } - - public String generate(Map model, String templateName) { - StringWriter out = new StringWriter(); - generate(model, templateName + ".ftl", out); - return out.getBuffer().toString(); - } - - public void generateBean(Map model, String fileName) { - generate(model, TEMPLATE_JAVA_BEAN, fileName); - } - - public void generateCache(Map model, String fileName) { - generate(model, TEMPLATE_JAVA_CACHE, fileName); - } - - public void generateService(Map model, String fileName) { - generate(model, TEMPLATE_JAVA_SERVICE, fileName); - } - - public void generateJsEvent(Map model, String fileName) { - generate(model, TEMPLATE_JS_EVENT, fileName); - } - - - /** - * 获取单实例 - * - * @return - */ - public static CodeGenerator getInstance() { - if (instance == null) { - synchronized (CodeGenerator.class) { - instance = new CodeGenerator(); - } - } - return instance; - } - - static class PKGenerator implements TemplateMethodModelEx { - @Override - public Object exec(List list) throws TemplateModelException { - return String.valueOf(DbEngine.getInstance().nextId()); -// return DbEngine.getInstance().nextId(); - } - } - - - /* - {param:{pa:"aaa"}, - layout:{ - c1:[{type:"list", dataset:"ds123", fields:[{field:"", dataset:""}], cfilters:[{}]}] - } - */ - public static void main(String[] args) { - StringWriter out = new StringWriter(); - SwMap map = new SwMap(); - SwMap param = new SwMap(); - param.put("pa", "aaaaa"); - map.put("param", param); - - SwMap layout = new SwMap(); - map.put("layout", layout); - List groups = new ArrayList<>(); - layout.put("c1", groups); - - SwMap area = new SwMap(); - groups.add(area); - area.put("type", "list"); - area.put("dataset", "ds123"); - - List fields = new ArrayList<>(); - area.put("fields", fields); - SwMap field = new SwMap(); - field.put("field", "f123"); - field.put("dataset", "ds123"); - field.put("label", "字段123"); - fields.add(field); - - field = new SwMap(); - field.put("field", "f121"); - field.put("label", "字段121"); - field.put("dataset", "ds123"); - fields.add(field); - - field = new SwMap(); - field.put("field", "f122"); - field.put("label", "字段122"); - field.put("dataset", "ds123"); - fields.add(field); - - List filters = new ArrayList<>(); - area.put("cfilters", filters); - field = new SwMap(); - field.put("field", "f122"); - field.put("dataset", "ds123"); - field.put("label", "字段122"); - field.put("maxlength", 20); - filters.add(field); - - map.put("title", "thisIsATest!"); - map.put("newId", new PKGenerator()); - CodeGenerator.getInstance().generate(map, "model_card.ftl", out); - System.out.println(out.getBuffer().toString()); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java deleted file mode 100644 index 34e841b..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java +++ /dev/null @@ -1,106 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import cc.smtweb.framework.core.util.DateUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.time.DateUtils; - -import java.io.File; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.Random; - -/** - * 动态文件〈文件路径〉 - * - * @author kevin - * @since 1.0.0 - */ -@Slf4j -public class FileDynPath extends FileFixPath { - // 目录允许的最大文件数量,避免批量导入文件时文件太多 - private static final int MAX_FILE_COUNT = 2000; - private static final int MAX_DIR_COUNT = 100000; - private long startTime; - private long endTime; - private final SimpleDateFormat sdf; - // 文件数量 - private int fileCount; - // 目录子索引 - private int pathIndex; - - public FileDynPath(String rootPath, String typeDir, SimpleDateFormat sdf) { - super(rootPath, typeDir); - this.sdf = sdf; - } - - /** - * 返回日期路径字符串 - */ - @Override - public FilePathInfo makeDatePath(long fileId, String fileExt) { - long now = System.currentTimeMillis(); - String fileName; - - // 如果不在就需要重新创建子目录 - if (now < startTime || now >= endTime) { - startTime = DateUtil.getTimesmorning(now); - endTime = startTime + DateUtils.MILLIS_PER_DAY; - - this.path = this.typeDir + "/" + sdf.format(new Timestamp(now)); - createFolder(rootPath + this.path); - } - - // 如果文件数量太大就需要创建新子目录 - while (this.fileCount >= MAX_FILE_COUNT) { - this.pathIndex++; - if(this.pathIndex > MAX_DIR_COUNT) { - throw new RuntimeException("dir is two many"); - } - - createFolder(rootPath + getSubPath()); - } - - Random random = new Random(); - int randomId = random.nextInt(Integer.MAX_VALUE); - - fileName = Long.toHexString(fileId) + "_" + Integer.toHexString(randomId) + fileExt; - - return new FilePathInfo(rootPath, getSubPath(), now, fileName, fileId); - } - - private String getSubPath() { - if (this.pathIndex > 0) { - return String.format("%s%02d/%04d", this.path, MAX_DIR_COUNT / 1000, this.pathIndex % 1000); - } - - return this.path; - } - - private boolean createFolder(String path) { - File file = new File(path); - if (file.exists()) { - if (!file.isDirectory()) { - return false; - } - - File[] list = file.listFiles(); - if (list != null) { - this.fileCount = list.length; - } else { - this.fileCount = 0; - } - - return true; - } - - if (!file.mkdirs()) { - log.error("unable to create folders {}.", rootPath + this.path); - return false; - } - - log.debug("create folders {}.", file); - this.fileCount = 0; - - return true; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FileFixPath.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FileFixPath.java deleted file mode 100644 index 5838559..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FileFixPath.java +++ /dev/null @@ -1,51 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import lombok.extern.slf4j.Slf4j; - -import java.io.File; - -/** - * 〈文件路径〉 - * - * @author kevin - * @since 1.0.0 - */ -@Slf4j -public class FileFixPath { - protected String path; - protected String rootPath; - protected String typeDir; - - public FileFixPath(String rootPath, String typeDir) { - this.rootPath = rootPath; - this.typeDir = typeDir; - } - - public FilePathInfo makeDatePath(long fileId, String fileName) { - long now = System.currentTimeMillis(); - this.path = this.typeDir + "/"; - createFolder(rootPath + this.path); - - return new FilePathInfo(rootPath, this.path, now, fileName, fileId); - } - - private boolean createFolder(String path) { - File file = new File(path); - if (file.exists()) { - if (!file.isDirectory()) { - return false; - } - - return true; - } - - if (!file.mkdirs()) { - log.error("unable to create folders {}.", rootPath + this.path); - return false; - } - - log.debug("create folders {}.", file); - - return true; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java deleted file mode 100644 index 4d307ba..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java +++ /dev/null @@ -1,132 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import java.text.SimpleDateFormat; -import java.util.HashMap; -import java.util.Map; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.apache.tika.mime.MimeType; -import org.apache.tika.mime.MimeTypeException; -import org.apache.tika.mime.MimeTypes; -import org.springframework.web.multipart.MultipartFile; -import cc.smtweb.framework.core.db.jdbc.IdGenerator; - -/** - * 文件名生成规则 subDir/[yyyymm]/[d]/[hex(fileid)]_[hex(rand)].[fileExt] 如果文件是图片格式,会生成缩略图,文件名会直接添加.thumb.jpg后缀 规则参数 yyyymm: - * 时间的年月,固定6位字符。如200505 d: 时间的日期,值范围1~31。如5 fileid: 上传文件的ID,hex(int64) rand: 防盗链随机数,hex(int32)。 fileExt: 文件扩展名。 - */ -@Slf4j -public class FilePathGenerator { - - public static final String THUMB_FILE_EXT = ".thumb.jpg"; - // 文件时间是否作为PK - private SimpleDateFormat sdf; - @Getter - private String rootPath; - private Map fileFxPathMap = new HashMap<>(); - private Map fileDynPathMap = new HashMap<>(); - private String fileUrl; - private IdGenerator idGenerator; - - public FilePathGenerator(String rootPath, String fileUrl, IdGenerator idGenerator) { - this.fileUrl = fixEnd(fileUrl); - this.idGenerator = idGenerator; - this.rootPath = fixEnd(rootPath); - - sdf = new SimpleDateFormat("yyyyMM/dd/"); - } - - private static String fixEnd(String path) { - if (path.endsWith("/") || path.endsWith("\\")) { - return path; - } else { - return path + "/"; - } - } - - /** - * 生成文件路径,根据日期分目录存储 - * - * @param subPath 子目录,区分不同应用的文件 - * @param originalFileName 原始的文件名,用于提取扩展名用 - * @return 文件路径信息类 - */ - public FilePathInfo make(String subPath, String originalFileName) { - return make(subPath, originalFileName, null, false); - } - - public FilePathInfo make(String subPath, String originalFileName, boolean keepName) { - return make(subPath, originalFileName, null, keepName); - } - /** - * 生成文件路径,根据日期分目录存储 - * - * @param subPath 子目录,区分不同应用的文件 - * @param multipartFile 上传文件流,用于提取扩展名用 - * @return 文件路径信息类 - */ - public FilePathInfo make(String subPath, MultipartFile multipartFile) { - return make(subPath, multipartFile.getOriginalFilename(), multipartFile.getContentType(), false); - } - - private synchronized FilePathInfo make(String subPath, String originFileName, String contentType, boolean keepName) { - if (keepName) { - FileFixPath filePathSub = fileFxPathMap.get(subPath); - if (filePathSub == null) { - filePathSub = new FileFixPath(this.rootPath, subPath); - fileFxPathMap.put(subPath, filePathSub); - } - - return filePathSub.makeDatePath(this.idGenerator.nextId(), originFileName); - } else { - FileDynPath filePathSub = fileDynPathMap.get(subPath); - if (filePathSub == null) { - filePathSub = new FileDynPath(this.rootPath, subPath, sdf); - fileDynPathMap.put(subPath, filePathSub); - } - - return filePathSub.makeDatePath(this.idGenerator.nextId(), ext(originFileName, contentType)); - } - } - - private static String ext(String filename, String contentType) { - int index = filename.lastIndexOf("."); - - if (index == -1) { - if (contentType != null) { - MimeTypes allTypes = MimeTypes.getDefaultMimeTypes(); - try { - MimeType jpeg = allTypes.forName(contentType); - return jpeg.getExtension(); - } catch (MimeTypeException e) { - log.error(contentType, e); - } - } - - return ""; - } - - return filename.substring(index); - } - - // 根据数据库存储文件路径获取URL - public String getFileUrl(FilePathInfo filePathInfo) { - return this.fileUrl + filePathInfo.getMysqlFilePath(); - } - - // 根据数据库存储文件路径获取URL - public String getFileUrl(String mysqlFilePath) { - return this.fileUrl + mysqlFilePath; - } - - // 根据数据库存储文件路径获取磁盘存储路径 - public String getFileDiskPath(String mysqlFilePath) { - return this.rootPath + mysqlFilePath; - } - - // 获取下载路径前缀 - public String getDownloadUrl() { - return this.fileUrl; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java deleted file mode 100644 index de9557e..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java +++ /dev/null @@ -1,48 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import lombok.Getter; - - -/** - * 数据库需要存储 - * fileId, fileTime, subPath + fileName - */ -@Getter -public class FilePathInfo { - // 文件ID - private long fileId; - // 文件创建时间,数据库需要存储 - private long fileTime; - // 文件子路径 - private String subPath; - // 文件名 - private String fileName; - // 本地根路径 - private String rootPath; - - public FilePathInfo(String rootPath, String subPath, long fileTime, String fileName, long fileId) { - this.rootPath = rootPath; - this.subPath = subPath; - this.fileTime = fileTime; - this.fileName = fileName; - this.fileId = fileId; - } - - /** - * 获取本地需要存储的文件全路径 - */ - public String getFullFileName() { - return getDiskFilePath(); - } - - public String getDiskFilePath() { - return this.rootPath + subPath + fileName; - } - - /** - * 获取数据库存储需要的文件全路径 - */ - public String getMysqlFilePath() { - return subPath + fileName; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java deleted file mode 100644 index ec08884..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import java.util.List; - -/** - * 树型节点句柄 - * @author xkliu - */ -public interface ITreeDataHandler { - /** - * 获取ID - * @param node 节点 - * @return 节点ID - */ - Long getId(T node); - - /** - * 获取上级ID - * @param node 当前节点 - * @return 上级ID - */ - Long getParentId(T node); - -// void addChild(IWebTreeVO item); - - /** - * 获取下级对象列表 - * @param node 当前节点 - * @return 下级对象列表 - */ - List getChildren(T node); - - /** - * 设置下级对象列表 - * @param children 下级对象列表 - */ - void setChildren(T node, List children); - - /** - * 是否强行添加未找到上级的错误节点到顶级 - * @param node 通过node有parentId值,但未找到对应上级节点 - * @return 是否强行添加错误节点到顶级 - */ - default boolean forceAdd(T node) { return false; } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java deleted file mode 100644 index 2e43c00..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java +++ /dev/null @@ -1,6 +0,0 @@ -package cc.smtweb.system.bpm.util; - -public interface ITreeDataLevelHandler extends ITreeDataHandler { - int getLevel(T t); - void setLevel(T t, int level); -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java deleted file mode 100644 index 7ef1883..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java +++ /dev/null @@ -1,73 +0,0 @@ -package cc.smtweb.system.bpm.util; - - -import cc.smtweb.framework.core.common.SwMap; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; -import lombok.Data; -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 14-2-14 上午10:13 - * 读取Idea信息的工具类 - */ -public class IdeaUtil { - //获取工程中的Module文件 - public static Map getModules(String ideaPath) { - Map map = new HashMap<>(); - IdeaProject project = XmlUtil.readValue(new File(ideaPath + "/.idea/modules.xml"), IdeaProject.class); - if (project == null || project.component == null || project.component.modules == null) return map; - for (Module module: project.component.modules) { - String s = module.filepath.replace("$PROJECT_DIR$", ideaPath); - File f = new File(s); - s = f.getName(); - int i = s.lastIndexOf("."); - if (i >= 0) s = s.substring(0, i); - map.put(s, f.getParent()); - } - return map; - } - - - public static void main(String args[]) throws Exception { - Map list = getModules("e:/jujia/git/6.0/smtweb2/smtweb-framework"); - for (Map.Entry s : list.entrySet()) { - System.out.println(s.getKey() + "=" + s.getValue()); - } - } - - @Data - @JsonIgnoreProperties(ignoreUnknown = true) - @JacksonXmlRootElement(localName = "project") - public static class IdeaProject { - private Component component; - - } - - @Data - @JsonIgnoreProperties(ignoreUnknown = true) - static class Component { - @JacksonXmlElementWrapper(localName = "modules") - @JacksonXmlProperty(localName = "module") - public List modules; - } - - @Data - @JsonIgnoreProperties(ignoreUnknown = true) - static class Module { - @JacksonXmlProperty - private String fileurl; - @JacksonXmlProperty - private String filepath; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java deleted file mode 100644 index 33f5681..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java +++ /dev/null @@ -1,79 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import org.apache.commons.codec.binary.Base64; -import org.springframework.web.multipart.MultipartFile; - -import java.io.*; - -public class MemMultipartFile implements MultipartFile { - private static final String DATA_IMAGE = "data:image/"; - private byte[] data; - private String contentType; - private String filename; - - public static MemMultipartFile build(String dataUrl) { - if (dataUrl != null && dataUrl.startsWith(DATA_IMAGE)) { - // data:image/png;base64, - int pos1 = dataUrl.indexOf(';', DATA_IMAGE.length()); - int pos2 = dataUrl.indexOf(',', DATA_IMAGE.length()); - if (pos1 > 0 && pos2 > pos1) { - byte[] data = Base64.decodeBase64(dataUrl.substring(pos2)); - - if (data != null) { - String contentType = dataUrl.substring(5, pos1); - return new MemMultipartFile(contentType.replace('/', '.'), contentType, data); - } - } - } - - return null; - } - - private MemMultipartFile(String filename, String contentType, byte[] data) { - this.data = data; - this.contentType = contentType; - this.filename = filename; - } - - @Override - public String getName() { - return "data"; - } - - @Override - public String getOriginalFilename() { - return filename; - } - - @Override - public String getContentType() { - return contentType; - } - - @Override - public boolean isEmpty() { - return data.length == 0; - } - - @Override - public long getSize() { - return data.length; - } - - @Override - public byte[] getBytes() throws IOException { - return data; - } - - @Override - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(data); - } - - @Override - public void transferTo(File file) throws IOException, IllegalStateException { - try(FileOutputStream os = new FileOutputStream(file)) { - os.write(data); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java deleted file mode 100644 index e3b2d22..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java +++ /dev/null @@ -1,109 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import java.awt.Color; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.List; - -import javax.imageio.ImageIO; - -import lombok.Getter; -import net.coobird.thumbnailator.Thumbnails; -import net.coobird.thumbnailator.geometry.Positions; -import net.coobird.thumbnailator.resizers.configurations.Antialiasing; -import net.sf.image4j.codec.ico.ICODecoder; -import org.apache.commons.lang3.StringUtils; - -/** - * 缩略图生成工具 - * @author xkliu - */ -@Getter -public class ThumbImage { - // 图片处理方式 - public static final int TYPE_DEFAULT = 1; - public static final int TYPE_THUMB = 2; - public static final int TYPE_AVATAR = 3; - - private int imageWidth; - private int imageHeight; - - public static int type(String thumb) { - // 解决历史遗留boolean类型 - if (StringUtils.isBlank(thumb) || "false".equalsIgnoreCase(thumb)) { - return TYPE_DEFAULT; - } - - if ("true".equalsIgnoreCase(thumb)) { - return TYPE_THUMB; - } - - return Integer.parseInt(thumb); - } - - public void makeThumb(boolean isThumb, File file, int size) throws IOException { - makeThumb(file, size, size, isThumb); - } - // 后台等比压缩后大小最好控制在20k以内 - public void makeThumb(File file, int w, int h, boolean keepAspectRatio) throws IOException { - String fileName = file.getName().toLowerCase(); - - BufferedImage image; - - if (fileName.endsWith(".ico")) { - List images = ICODecoder.read(file); - image = images.get(images.size() - 1); - } else { - image = ImageIO.read(file); - } - - imageWidth = image.getWidth(); - imageHeight = image.getHeight(); - - if (fileName.endsWith(".png") || fileName.endsWith(".gif")) { - // 把透明的图填充白色背景 - BufferedImage newBufferedImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); - newBufferedImage.createGraphics().drawImage(image, 0, 0, Color.WHITE, null); - image = newBufferedImage; - } - - Thumbnails.Builder builder = Thumbnails.of(image); - - if (keepAspectRatio) { - if (h > 0) { - // 高度为基准调整宽度到达原图缩放比例 - int imageR = imageWidth * 1000 / imageHeight; - w = h * imageR / 1000; - } else { - // 宽度为基准调整宽度到达原图缩放比例 - int imageR = imageHeight * 1000 / imageWidth; - h = w * imageR / 1000; - } - -// int r = w * 1000 / h; -// int imageR = imageWidth * 1000 / imageHeight; -// if (r != imageR) { -// w = imageHeight * r / 1000; -// } - } else { - int r = w * 1000 / h; - int imageR = imageWidth * 1000 / imageHeight; - - if (r != imageR) { - int width = imageWidth; - int height = imageHeight; - if (r > imageR) { - width = imageHeight * r / 1000; - } else { - height = imageWidth * 1000 / r; - } - - builder.sourceRegion(Positions.CENTER, width, height); - } - } - - builder.size(w, h).antialiasing(Antialiasing.ON).outputFormat("jpg").outputQuality(0.9) - .toFile(file.getAbsolutePath() + FilePathGenerator.THUMB_FILE_EXT); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java deleted file mode 100644 index 7c1e490..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java +++ /dev/null @@ -1,217 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -/** - * 树结构数据创建器 - * @author xkliu - */ -public class TreeDataUtil { - private TreeDataUtil(){} - - public static boolean longEquals(Long l1, Long l2) { - if (l1 != null) { - return l1.equals(l2); - } - - return l2 == null; - } - - private static boolean findAndAdd(T parent, T item, ITreeDataHandler handler) { - if (longEquals(handler.getId(parent), handler.getParentId(item))) { - addChild(parent, item, handler); - return true; - } else { - List children = handler.getChildren(parent); - - if (children != null) { - for (T child : children) { - if (findAndAdd(child, item, handler)) { - return true; - } - } - } - } - - return false; - } - - private static boolean findAndAddLevel(T parent, T item, ITreeDataLevelHandler handler) { - if (longEquals(handler.getId(parent), handler.getParentId(item))) { - addChildLevel(parent, item, handler); - return true; - } else { - List children = handler.getChildren(parent); - - if (children != null) { - for (T child : children) { - if (findAndAddLevel(child, item, handler)) { - return true; - } - } - } - } - - return false; - } - - private static void addChild(T parent, T item, ITreeDataHandler handler) { - List children = handler.getChildren(parent); - if (children == null) { - children = new ArrayList<>(); - handler.setChildren(parent, children); - } - - children.add(item); - } - - private static void addChildLevel(T parent, T item, ITreeDataLevelHandler handler) { - List children = handler.getChildren(parent); - if (children == null) { - children = new ArrayList<>(); - handler.setChildren(parent, children); - } - - updateLevel(item, handler.getLevel(parent) + 1, handler); - children.add(item); - } - - private static void updateLevel(T parent, int parentLevel, ITreeDataLevelHandler handler) { - handler.setLevel(parent, parentLevel); - List children = handler.getChildren(parent); - if (children != null) { - int level = parentLevel + 1; - for (T t: children) { - handler.setLevel(t, level); - updateLevel(t, level, handler); - } - } - } - - // 读取树结构 - public static List buildTree(T root, List list, ITreeDataHandler handler) { - if (list != null) { - for (T item: list) { - if (!findAndAdd(root, item, handler)) { - for (T it: list) { - if (longEquals(handler.getId(it), handler.getParentId(item))) { - addChild(it, item, handler); - item = null; - break; - } - } - - // not find item parent - if (item != null && handler.forceAdd(item)) { - addChild(root, item, handler); - } - } - } - } - - return handler.getChildren(root); - } - - // 读取树结构 - public static List buildLevelTree(T root, List list, ITreeDataLevelHandler handler) { - if (list != null) { - handler.setLevel(root, 0); - for (T item: list) { - if (!findAndAddLevel(root, item, handler)) { - for (T it: list) { - if (longEquals(handler.getId(it), handler.getParentId(item))) { - addChildLevel(it, item, handler); - item = null; - break; - } - } - - // not find item parent - if (item != null && handler.forceAdd(item)) { - addChildLevel(root, item, handler); - } - } - } - } - - return handler.getChildren(root); - } - - public static T findParent(T root, Long id, int treeLevel, ITreeDataLevelHandler handler) { - T result = findParentInLevel(root, id, treeLevel, handler); - if (result != null && handler.getLevel(result) != treeLevel) { - result = null; - } - - return result; - } - - private static T findParentInLevel(T parent, Long id, int treeLevel, ITreeDataLevelHandler handler) { - List children = handler.getChildren(parent); - if (children != null) { - for (T child: children) { - if (id.equals(handler.getId(child))) { - return parent; - } else { - T find = findParentInLevel(child, id, treeLevel - 1, handler); - if (find != null) { - if (treeLevel > 0) { - return find; - } else { - return parent; - } - } - } - } - } - - return null; - } - - public static T findParent(T root, Long id,ITreeDataHandler handler) { - List children = handler.getChildren(root); - if (children != null) { - for (T child: children) { - if (id.equals(handler.getId(child))) { - return root; - } else { - T find = findParent(child, id, handler); - if (find != null) { - return find; - } - } - } - } - - return null; - } - - public static T find(T root, Long id, ITreeDataHandler handler) { - List children = handler.getChildren(root); - if (children != null) { - for (T child: children) { - if (id.equals(handler.getId(child))) { - return child; - } else { - T find = find(child, id, handler); - if (find != null) { - return find; - } - } - } - } - - return null; - } - - public static void forEach(T node, ITreeDataHandler handler, Consumer action) { - List children = handler.getChildren(node); - if (children != null) { - for (T child: children) { - action.accept(child); - } - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java deleted file mode 100644 index 3235db6..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java +++ /dev/null @@ -1,88 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import cc.smtweb.framework.core.exception.JsonParseException; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import org.apache.commons.lang3.StringUtils; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class XmlUtil { - private static final XmlMapper OBJECT_MAPPER = new XmlMapper(); - - static { - OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); - OBJECT_MAPPER.enable(SerializationFeature.INDENT_OUTPUT); - } - - private XmlUtil() {} - - public static T readValue(String str, Class clazz) { - try { - if (StringUtils.isBlank(str)) { - return null; - } else { - return OBJECT_MAPPER.readValue(str, clazz); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to " + clazz + " type", e); - } - } - - public static T readValue(File file, Class clazz) { - try { - if (file == null || !file.exists()) { - return null; - } else { - return OBJECT_MAPPER.readValue(file, clazz); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to " + clazz + " type", e); - } - } - - public static T readValue(InputStream is, Class clazz) { - try { - if (is == null) { - return null; - } else { - return OBJECT_MAPPER.readValue(is, clazz); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this xml to " + clazz + " type", e); - } - } - - public static String writeValue(Object obj) { - try { - return OBJECT_MAPPER.writeValueAsString(obj); - } catch (JsonProcessingException e) { - throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); - } - } - - public static void writeValue(OutputStream outputStream, Object obj) { - try { - OBJECT_MAPPER.writeValue(outputStream, obj); - } catch (JsonProcessingException e) { - throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); - } catch (IOException e) { - throw new JsonParseException(e.getMessage(), e); - } - } - - public static void writeValue(File file, Object obj) { - try { - OBJECT_MAPPER.writeValue(file, obj); - } catch (JsonProcessingException e) { - throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e); - } catch (IOException e) { - throw new JsonParseException(e.getMessage(), e); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java deleted file mode 100644 index 24ebd47..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java +++ /dev/null @@ -1,112 +0,0 @@ -package cc.smtweb.system.bpm.util; - -import cc.smtweb.framework.core.exception.JsonParseException; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; -import org.apache.commons.lang3.StringUtils; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.introspector.Property; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.Tag; -import org.yaml.snakeyaml.representer.Representer; - -import java.io.*; -import java.nio.charset.StandardCharsets; - -public class YamlUtil { - private static final ObjectMapper OBJECT_MAPPER; - private static final Representer representer; - - static { - YAMLFactory yamlFactory = new YAMLFactory(); - -// yamlFactory.enable(YAMLGenerator.Feature.CANONICAL_OUTPUT); - yamlFactory.disable(YAMLGenerator.Feature.SPLIT_LINES); - yamlFactory.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES); - - OBJECT_MAPPER = new ObjectMapper(yamlFactory); - OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); - - // 生成yaml时忽略null属性 - representer = new Representer() { - @Override - protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) { - // if value of property is null, ignore it. - if (propertyValue == null) { - return null; - } - else { - return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); - } - } - }; - } - - private YamlUtil() {} - - public static T readValue(String str, Class clazz) { - try { - if (StringUtils.isBlank(str)) { - return null; - } else { - return OBJECT_MAPPER.readValue(str, clazz); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this json to " + clazz + " type", e); - } - } - - public static T readValue(File file, Class clazz) { - try { - return OBJECT_MAPPER.readValue(file, clazz); - } catch (Exception e) { - throw new JsonParseException("can't convert this json to " + clazz + " type", e); - } - } - - public static T readValue(InputStream is, Class clazz) { - try { - if (is == null) { - return null; - } else { - return OBJECT_MAPPER.readValue(is, clazz); - } - } catch (Exception e) { - throw new JsonParseException("can't convert this yaml to " + clazz + " type", e); - } - } - - public static String writeValue(Object obj) { - Yaml yaml = buildYaml(); - StringWriter sw = new StringWriter(); - yaml.dump(obj, sw); - return sw.toString(); - } - - private static Yaml buildYaml() { - Yaml result = new Yaml(representer); - - return result; - } - - public static void writeValue(OutputStream outputStream, Object obj) { - Yaml yaml = buildYaml(); - yaml.dump(obj, new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)); - } - - public static void writeValue(File file, Object obj) { - Yaml yaml = buildYaml(); - try(OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) { - yaml.dump(obj, out); -// OBJECT_MAPPER.writeValue(file, obj); - } catch (IOException e) { - throw new JsonParseException(e.getMessage(), e); - } - - -// StringWriter sw = new StringWriter(); -// System.out.println(sw.toString()); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java deleted file mode 100644 index 100114a..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java +++ /dev/null @@ -1,55 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.vo.ModelCatalog; - -import java.util.List; - -/** - * Created by Akmm at 2022/1/12 18:34 - */ -@SwCache(ident = "ASP_MODEL_CATALOG", title = "目录") -public class ModelCatalogCache extends AbstractCache { - public final static String CACHE_KEY = "prj"; - - public static ModelCatalogCache getInstance() { - return CacheManager.getIntance().getCache(ModelCatalogCache.class); - } - - public ModelCatalogCache() { - regList(SwConsts.KEY_PARENT_ID, k-> String.valueOf(k.getParentId())); - regList(CACHE_KEY, k-> k.getPrjId() + SwConsts.SPLIT_CHAR + k.getParentId()); - } - - @Override - protected String getId(ModelCatalog bean) { - return String.valueOf(bean.getId()); - } - - @Override - protected List loadAll() { - EntityDao dao = DbEngine.getInstance().findDao(ModelCatalog.class); - return dao.query(); - } - - public String getName(long id) { - ModelCatalog bean = get(id); - return bean != null ? bean.getName() : ""; - } - - public String getFullName(long id) { - ModelCatalog bean = get(id); - if (bean == null) return null; - StringBuilder sret = new StringBuilder(); - while (bean != null) { - sret.insert(0, "." + bean.getCode()); - bean = get(bean.getParentId()); - } - return sret.substring(1); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogService.java deleted file mode 100644 index 19cedf8..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogService.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.db.vo.ModelCatalog; -import cc.smtweb.framework.core.mvc.service.*; - -/** - * Created by Akmm at 2022/3/1 17:00 - * 项目服务类 - */ -@SwService -public class ModelCatalogService extends AbstractCompService { - @Override - protected AbstractHandler createHandler(String type) { - switch (type) { - case TYPE_LOAD: - return new DefaultLoadHandler(ModelCatalog.ENTITY_NAME); - case TYPE_SAVE: - return new DefaultSaveHandler<>(ModelCatalog.ENTITY_NAME); - case TYPE_DEL: - return new DefaultDelHandler<>(ModelCatalog.ENTITY_NAME); - case TYPE_LIST: - return new DefaultListHandler<>(ModelCatalog.ENTITY_NAME); - case TYPE_TREE: - return new ModelCatalogTreeHandler(); - } - return null; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java deleted file mode 100644 index 6ec3335..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java +++ /dev/null @@ -1,200 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelCatalog; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.AbstractTreeHandler; -import cc.smtweb.framework.core.mvc.service.TreeHelper; -import cc.smtweb.framework.core.session.UserSession; -import cc.smtweb.framework.core.util.CommUtil; -import cc.smtweb.system.bpm.web.design.form.ModelForm; -import cc.smtweb.system.bpm.web.design.form.ModelFormCache; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by Akmm at 2022/3/21 18:22 - */ -public class ModelCatalogTreeHandler extends AbstractTreeHandler { - //查询类型:0-目录;1-表定义;2-页面;3-控件;23-页面和控件 - private final static int TYPE_CATALOG = 0; - private final static int TYPE_TABLE = 1; - private final static int TYPE_PAGE = 2; - private final static int TYPE_WIDGET = 3; - private final static int TYPE_FORM = 23; - - private long prj_id;//所属项目 - private int type;//查询类型:0-目录;1-表定义;2-页面定义 - private boolean exc_empty;//排除空目录,type非目录时有效 - - private ModelCatalogTreeHelper mcTreeHelper = null; - - @Override - public void init(SwMap params, UserSession us) { - super.init(params, us); - type = params.readInt("type"); - prj_id = params.readLong("prj_id"); - exc_empty = params.readBool("exc_empty"); - mcTreeHelper = (ModelCatalogTreeHelper) TreeHelper.getTreeHelper(ModelCatalog.ENTITY_NAME, ModelCatalogTreeHelper.class); - } - - @Override - protected List getChildren(DefaultEntity bean) { - if (bean instanceof ModelCatalog) { - return super.getChildren(bean); - } - return null; - } - - @Override - protected List filterData() { - - EntityDao dao = DbEngine.getInstance().findDao(ModelCatalog.ENTITY_NAME); - String text = "%" + params.readString("text") + "%"; - List list = dao.queryWhere(" mc_prj_id=? and (mc_name like ? or mc_code like ?) order by mc_name", prj_id, text, text); - List listRet = new ArrayList<>(list); - - switch (type) { - case TYPE_TABLE: - EntityDao tabledao = DbEngine.getInstance().findDao(ModelTable.class); - List l = tabledao.queryWhere(" tb_prj_id=? and (tb_name like ? or tb_title like ?) order by tb_name", prj_id, text, text); - listRet.addAll(l); - break; - case TYPE_PAGE: - case TYPE_WIDGET: - case TYPE_FORM: - EntityDao formdao = DbEngine.getInstance().findDao(ModelForm.class); - List lf; - if (type != TYPE_FORM) { - lf = formdao.queryWhere(" mf_prj_id=? and (mf_name like ? or mf_title like ?) order by tb_name", prj_id, text, text); - } else { - //数据库type 0-页面 1-控件 - lf = formdao.queryWhere(" mf_prj_id=? and mf_type=? and (mf_name like ? or mf_title like ?) order by tb_name", prj_id, type - 2, text, text); - } - listRet.addAll(lf); - } - return listRet; - } - - @Override - protected List getChildren(long id) { - List list = mcTreeHelper.getChildren(id, prj_id, (o1, o2) -> CommUtil.chineseCompare(o1.getName(), o2.getName())); - List listRet; - if (type != TYPE_CATALOG && exc_empty) {//排除空目录 - listRet = cleanEmpty(list); - } else { - listRet = new ArrayList<>(list); - } - - switch (type) { - case TYPE_TABLE: - addTableChildren(listRet, id); - break; - case TYPE_PAGE: - case TYPE_WIDGET: - case TYPE_FORM: - addPageChildren(listRet, id, type); - } - return listRet; - } - - /** - * 去掉没有叶子的空目录 - * @param list - * @return - */ - private List cleanEmpty(List list) { - if (list.isEmpty()) return new ArrayList<>(list); - List lret = new ArrayList<>(); - for (ModelCatalog mc: list) { - if (hasChildren(mc)) lret.add(mc); - } - return lret; - } - - //递归判断,目录是否有儿子 - private boolean hasChildren(ModelCatalog mc) { - List listRet = new ArrayList<>(); - switch (type) { - case TYPE_TABLE: - addTableChildren(listRet, mc.getId()); - break; - case TYPE_PAGE: - case TYPE_WIDGET: - case TYPE_FORM: - addPageChildren(listRet, mc.getId(), type); - } - if (!listRet.isEmpty()) return true; - List list = mcTreeHelper.getChildren(mc.getId(), prj_id, null); - if (list == null || list.isEmpty()) return false; - for (ModelCatalog c: list) { - if (hasChildren(c)) return true; - } - return false; - } - - //增加表 - private void addTableChildren(List listRet, long mcid) { - Collection set = ModelTableCache.getInstance().getTablesByMc(mcid, (o1, o2) -> CommUtil.chineseCompare(o1.getName(), o2.getName())); - if (set == null || set.isEmpty()) return; - - listRet.addAll(set); - } - - //增加页面定义 - private void addPageChildren(List listRet, long mcid, int type) { - List set = ModelFormCache.getInstance().getFormsByMc(mcid, (o1, o2) -> { - if (o1.getType() != o2.getType()) return o1.getType() - o2.getType(); - return CommUtil.chineseCompare(o1.getTitle(), o2.getTitle()); - }); - if (set == null || set.isEmpty()) return; - if (type != TYPE_FORM) { - int pt = type - 2; - for (ModelForm form: set) { - if (form.getType() == pt) { - listRet.add(form); - } - } - } else { - listRet.addAll(set); - } - } - - @Override - protected long getId(DefaultEntity bean) { - return bean.getEntityId(); - } - - @Override - protected String getText(DefaultEntity bean) { - if (bean instanceof ModelCatalog) { - return ((ModelCatalog) bean).getName(); - } - if (bean instanceof ModelTable) { - return ((ModelTable) bean).getTitle(); - } - - if (bean instanceof ModelForm) { - return ((ModelForm)bean).getTitle(); - } - return null; - } - - @Override - protected void buildNode(SwMap node, DefaultEntity bean) { - super.buildNode(node, bean); - if (bean instanceof ModelCatalog) { - node.put("type", TYPE_CATALOG); - } else if (bean instanceof ModelTable) { - node.put("type", TYPE_TABLE); - } else if (bean instanceof ModelForm) { - node.put("type", ((ModelForm)bean).getType() + 2); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java deleted file mode 100644 index 037a170..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java +++ /dev/null @@ -1,34 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.db.vo.ModelCatalog; -import cc.smtweb.framework.core.mvc.service.TreeHelper; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; - -/** - * Created by Akmm at 2022/3/25 10:47 - */ -public class ModelCatalogTreeHelper extends TreeHelper { - //按项目的缓存key,确保此表缓存配置:prj:prjid_parentid - private final static String CACHE_KEY = "prj"; - - public ModelCatalogTreeHelper() { - super(ModelCatalog.ENTITY_NAME); - } - - public List getChildren(long id, long prj_id, Comparator comparator) { - if (id > 0) { - return getChildren(id, comparator); - } - Collection set = cache.getListByKey(CACHE_KEY, prj_id + SwConsts.SPLIT_CHAR + SwConsts.DEF_ROOT_ID); - - List list = set == null ? new ArrayList<>() : new ArrayList<>(set); - if (comparator != null) - list.sort(comparator); - return list; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseComboHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseComboHandler.java deleted file mode 100644 index 265eee2..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseComboHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.db.vo.ModelDatabase; -import cc.smtweb.framework.core.mvc.service.DefaultComboHandler; - -import java.util.List; - -/** - * Created by Akmm at 2022/3/22 19:25 - */ -public class ModelDatabaseComboHandler extends DefaultComboHandler { - public ModelDatabaseComboHandler() { - super(ModelDatabase.ENTITY_NAME); - } - - @Override - protected void buildCondition(StringBuilder sql, List args) { - super.buildCondition(sql, args); - long prj_id = params.readLong("prj_id"); - if (prj_id > 0) { - sql.append(" and db_prj_id=?"); - args.add(prj_id); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseService.java deleted file mode 100644 index c002425..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelDatabaseService.java +++ /dev/null @@ -1,30 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.db.vo.ModelCatalog; -import cc.smtweb.framework.core.db.vo.ModelDatabase; -import cc.smtweb.framework.core.mvc.service.*; - -/** - * Created by Akmm at 2022/3/22 9:12 - */ -@SwService -public class ModelDatabaseService extends AbstractCompService { - @Override - protected AbstractHandler createHandler(String type) { - switch (type) { - case TYPE_LOAD: - return new DefaultLoadHandler(ModelDatabase.ENTITY_NAME); - case TYPE_SAVE: - return new DefaultSaveHandler<>(ModelDatabase.ENTITY_NAME); - case TYPE_DEL: - return new DefaultDelHandler<>(ModelDatabase.ENTITY_NAME); - case TYPE_LIST: - return new DefaultListHandler<>(ModelDatabase.ENTITY_NAME); - case TYPE_COMBO: - return new ModelDatabaseComboHandler(); - - } - return null; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java deleted file mode 100644 index 0ba5e4a..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java +++ /dev/null @@ -1,48 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.vo.ModelProject; - -import java.util.List; - -/** - * Created by Akmm at 2022/1/12 18:34 - */ -@SwCache(ident = "ASP_MODEL_PROJECT", title = "项目定义") -public class ModelProjectCache extends AbstractCache { - private final static String mm = "m"; - public static ModelProjectCache getInstance() { - return CacheManager.getIntance().getCache(ModelProjectCache.class); - } - - public ModelProjectCache() { - regMap(mm, k-> String.valueOf(k.getModule())); - } - - @Override - protected String getId(ModelProject bean) { - return String.valueOf(bean.getId()); - } - - @Override - protected List loadAll() { - EntityDao dao = DbEngine.getInstance().findDao(ModelProject.class); - return dao.query(); - } - - public String getModule(long id) { - ModelProject bean = get(id); - return bean != null ? bean.getModule() : ""; - } - public ModelProject getByModule(String module){ - return getByKey(mm,module); - } - public String getIdByModule(String module) { - ModelProject bean = getByModule(module); - return bean !=null ? String.valueOf(bean.getId()): ""; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectService.java deleted file mode 100644 index 396c2b1..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectService.java +++ /dev/null @@ -1,31 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.db.vo.ModelProject; -import cc.smtweb.framework.core.mvc.service.*; - -/** - * Created by Akmm at 2022/3/1 17:00 - * 项目服务类 - */ -@SwService -public class ModelProjectService extends AbstractCompService { - @Override - protected AbstractHandler createHandler(String type) { - switch (type) { - case TYPE_LOAD: - return new DefaultLoadHandler(ModelProject.ENTITY_NAME); - case TYPE_SAVE: - return new DefaultSaveHandler<>(ModelProject.ENTITY_NAME); - case TYPE_DEL: - return new DefaultDelHandler<>(ModelProject.ENTITY_NAME); - case TYPE_LIST: - return new DefaultListHandler<>(ModelProject.ENTITY_NAME); - case TYPE_COMBO: - return new DefaultComboHandler<>(ModelProject.ENTITY_NAME); - } - return null; - } - - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableComboHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableComboHandler.java deleted file mode 100644 index b4b574f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableComboHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.DefaultComboHandler; - -import java.util.List; - -/** - * Created by Akmm at 2022/3/22 19:25 - */ -public class ModelTableComboHandler extends DefaultComboHandler { - public ModelTableComboHandler() { - super(ModelTable.ENTITY_NAME); - } - - @Override - protected void buildCondition(StringBuilder sql, List args) { - super.buildCondition(sql, args); - long prj_id = params.readLong("prj_id"); - if (prj_id > 0) { - sql.append(" and tb_prj_id=?"); - args.add(prj_id); - } - - long db_id = params.readLong("db_id"); - if (db_id > 0) { - sql.append(" and tb_db_id=?"); - args.add(db_id); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableSaveHanlder.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableSaveHanlder.java deleted file mode 100644 index 01ab1eb..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableSaveHanlder.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.DefaultSaveHandler; - -/** - * Created by Akmm at 2022/3/25 11:40 - */ -public class ModelTableSaveHanlder extends DefaultSaveHandler { - public ModelTableSaveHanlder() { - super(ModelTable.ENTITY_NAME); - } - - @Override - protected void readFromPage() { - super.readFromPage(); - bean.setContent(bean.getContent()); - bean.setName(bean.getName().toUpperCase()); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java deleted file mode 100644 index 4936a5f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java +++ /dev/null @@ -1,47 +0,0 @@ -package cc.smtweb.system.bpm.web.design.db; - -import cc.smtweb.framework.core.annotation.SwBody; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.*; -import cc.smtweb.framework.core.session.UserSession; - -/** - * Created by Akmm at 2022/3/22 9:12 - */ -@SwService -public class ModelTableService extends AbstractCompService { - @Override - protected AbstractHandler createHandler(String type) { - switch (type) { - case TYPE_LOAD: - return new DefaultLoadHandler(ModelTable.ENTITY_NAME); - case TYPE_SAVE: - return new ModelTableSaveHanlder(); - case TYPE_DEL: - return new DefaultDelHandler(ModelTable.ENTITY_NAME); - case TYPE_LIST: - return new DefaultListHandler(ModelTable.ENTITY_NAME); - case TYPE_COMBO: - return new ModelTableComboHandler(); - - } - return null; - } - - //获取表的字段列表 - public R loadFields(@SwBody SwMap params, UserSession us) { - try { - final long tableId = params.readLong("tableId"); - ModelTable table = ModelTableCache.getInstance().get(tableId); - if (table == null) return R.error("没有找到对应的表定义信息【" + tableId + "】!"); - - return R.success(SwListData.create(table.getFields(), 0)); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java deleted file mode 100644 index 1cbe955..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java +++ /dev/null @@ -1,93 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow; - -import cc.smtweb.framework.core.common.IntEnum; - -/** - * Created by Akmm at 2022/5/24 9:04 - * 工作流常量及枚举定义 - */ -public interface FlowConst { - //流程按钮 - class Button { - public static final String DISUSE = "disuse";// 作废 - public static final String LOG = "log";// 流程历史 - public static final String WORD = "word";// 导出Word - public static final String EXCEL = "excel";// 导出Excel - public static final String HANDLER = "handler";// 办理,签收 - public static final String SUBMIT = "submit";// 提交 - public static final String RETAKE = "retake";// 取回 - public static final String REJECT = "reject";// 驳回 - public static final String ADD = "add";// 新增 - public static final String DEL = "del";// 删除 - public static final String SAVE = "save";// 保存 - } - /** - * 活动类型 1-开始任务 2-用户任务 3-条件分支 4-并行开始 5-并行结束 6-脚本任务 9-结束任务 - */ - class ActivityType extends IntEnum { - public static ActivityType instance = new ActivityType(); - public static IntEnumBean START = instance.addEnum(1, "开始任务"); - public static IntEnumBean USER = instance.addEnum(2, "用户任务"); - public static IntEnumBean CONDITION = instance.addEnum(3, "判断分支"); - public static IntEnumBean PARALLEL = instance.addEnum(4, "并行开始"); - public static IntEnumBean GATHER = instance.addEnum(5, "并行结束"); - public static IntEnumBean AUTO = instance.addEnum(6, "脚本任务"); - public static IntEnumBean END = instance.addEnum(9, "结束任务"); - } - - /** - * 流程活动状态 0-待办 1-办理中 2-已提交 3-已驳回 - */ - class ActivityStatu extends IntEnum { - public static ActivityStatu instance = new ActivityStatu(); - public static IntEnumBean WAIT = instance.addEnum(0, "待办"); - public static IntEnumBean HANDLE = instance.addEnum(1, "办理中"); - public static IntEnumBean SUBMIT = instance.addEnum(2, "已提交"); - public static IntEnumBean DISUSE = instance.addEnum(8, "已作废"); - public static IntEnumBean REJECT = instance.addEnum(9, "已驳回"); - } - - /** - * 流程实例状态 - */ - class InstanceStatu extends IntEnum { - public static ActivityStatu instance = new ActivityStatu(); - public static IntEnumBean BEGIN = instance.addEnum(1, "制单"); - public static IntEnumBean RUNING = instance.addEnum(2, "审批中"); - public static IntEnumBean FINISH = instance.addEnum(99, "生效"); - public static IntEnumBean ABORTED = instance.addEnum(98, "中止"); - public static IntEnumBean DISUSE = instance.addEnum(89, "作废"); - } - - /** - * 流程任务创建方式 - */ - class TaskCreateType extends IntEnum { - public static TaskCreateType instance = new TaskCreateType(); - public static IntEnumBean AUTO = instance.addEnum(1, "自动"); - public static IntEnumBean RETAKE = instance.addEnum(2, "取回"); - public static IntEnumBean REJECT = instance.addEnum(3, "驳回"); - } - - /** - * 候选人过滤类别 主办人过滤:制单人所属单位/制单人所属部门/上一步提交人所属单位/上一步提交人所属部门 - */ - class CndFilterType extends IntEnum { - public static CndFilterType instance = new CndFilterType(); - public static IntEnumBean BILL_CORP = instance.addEnum(1, "单据所属单位"); - public static IntEnumBean BILL_DEPT = instance.addEnum(2, "单据所属部门"); - public static IntEnumBean MAKE_CORP = instance.addEnum(3, "制单人所属单位"); - public static IntEnumBean MAKE_DEPT = instance.addEnum(4, "制单人所属部门"); - public static IntEnumBean SUBMITTER_CORP = instance.addEnum(5, "上一步提交人所属单位"); - public static IntEnumBean SUBMITTER_DEPT = instance.addEnum(6, "上一步提交人所属部门"); - } - - /** - * 主办人忽略类型:位运算,上一步提交人/过滤制单人 - */ - class CndIgnoreType extends IntEnum { - public static CndIgnoreType instance = new CndIgnoreType(); - public static IntEnumBean MAKER = instance.addEnum(1, "制单人"); - public static IntEnumBean SUBMITTER = instance.addEnum(2, "上一步提交人"); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java deleted file mode 100644 index e6c1957..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java +++ /dev/null @@ -1,90 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.util.JsonUtil; -import cc.smtweb.system.bpm.web.design.flow.define.ProcInfo; -import com.fasterxml.jackson.annotation.JsonIgnore; - -/** - * Created by Akmm at 2022/5/21 10:40 - * 流程定义 - */ -@SwTable("ASP_MODEL_PROC") -public class ModelProc extends DefaultEntity { - public static final String ENTITY_NAME = "ASP_MODEL_PROC"; - //流程定义详情 - @JsonIgnore - private transient ProcInfo procInfo = null; - - public ModelProc() { - super(ENTITY_NAME); - } - - public ProcInfo getProcInfo() { - if (procInfo == null) { - synchronized ("ModelProc_" + getId()) { - if (procInfo == null) { - procInfo = JsonUtil.parse(getContent(), ProcInfo.class); - } - } - } - return procInfo; - } - - public long getId() { - return getLong("prc_id"); - } - - public void setId(long prcId) { - put("prc_id", prcId); - } - - public long getPrjId() { - return getLong("prc_prj_id"); - } - - public void setPrjId(long prcPrjId) { - put("prc_prj_id", prcPrjId); - } - - public long getMcId() { - return getLong("prc_mc_id"); - } - - public void setMcId(long prcMcId) { - put("prc_mc_id", prcMcId); - } - - public String getCode() { - return getStr("prc_code"); - } - - public void setCode(String prcCode) { - put("prc_code", prcCode); - } - - public String getName() { - return getStr("prc_name"); - } - - public void setName(String prcName) { - put("prc_name", prcName); - } - - public String getContent() { - return getStr("prc_content"); - } - - public void setContent(String prcContent) { - put("prc_content", prcContent); - } - - public String getRemark() { - return getStr("prc_remark"); - } - - public void setRemark(String prcRemark) { - put("prc_remark", prcRemark); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java deleted file mode 100644 index 3cfd542..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java +++ /dev/null @@ -1,59 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Set; - -/** - * Created by Akmm at 2022/1/12 18:34 - */ -@SwCache(ident = "ASP_MODEL_PROC", title = "流程定义") -public class ModelProcCache extends AbstractCache { - private final static String mk = "k"; - private final static String mp = "prj"; - private final static String mc = "c"; - - public static ModelProcCache getInstance() { - return CacheManager.getIntance().getCache(ModelProcCache.class); - } - - public ModelProcCache() { - regMap(mk, k-> k.getName().toUpperCase()); - regList(mp, k-> String.valueOf(k.getPrjId())); - regList(mc, k-> String.valueOf(k.getMcId())); - } - - @Override - protected String getId(ModelProc bean) { - return String.valueOf(bean.getId()); - } - - @Override - protected List loadAll() { - EntityDao dao = DbEngine.getInstance().findDao(ModelProc.class); - return dao.query(); - } - - public final ModelProc getByName(String key) { - return getByKey(mk, key.toUpperCase()); - } - - public final Set getFormsByMc(long mcId) { - return getListByKey(mc, String.valueOf(mcId)); - } - - public final List getFormsByMc(long mcId, Comparator comparator) { - Set set = getListByKey(mc, String.valueOf(mcId)); - if (set == null || set.isEmpty()) return null; - List list = new ArrayList<>(set); - list.sort(comparator); - return list; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java deleted file mode 100644 index d44fad1..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java +++ /dev/null @@ -1,102 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow; - -import cc.smtweb.framework.core.annotation.SwBody; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.mvc.service.AbstractCompService; -import cc.smtweb.framework.core.mvc.service.AbstractHandler; -import cc.smtweb.framework.core.mvc.service.DefaultDelHandler; -import cc.smtweb.framework.core.mvc.service.DefaultListHandler; -import cc.smtweb.framework.core.session.UserSession; -import cc.smtweb.framework.core.util.SqlUtil; -import cc.smtweb.system.bpm.web.design.form.ModelForm; -import cc.smtweb.system.bpm.web.design.form.ModelFormLoadHandler; -import cc.smtweb.system.bpm.web.design.form.ModelFormSaveHandler; -import org.apache.commons.lang3.StringUtils; - -import java.sql.ResultSetMetaData; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Akmm at 2022/3/22 9:12 - */ -@SwService -public class ModelProcService extends AbstractCompService { - @Override - protected AbstractHandler createHandler(String type) { - switch (type) { - case TYPE_LOAD: - return new ModelFormLoadHandler(); - case TYPE_SAVE: - return new ModelFormSaveHandler(); - case TYPE_DEL: - return new DefaultDelHandler(ModelForm.ENTITY_NAME); - case TYPE_LIST: - return new DefaultListHandler(ModelForm.ENTITY_NAME); - - } - return null; - } - - //保存数据集 - public R saveDataset(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelFormSaveHandler)handler).saveDataset()); - } - - //加载数据集 - public R loadDataset(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadDataset()); - } - - //保存页面模型 - public R saveModel(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelFormSaveHandler)handler).saveModel()); - } - - //加载页面模型 - public R loadModel(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadModel()); - } - - //加载引擎用页面模型 - public R model(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadForm()); - } - - //获取页面使用的控件的filter信息 - public R loadWidgetFilter(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelFormLoadHandler)handler).loadWidgetFilter()); - } - - //获取自定义sql的字段信息,去库里查 - public R loadSqlFields(@SwBody SwMap params, UserSession us) { - try { - String sql = params.readString("sql"); - if (StringUtils.isEmpty(sql)) return R.error("没有传入的sql!"); - sql = sql.trim().toLowerCase(); - if (!sql.startsWith("select ")) return R.error("非查询类sql,禁止执行!"); - if (sql.contains(";")) return R.error("sql内禁止出现分号!"); - sql = SqlUtil.replaceTable(sql); - List ret = DbEngine.getInstance().query(sql + " where 1=0", rs -> { - List fields = new ArrayList<>(); - ResultSetMetaData metaData = rs.getMetaData(); - - for (int i = 1, count = metaData.getColumnCount(); i <= count; i++) { - SwMap col = new SwMap(2); - col.put("name", metaData.getColumnLabel(i)); - SwEnum.DataTypeBean dtb = SwEnum.DataType.getBySqlType(metaData.getColumnType(i), metaData.getPrecision(i), metaData.getScale(i)); - col.put("dataType", dtb.value); - fields.add(col); - } - return fields; - }); - return R.success(ret); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ActivityInfo.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ActivityInfo.java deleted file mode 100644 index 91172f8..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ActivityInfo.java +++ /dev/null @@ -1,35 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow.define; - -import lombok.Data; - -import java.util.List; - -/** - * Created by Akmm at 2022/5/21 10:48 - * 步骤定义 - */ -@Data -public class ActivityInfo { - //"id": "", - private String id; - //类别:1-开始任务 2-用户任务 3-条件分支 4-并行开始 5-并行结束 6-脚本任务 9-结束任务 - private int type; - //活动编号,代码可调用 - private String code; - //活动名称 - private String label; - //表单定义 - private String page; - //是否可编辑 - private boolean canEdit; - //是否需要会签 - private boolean needSign; - //可编辑的字段 - private List eidtFields; - //不可查看的字段 - private List disableFields; - //主办人相关信息 - private HandlerInfo handler; - //会签相关信息 - private SignInfo sign; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/HandlerInfo.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/HandlerInfo.java deleted file mode 100644 index 1475f1c..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/HandlerInfo.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow.define; - -import lombok.Data; - -import java.util.List; - -/** - * Created by Akmm at 2022/5/23 9:45 - * 主办人设置信息 - */ -@Data -public class HandlerInfo { - //主办人分组 - private List userGroup; - //主办人过滤:制单人所属单位/制单人所属部门/上一步提交人所属单位/上一步提交人所属部门 - private int filter; - //主办人过滤:上一步提交人/过滤制单人 - private int ignore; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java deleted file mode 100644 index 1f1fd8f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow.define; - -import lombok.Data; - -import java.util.List; - -/** - * Created by Akmm at 2022/5/21 10:48 - * 流程定义信息 - */ -@Data -public class ProcInfo { - //默认表单定义 - private String page; - //是否允许编辑非本人单据 - private boolean canEditOther; - //1-驳回到制单 0-逐级驳回 - private boolean rejectToMake; - //活动节点 - private List activities; - //连接线 - private List trans; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/SignInfo.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/SignInfo.java deleted file mode 100644 index ab1b148..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/SignInfo.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow.define; - -import lombok.Data; - -/** - * Created by Akmm at 2022/5/23 9:54 - * 会签信息 - */ -@Data -public class SignInfo extends HandlerInfo{ - //最少会签人数 - private int minSign; - //最少会签同意人数 - private int minAgree; - //最少会签同意人数单位:0-人数 1-会签同意占比 - private int minAgreeUnit; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/TransInfo.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/TransInfo.java deleted file mode 100644 index 246792e..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/TransInfo.java +++ /dev/null @@ -1,23 +0,0 @@ -package cc.smtweb.system.bpm.web.design.flow.define; - -import lombok.Data; - -/** - * Created by Akmm at 2022/5/21 11:38 - * 连接线 - */ -@Data -public class TransInfo { - //唯一标识 - private String id; - //序号 - private int seq; - //条件表达式 - private String expr; - //源活动 - private String src; - //目标活动 - private String dst; - //说明 - private String desc; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java deleted file mode 100644 index eb81d5f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java +++ /dev/null @@ -1,197 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form; - -import cc.smtweb.framework.core.common.*; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelCache; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.mvc.service.AbstractHandler; -import cc.smtweb.framework.core.util.DateUtil; -import cc.smtweb.framework.core.util.MapUtil; -import cc.smtweb.framework.core.util.SpringUtil; -import cc.smtweb.system.bpm.spring.BpmConfigBean; -import cc.smtweb.system.bpm.util.CodeGenUtil; -import cc.smtweb.system.bpm.util.CodeGenerator; -import cc.smtweb.system.bpm.util.IdeaUtil; -import cc.smtweb.system.bpm.web.design.db.ModelCatalogCache; -import cc.smtweb.system.bpm.web.design.db.ModelProjectCache; -import org.apache.commons.lang3.StringUtils; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 2022/6/14 20:11 - * 生成代码 - */ -public class CodeBuildHandler extends AbstractHandler { - private static final String SRC_MAIN_JAVA = "/src/main/java/"; - private static final String SRC_MAIN_RES = "/src/main/resources"; - - private String userName; - //java文件所在路径 - private String codeJavaPath; - private String packageName; - private BpmConfigBean bpmConfigBean; - - public R buildJavaCode() { - userName = String.valueOf(us.getUserId()); - - //页面id - long pageId = params.readLong("pageId"); - - //是否需要创建服务 - boolean needBuildService = params.readBool("service"); - //实体相关 - List> tables = params.readListMap("table"); - - buildCodeJavaPath(pageId); - for (Map map : tables) { - long tableId = MapUtil.readLong(map, "tableId"); - buildJavaTable(tableId, MapUtil.readBool(map, "bean"), MapUtil.readBool(map, "cache")); - } - if (needBuildService) buildJavaService(pageId); - return R.success(); - } - - public R buildJsCode() { - userName = String.valueOf(us.getUserId()); - //页面id - long pageId = params.readLong("pageId"); - ModelForm form = ModelFormCache.getInstance().get(pageId); - if (form == null) throw new BizException("未找到指定的页面定义(" + pageId + ")!"); - String moduleName = ModelProjectCache.getInstance().getModule(form.getPrjId()); - - if (StringUtils.isEmpty(moduleName) || SwConsts.DEF_DB_NAME.equals(moduleName) || moduleName.equals("bpm")) { - moduleName = "sw-system-bpm"; - } - BpmConfigBean bpmConfigBean = SpringUtil.getBean(BpmConfigBean.class); - Map mapIdeaModules = IdeaUtil.getModules(bpmConfigBean.getCodeJavaPath()); - if (mapIdeaModules == null || mapIdeaModules.isEmpty()) throw new BizException("没有定义idea项目的路径(smtweb.bpm.codeJavaPath)!"); - codeJavaPath = mapIdeaModules.get(moduleName); - if (StringUtils.isEmpty(codeJavaPath)) { - throw new BizException("没有找到对应项目在idea中Module的路径(" + moduleName + ")!"); - } - codeJavaPath += "/src/main/resources/static/event/" + moduleName + "/"; - //加上目录 - String cn = ModelCatalogCache.getInstance().getFullName(form.getMcId()); - if (StringUtils.isNotEmpty(cn)) { - codeJavaPath += cn.replaceAll("\\.", "/"); - } - new File(codeJavaPath).mkdirs(); - - SwMap model = new SwMap(); - model.put("user", userName); - model.put("sysTime", DateUtil.nowDateTime()); - model.put("title", form.getTitle()); - model.put("eventPath", ModelFormHelper.getEventPath(form)); - CodeGenerator.getInstance().generateJsEvent(model, codeJavaPath + "/" + form.getName() + ".js"); - return R.success(); - } - - /** - * 构建java代码路径 - * - * @param pageId 页面id - */ - private void buildCodeJavaPath(long pageId) { - ModelForm form = ModelFormCache.getInstance().get(pageId); - if (form == null) throw new BizException("未找到指定的页面定义(" + pageId + ")!"); - String moduleName = ModelProjectCache.getInstance().getModule(form.getPrjId()); - - if (StringUtils.isEmpty(moduleName) || SwConsts.DEF_DB_NAME.equals(moduleName) || moduleName.equals("bpm")) { - moduleName = "sw-system-bpm"; - packageName = "cc.smtweb.system.bpm.web"; - } else { - packageName = "cc.smtweb.biz." + moduleName + ".web"; - } - BpmConfigBean bpmConfigBean = SpringUtil.getBean(BpmConfigBean.class); - Map mapIdeaModules = IdeaUtil.getModules(bpmConfigBean.getCodeJavaPath()); - if (mapIdeaModules == null || mapIdeaModules.isEmpty()) throw new BizException("没有定义idea项目的路径(smtweb.bpm.codeJavaPath)!"); - codeJavaPath = mapIdeaModules.get(moduleName); - if (StringUtils.isEmpty(codeJavaPath)) { - throw new BizException("没有找到对应项目在idea中Module的路径(" + moduleName + ")!"); - } - codeJavaPath += "/src/main/java/"; - //加上目录 - String cn = ModelCatalogCache.getInstance().getFullName(form.getMcId()); - if (StringUtils.isNotEmpty(cn)) { - packageName += "." + cn; - } - codeJavaPath += packageName.replaceAll("\\.", "/"); - new File(codeJavaPath).mkdirs(); - } - - /** - * 生成bean - * - * @param tableId - */ - private void buildJavaTable(long tableId, boolean needBean, boolean needCache) { - ModelTable table = ModelTableCache.getInstance().get(tableId); - if (table == null) throw new BizException("没有找到对应的表定义(" + tableId + ")!"); - SwMap model = new SwMap(); - model.put("user", userName); - model.put("sysTime", DateUtil.nowDateTime()); - model.put("packageName", packageName); - model.put("tableName", table.getName()); - model.put("tableTitle", table.getTitle()); - - final String beanName = CodeGenUtil.getBeanName(table.getName()); - model.put("beanName", beanName); - if (needBean) { - List fields = new ArrayList<>(); - model.put("fields", fields); - for (ModelField field : table.getFields()) { - SwMap fn = new SwMap(); - fields.add(fn); - fn.put("name", field.getName()); - fn.put("title", field.getTitle()); - fn.put("javaName", CodeGenUtil.getBeanName(field.getName())); - SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(field.getDataType()); - fn.put("javaType", dtb.javaType); - fn.put("shortJavaType", dtb.shortJavaType); - } - - CodeGenerator.getInstance().generateBean(model, codeJavaPath + "/" + beanName + ".java"); - } - - if (needCache) { - if (!table.isNeedCache()) throw new BizException("表设置为不需要缓存!" + table.getTitle()); - List caches = new ArrayList<>(); - model.put("caches", caches); - for (ModelCache cache : table.getCaches()) { - SwMap fn = new SwMap(); - caches.add(fn); - final String name = cache.getName(); - fn.put("name", name); - fn.put("nameUF", CodeGenUtil.toUpperHump(name)); - fn.put("title", cache.getTitle()); - fn.put("fields", cache.getFields()); - } - - CodeGenerator.getInstance().generateCache(model, codeJavaPath + "/" + beanName + "Cache.java"); - } - } - - private void buildJavaService(long pageId) { - ModelForm form = ModelFormCache.getInstance().get(pageId); - String sName = form.getService(); - if (StringUtils.isEmpty(sName)) throw new BizException("页面设置未定义服务名!" + form.getTitle()); - sName = CodeGenUtil.toUpperHump(sName); - - SwMap model = new SwMap(); - model.put("user", userName); - model.put("sysTime", DateUtil.nowDateTime()); - model.put("packageName", packageName); - model.put("formTitle", form.getTitle()); - model.put("service", sName); - model.put("eventPath", ModelFormHelper.getEventPath(form)); - - CodeGenerator.getInstance().generateService(model, codeJavaPath + "/" + sName + "Service.java"); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java deleted file mode 100644 index 8c6f51d..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java +++ /dev/null @@ -1,210 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.system.bpm.web.design.form.define.PageDatasets; -import cc.smtweb.system.bpm.web.design.form.define.PageModel; - -/** - * Created by Akmm at 2022/4/15 17:26 - */ -@SwTable("ASP_MODEL_FORM") -public class ModelForm extends DefaultEntity { - public static final String ENTITY_NAME = "ASP_MODEL_FORM"; - //将相关信息缓存起来 - private transient long masterTableId = -1; - private transient PageDatasets datasets; - private transient SwMap opts; - - public void clearEx() { - masterTableId = -1L; - datasets = null; - opts = null; - } - - public long getMasterTableId() { - if (masterTableId < 0) { - synchronized (ModelForm.class) { - if (masterTableId < 0) { - datasets = ModelFormHelper.parsePageDataset(getDataset()); - if (datasets == null) { - masterTableId = 0; - } else { - masterTableId = datasets.findMasterTableId(); - } - } - } - } - return masterTableId; - } - - public void setMasterTableId(long masterTableId) { - this.masterTableId = masterTableId; - } - - public PageDatasets getDatasets() { - if (datasets == null) { - synchronized (ModelForm.class) { - if (datasets == null) { - datasets = ModelFormHelper.parsePageDataset(getDataset()); - } - } - } - return datasets; - } - - public void setDatasets(PageDatasets datasets) { - this.datasets = datasets; - } - - public SwMap getOpts() { - if (opts == null) { - synchronized (ModelForm.class) { - if (opts == null) { - opts = ModelFormHelper.parseFormOption(getOption()); - } - } - } - return opts; - } - - public void setOpts(SwMap opts) { - this.opts = opts; - } - - public ModelForm() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("mf_id"); - } - - public void setId(long mfId) { - put("mf_id", mfId); - } - - public long getPrjId() { - return getLong("mf_prj_id"); - } - - public void setPrjId(long mfPrjId) { - put("mf_prj_id", mfPrjId); - } - - public long getMcId() { - return getLong("mf_mc_id"); - } - - public void setMcId(long mfMcId) { - put("mf_mc_id", mfMcId); - } - - public String getName() { - return getStr("mf_name"); - } - - public void setName(String mfName) { - put("mf_name", mfName); - } - - public String getTitle() { - return getStr("mf_title"); - } - - public void setTitle(String mfTitle) { - put("mf_title", mfTitle); - } - - public int getType() { - return getInt("mf_type"); - } - - public void setType(int mfType) { - put("mf_type", mfType); - } - - public String getService() { - return getStr("mf_service"); - } - - public void setService(String mfService) { - put("mf_service", mfService); - } - - public String getContent() { - return getStr("mf_content"); - } - - public void setContent(String mfContent) { - put("mf_content", mfContent); - } - - public String getOption() { - return getStr("mf_option"); - } - - public void setOption(String mf_option) { - put("mf_option", mf_option); - opts = null; - } - - public String getTmpl() { - return getStr("mf_tmpl"); - } - - public void setTmpl(String mf_tmpl) { - put("mf_tmpl", mf_tmpl); - } - - public String getDataset() { - return getStr("mf_dataset"); - } - - public void setDataset(String mf_dataset) { - put("mf_dataset", mf_dataset); - datasets = null; - masterTableId = 0L; - } - - public long getCreateUid() { - return getLong("mf_create_uid"); - } - - public void setCreateUid(long mfCreateUid) { - put("mf_create_uid", mfCreateUid); - } - - public long getUpdateUid() { - return getLong("mf_update_uid"); - } - - public void setUpdateUid(long mfUpdateUid) { - put("mf_update_uid", mfUpdateUid); - } - - public long getCreateAt() { - return getLong("mf_create_at"); - } - - public void setCreateAt(long mfCreateAt) { - put("mf_create_at", mfCreateAt); - } - - public long getUpdateAt() { - return getLong("mf_update_at"); - } - - public void setUpdateAt(long mfUpdateAt) { - put("mf_update_at", mfUpdateAt); - } - - public String getRemark() { - return getStr("mf_remark"); - } - - public void setRemark(String mfRemark) { - put("mf_remark", mfRemark); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java deleted file mode 100644 index 77c01fd..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java +++ /dev/null @@ -1,86 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.AbstractEntityCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Set; - -/** - * Created by Akmm at 2022/1/12 18:34 - */ -@SwCache(ident = "ASP_MODEL_FORM", title = "页面定义") -public class ModelFormCache extends AbstractEntityCache { - private final static String mk = "k"; - private final static String mp = "prj"; - private final static String mc = "c"; - private final static String mt = "t"; - - public static ModelFormCache getInstance() { - return CacheManager.getIntance().getCache(ModelFormCache.class); - } - - public ModelFormCache() { - regMap(mk, k-> k.getName().toUpperCase()); - regList(mp, k-> String.valueOf(k.getPrjId())); - regList(mc, k-> String.valueOf(k.getMcId())); - regList(mt, k-> k.getMasterTableId() + SwConsts.SPLIT_CHAR + k.getType()); -// regList(mf, k-> k.get); - } - - @Override - protected String getId(ModelForm bean) { - return String.valueOf(bean.getId()); - } - - @Override - protected List loadAll() { - EntityDao dao = DbEngine.getInstance().findDao(ModelForm.class); - return dao.query(); - } - - public final ModelForm getByName(String key) { - return getByKey(mk, key.toUpperCase()); - } - - public final Set getFormsByMc(long mcId) { - return getListByKey(mc, String.valueOf(mcId)); - } - - public final List getFormsByMc(long mcId, Comparator comparator) { - Set set = getListByKey(mc, String.valueOf(mcId)); - if (set == null || set.isEmpty()) return null; - List list = new ArrayList<>(set); - list.sort(comparator); - return list; - } - - public final Set getFormsByPrj(long mcId) { - return getListByKey(mp, String.valueOf(mcId)); - } - - public final List getFormsByPrj(long mcId, Comparator comparator) { - Set set = getListByKey(mp, String.valueOf(mcId)); - if (set == null || set.isEmpty()) return null; - List list = new ArrayList<>(set); - list.sort(comparator); - return list; - } - - //根据表id,找对应的页面设计 - public Set getListByTable(long tableId, int type) { - return getListByKey(mt, tableId + SwConsts.SPLIT_CHAR + type); - } - - public String getText(long id) { - ModelForm form = get(id); - return form != null ? form.getTitle() : String.valueOf(id); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java deleted file mode 100644 index 2c2e063..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java +++ /dev/null @@ -1,475 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.variable.SwVariableFactory; -import cc.smtweb.framework.core.session.UserSession; -import cc.smtweb.framework.core.util.CommUtil; -import cc.smtweb.framework.core.util.JsonUtil; -import cc.smtweb.framework.core.util.MapUtil; -import cc.smtweb.system.bpm.util.CodeGenerator; -import cc.smtweb.system.bpm.web.design.db.ModelCatalogCache; -import cc.smtweb.system.bpm.web.design.db.ModelProjectCache; -import cc.smtweb.system.bpm.web.design.form.define.*; -import com.fasterxml.jackson.core.JsonProcessingException; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -/** - * Created by Akmm at 2022/4/20 18:45 - * 辅助类 - */ -public class ModelFormHelper { - public static final String KEY_EVENT_PATH = "eventPath"; - //分组类别-list - public static final String PAGE_TYPE_LIST = "list"; - //分组类别-card - public static final String PAGE_TYPE_CARD = "card"; - //分组类别-view - public static final String PAGE_TYPE_VIEW = "view"; - - /** - * 从缓存获取Form对象 - * - * @param formId - * @return - */ - public static ModelForm getFromCache(long formId) { - AbstractCache cache = ModelFormCache.getInstance(); - if (cache == null) return null; - return cache.get(formId); - } - - /*public static PageDatasets parsePageDataset(long formId) { - ModelForm form = getFromCache(formId); - if (form == null) return null; - return parsePageDataset(form.getDataset()); - }*/ - - public static PageDatasets parsePageDataset(String jsonStr) { - if (StringUtils.isEmpty(jsonStr)) return null; - PageDataset[] list = JsonUtil.parse(jsonStr, PageDataset[].class); - return new PageDatasets(list); - } - - /** - * 根据json字符串解析对象 - * - * @param jsonStr - * @return - */ - public static PageModel parsePageInfo(String jsonStr) { - if (StringUtils.isEmpty(jsonStr)) return null; - return JsonUtil.parse(jsonStr, PageModel.class); - } - - public static SwMap parseFormOption(String jsonStr) { - if (StringUtils.isEmpty(jsonStr)) return null; - return JsonUtil.parse(jsonStr, SwMap.class); - } - - /** - * 页面传回的content,加工处理成待保存的json串 - * 主要处理内容: - * 1、model的一些maxlen、默认值等信息,如果和数据库一致,则去掉 - * 2、db中的只保留表、字段和别名 - * - * @param form - * @return - */ - public static String buildSaveModel(ModelForm form, String jsonStr) { - PageDatasets datasets = form.getDatasets(); - PageModel pageInfo = parsePageInfo(jsonStr); - if (pageInfo == null) return ""; - for (Map model : pageInfo.model) { - buildSaveModelFields(datasets, pageInfo, model, true); - buildSaveModelFields(datasets, pageInfo, model, false); - } - return JsonUtil.encodeString(pageInfo); - } - - //处理model的fields和filters - private static void buildSaveModelFields(PageDatasets datasets, PageModel pageInfo, Map model, boolean isField) { - String db = (String) model.get("dataset"); - //没有配置db,配置有误,不处理 - if (StringUtils.isEmpty(db)) throw new BizException("model未配置数据集db,无法解析!"); - PageDataset pds = datasets.findById(db); - String key = isField ? "fields" : "filters"; - List> fields = (List>) model.get(key); - if (fields == null || fields.isEmpty()) return; - for (Map field : fields) { - String fn = (String) field.get("field"); - if (StringUtils.isEmpty(fn)) throw new BizException("model[" + db + "]." + key + "未配置字段名field,无法解析!"); - PageDatasetField pdf = isField ? pds.findFieldByName(fn) : pds.findFilterByName(fn); - if (pdf == null) throw new BizException("model[" + db + "]." + key + "未找到定义的数据集字段(" + fn + "),无法解析!"); - - if (CommUtil.isStrEquals(MapUtil.readString(field, "label"), pdf.label)) { - field.remove("label"); - } - - //必填字段 - if (pdf.isFieldNotNull() == MapUtil.readBool(field, "required")) { - field.remove("required"); - } - - final SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(pdf.dataType); - if (dtb != null && MapUtil.readInt(field, "maxlength") == dtb.dataLength) { - field.remove("maxlength"); - } - } - } - - /** - * 保存的数据集,删除掉一些不必要的字段信息 - * - * @param jsonStr - * @return - */ - public static String buildSaveDataset(String jsonStr) { - PageDatasets datasets = parsePageDataset(jsonStr); - if (datasets == null || datasets.list == null) return ""; - for (PageDataset dataSet : datasets.list) { - buildSaveDataSetFields(dataSet.fields); - buildSaveDataSetFields(dataSet.filters); - } - return JsonUtil.encodeString(datasets.list); - } - - /** - * 构建待保存的数据集 - * - * @return - * @throws JsonProcessingException - */ - public static void buildSaveDataSetFields(List fields) { - ModelTable table = null; - for (PageDatasetField field : fields) { - if (field.table <= 0) continue; - if (table == null || table.getEntityId() != field.table) { - table = ModelTableCache.getInstance().get(field.table); - } - if (table == null) continue; - ModelField tf = table.findFieldByName(field.field); - if (tf == null) continue; - field.table_text = null; - if (CommUtil.isStrEquals(tf.getTitle(), field.label)) field.label = null; - if (CommUtil.isStrEquals(tf.getDataType(), field.dataType)) field.dataType = null; - if (CommUtil.isStrEquals(tf.getRemark(), field.remark)) field.remark = null; - if (CommUtil.isStrEquals(tf.getEditor(), field.editor)) field.editor = null; - } - } - - /** - * 构建请求的数据集,补充表定义信息 - * - * @return - * @throws JsonProcessingException - */ - public static String buildReqDataset(PageDatasets datasets) { - if (datasets == null || datasets.list == null) return ""; - return JsonUtil.encodeString(datasets.list); - } - - - /** - * 根据数据库存储的信息,加工处理成页面要的,与buildsave逆向 - * - * @param form - * @return - */ - public static String buildReqModel(ModelForm form) { - PageDatasets datasets = form.getDatasets(); - PageModel pageInfo = parsePageInfo(form.getContent()); - if (pageInfo == null) return ""; - for (Map model : pageInfo.model) { - String db = (String) model.get("dataset"); - //没有配置db,配置有误,不处理 - if (StringUtils.isEmpty(db)) continue; - PageDataset dataSet = datasets.findById(db); - if (dataSet == null) continue; - buildReqModelFields(dataSet, model, true); - buildReqModelFields(dataSet, model, false); - } - return JsonUtil.encodeString(pageInfo); - } - - //处理model的fields和filters - private static void buildReqModelFields(PageDataset dataSet, Map model, boolean isField) { - String key = isField ? "fields" : "filters"; - List> fields = (List>) model.get(key); - if (fields == null || fields.isEmpty()) return; - for (Map field : fields) { - String fn = (String) field.get("field"); - if (StringUtils.isEmpty(fn)) continue; - PageDatasetField pdf = isField ? dataSet.findFieldByName(fn) : dataSet.findFilterByName(fn); - if (pdf == null) continue; - if (!field.containsKey("label")) { - field.put("label", pdf.label); - } - //必填字段 - if (!field.containsKey("required")) { - field.put("required", pdf.isFieldNotNull()); - } - - if (!field.containsKey("maxlength")) { - final SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(pdf.dataType); - if (dtb != null) { - field.put("maxlength", dtb.dataLength); - } - } - if (!isField) { - PageDatasetFilter filter = (PageDatasetFilter) pdf; - field.put("type", filter.type); - field.put("linkDb", filter.linkDb); - field.put("linkField", filter.linkField); - field.put("value", filter.value); - field.put("trigger",filter.trigger); - } - } - } - - /** - * 根据数据库存储的信息,加工处理成页面要的,与buildsave逆向 - * - * @param form - * @return - */ - public static String buildEngineModel(ModelForm form, SwMap params, UserSession us) { - return buildEngineModel(form, params, us, true); - } - - public static String buildEngineModel(ModelForm form, SwMap params, UserSession us, boolean incExtra) { - PageDatasets datasets = form.getDatasets(); - if (datasets == null || datasets.list == null) return ""; - - SwMap ret = new SwMap(); - PageModel pageInfo = parsePageInfo(form.getContent()); - if (pageInfo == null) return ""; - ret.put("pageId", form.getEntityId()); - ret.put("label", form.getTitle()); - ret.put("service", form.getService()); - ret.put("module", ModelProjectCache.getInstance().getModule(form.getPrjId())); - buildOptsEx(form, ret); - //form不用管 - if (pageInfo.form != null) ret.put("form", pageInfo.form); - List listModel = new ArrayList<>(); - ret.put("model", listModel); - //构建Model - for (Map model : pageInfo.model) { - String db = (String) model.get("dataset"); - PageDataset dataSet = datasets.findById(db); - if (dataSet == null) throw new BizException("未找到指定的数据集定义!" + db); - - listModel.add(buildEngineModelMap(dataSet, model)); - } - if (incExtra) { - ret.put("extra", buildEngineExtra(pageInfo.option, params, us)); - } - return JsonUtil.encodeString(ret); - } - - //构建model部分 - private static SwMap buildEngineModelMap(PageDataset dataSet, Map model) { - SwMap ret = new SwMap(); - - ret.put("id", dataSet.id); - ret.put("name", dataSet.name); - ret.put("label", dataSet.label); - ret.put("type", dataSet.type); - ret.put("idField", dataSet.idField); - ret.put("lazy", dataSet.lazy); - ret.put("canEdit", dataSet.canEdit); - - ret.put("fields", model.get("fields")); - ret.put("filters", model.get("filters")); - - buildReqModelFields(dataSet, model, true); - buildReqModelFields(dataSet, model, false); - - return ret; - } - - //根据option构建Extra部分 - private static SwMap buildEngineExtra(Map option, SwMap params, UserSession us) { - SwMap map = new SwMap(); - if (option == null) return map; - //控件信息 - SwMap widget = new SwMap(); - map.put("widget", widget); - - List widgetIds = (List) option.get("widgetRef"); - for (Object v : widgetIds) { - long id; - if (v instanceof String) { - id = Long.parseLong((String) v); - } else if (v instanceof Integer) { - id = (Integer) v; - } else if (v instanceof Long) { - id = (Long) v; - } else throw new BizException("不能识别的控件Id:" + v); - ModelForm widgetForm = getFromCache(id); - if (widgetForm == null) throw new BizException("没有找到指定的控件定义!id=" + id); - SwMap w = new SwMap(); - widget.put("w" + id, w); - SwMap widgetOpts = widgetForm.getOpts(); - w.put("service", widgetForm.getService()); - if (widgetOpts != null) w.putAll(widgetOpts); - w.put("define", buildEngineModel(widgetForm, params, us, false)); - } - //构建变量 - SwMap mapVar = new SwMap(); - map.put("var", mapVar); - List vars = (List) option.get("vars"); - for (String var : vars) { - mapVar.put(var, SwVariableFactory.getInstance().calcVar(var, params, us)); - } - return map; - } - - //获取控件的filter信息 - public static List buildWidgetFilter(ModelForm bean) { - List listRet = new ArrayList<>(); - PageDatasets datasets = bean.getDatasets(); - if (datasets == null || datasets.list == null) return listRet; - for (PageDataset ds : datasets.list) { - for (PageDatasetFilter filter : ds.filters) { - if (SwEnum.FilterType.INPUT.value.equals(filter.type) || SwEnum.FilterType.PARAM.value.equals(filter.type)) { - SwMap fret = new SwMap(); - fret.put("name", filter.name); - fret.put("label", filter.label); - listRet.add(fret); - } - } - } - listRet.sort((o1, o2) -> CommUtil.chineseCompare(o1.readString("label"), o2.readString("label"))); - return listRet; - } - - /** - * 构建一些扩展属性,目前主要是eventPath - * - * @param opts - */ - public static void buildOptsEx(ModelForm bean, SwMap opts) { - String eventPath = getEventPath(bean); - if (StringUtils.isNotEmpty(eventPath)) { - opts.put(KEY_EVENT_PATH, eventPath); - } - } - - public static String getEventPath(ModelForm bean) { - String moduleName = ModelProjectCache.getInstance().getModule(bean.getPrjId()); - if (StringUtils.isNotEmpty(moduleName)) { - String ep = moduleName; - String cn = ModelCatalogCache.getInstance().getFullName(bean.getMcId()); - if (StringUtils.isNotEmpty(cn)) ep = ep + "." + cn; - return ep + "." + bean.getName(); - } - return ""; - } - - /** - * 根据向导生成model - * @param form - * @param tmplId - */ - public static void buildSaveModelByTmpl(ModelForm form, String tmplId) { - PageDatasets datasets = form.getDatasets(); - SwMap tmplModel = JsonUtil.parse(form.getTmpl(), SwMap.class); - tmplModel.put("title", form.getTitle()); - tmplModel.put("datasets", JsonUtil.bean2MapList(form.getDatasets().list)); - SwMap layout = tmplModel.readMap("layout"); - //用到的自定义控件 - Set setWidget = new HashSet<>(); - for (String key : layout.keySet()) { - List> groups = layout.readListMap(key); - for (Map group : groups) { - String type = MapUtil.readString(group, "type"); - switch (type) { - case PAGE_TYPE_CARD: - buildTmplFields(MapUtil.readListMap(group, "fields"), datasets, setWidget, true); - break; - case PAGE_TYPE_LIST: - buildTmplFields(MapUtil.readListMap(group, "fields"), datasets, setWidget, true); - buildTmplFields(MapUtil.readListMap(group, "cfilters"), datasets, setWidget, false); - buildTmplFields(MapUtil.readListMap(group, "sfilters"), datasets, setWidget, false); - break; - } - } - } - String widgetRef = ""; - if (!setWidget.isEmpty()) { - for (long s: setWidget) { - widgetRef += ",\"" + s + "\""; - } - widgetRef = widgetRef.substring(1); - } - tmplModel.put("widgetRef", widgetRef); - final String model = CodeGenerator.getInstance().generate(tmplModel, tmplId); - form.setContent(model); -// form.setContent(buildSaveModel(form)); - } - - private static void buildTmplFields(List> fields, PageDatasets datasets, Set setWidget, boolean isField) { - if (fields == null) return; - PageDataset dataset = null; - for (Map field : fields) { - final String dsId = MapUtil.readString(field, "dataset"); - if (dataset == null || !dataset.id.equals(dsId)) { - dataset = datasets.findById(dsId); - if (dataset == null) throw new BizException("没有找到指定数据集:" + dsId); - } - String fn = MapUtil.readString(field, "field"); - PageDatasetField pdf; - if (!isField) { - pdf = dataset.findFilterById(fn); - } else { - pdf = dataset.findFieldById(fn); - if (pdf == null) pdf = dataset.findFilterByName(fn); - } - if (pdf == null) throw new BizException("model[" + dsId + "]未找到定义的数据集字段(" + fn + "),无法解析!"); - field.put("id", pdf.id); - field.put("field", pdf.field); - field.put("name", pdf.name); - field.put("label", pdf.label); - field.put("required", pdf.isFieldNotNull()); - field.put("widget", 0); - final SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(pdf.dataType); - if (dtb != null) { - field.put("maxlength", dtb.dataLength); - field.put("editor", dtb.editor); - if (pdf.link > 0) { - long widget = getFieldCtrl(pdf.link); - if (widget > 0) { - setWidget.add(widget); - field.put("widget", widget); - field.put("widgetText", ModelFormCache.getInstance().getText(widget)); - } - } - } else { - field.put("maxlength", 0); - field.put("editor", SwEnum.EditorType.INPUT.value); - } - } - } - - /** - * 计算字段适用控件 - * - * @param tableId - * @return - */ - public static long getFieldCtrl(long tableId) { - Set set = ModelFormCache.getInstance().getListByTable(tableId, SwEnum.FormType.WIDGET.value); - if (set == null || set.isEmpty()) return 0L; - ModelForm form = set.iterator().next(); - return (form != null) ? form.getEntityId() : 0L; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java deleted file mode 100644 index 896992e..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.mvc.service.DefaultLoadHandler; -import cc.smtweb.framework.core.util.JsonUtil; - -/** - * Created by Akmm at 2022/5/9 16:17 - */ -public class ModelFormLoadHandler extends DefaultLoadHandler { - public ModelFormLoadHandler() { - super(ModelForm.ENTITY_NAME); - } - - @Override - protected ModelForm loadComp(long id) { - ModelForm bean = super.loadComp(id); - SwMap opts = bean.getOpts(); - if (opts != null) { - ModelFormHelper.buildOptsEx(bean, opts); - bean.setOption(JsonUtil.encodeString(opts)); - } - //去掉content和dataset - bean.getData().remove("mf_content"); - bean.getData().remove("mf_dataset"); - return bean; - } - - //页面设计-加载数据集定义 - public R loadDataset() { - long id = params.readLong("id"); - ModelForm bean = super.loadComp(id); - if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id); - return R.success(ModelFormHelper.buildReqDataset(bean.getDatasets())); - } - - //页面设计 - 加载页面model定义 - public R loadModel() { - long id = params.readLong("id"); - ModelForm bean = super.loadComp(id); - if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id); - return R.success(ModelFormHelper.buildReqModel(bean)); - } - - //页面引擎-获取页面模型 - public R loadForm() { - long id = params.readLong("id"); - ModelForm bean = super.loadComp(id); - if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id); - return R.success(ModelFormHelper.buildEngineModel(bean, params, us)); - } - - //获取页面使用的控件的filter信息 - public R loadWidgetFilter() { - long id = params.readLong("id"); - ModelForm bean = super.loadComp(id); - if (bean == null) throw new BizException("没有找到指定控件定义!id=" + id); - return R.success(ModelFormHelper.buildWidgetFilter(bean)); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java deleted file mode 100644 index 6ccfab9..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java +++ /dev/null @@ -1,135 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.DefaultSaveHandler; -import cc.smtweb.framework.core.util.JsonUtil; -import org.apache.commons.lang3.StringUtils; - -/** - * Created by Akmm at 2022/5/9 17:05 - * 页面定义保存,注意不要覆盖content和dataset - */ -public class ModelFormSaveHandler extends DefaultSaveHandler { - public ModelFormSaveHandler() { - super(ModelForm.ENTITY_NAME); - } - - @Override - protected void updateBean(EntityDao dao) { - SwMap opts = bean.getOpts(); - if (opts != null) { - opts.remove(ModelFormHelper.KEY_EVENT_PATH); - bean.setOption(JsonUtil.encodeString(opts)); - } - - dao.updateEntityEx(bean, "mf_content", "mf_dataset", "mf_tmpl"); - } - - public R saveDataset() { - long id = params.readLong("id"); - String data = params.readString("data"); - bean = loadComp(id); - if (StringUtils.isEmpty(data)) { - throw new BizException("没有待保存的数据!"); - } - bean.setDataset(ModelFormHelper.buildSaveDataset(data)); - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - EntityDao dao = DbEngine.getInstance().findDao(tableName); - - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); - if (field != null) bean.put(field.getName(), us.getUserId()); - dao.updateEntity(bean, "mf_dataset"); - } - - @Override - public void doAfterDbCommit() { - saveSuccess(); - } - - @Override - public void doAfterDbRollback() { - saveFailed(); - } - }); - return R.success(); - } - - public R saveModel() { - long id = params.readLong("id"); - String data = params.readString("data"); - bean = loadComp(id); - if (StringUtils.isEmpty(data)) { - throw new BizException("没有待保存的数据!"); - } - bean.setContent(ModelFormHelper.buildSaveModel(bean, data)); - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - EntityDao dao = DbEngine.getInstance().findDao(tableName); - - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); - if (field != null) bean.put(field.getName(), us.getUserId()); - dao.updateEntity(bean, "mf_content"); - } - - @Override - public void doAfterDbCommit() { - saveSuccess(); - } - - @Override - public void doAfterDbRollback() { - saveFailed(); - } - }); - return R.success(); - } - - public R saveModelByTmpl() { - long id = params.readLong("pageId"); - String templateId = params.readString("templateId"); - String data = params.readString("data"); - bean = loadComp(id); - if (StringUtils.isEmpty(data)) { - throw new BizException("没有待保存的数据!"); - } - bean.setTmpl(data); - ModelFormHelper.buildSaveModelByTmpl(bean, templateId); - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - EntityDao dao = DbEngine.getInstance().findDao(tableName); - - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); - if (field != null) bean.put(field.getName(), us.getUserId()); - dao.updateEntity(bean, "mf_content,mf_tmpl"); - } - - @Override - public void doAfterDbCommit() { - saveSuccess(); - } - - @Override - public void doAfterDbRollback() { - saveFailed(); - } - }); - return R.success(ModelFormHelper.buildReqModel(bean)); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java deleted file mode 100644 index 5ebb9b7..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java +++ /dev/null @@ -1,167 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form; - -import cc.smtweb.framework.core.annotation.SwBody; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.mvc.service.AbstractCompService; -import cc.smtweb.framework.core.mvc.service.AbstractHandler; -import cc.smtweb.framework.core.mvc.service.DefaultDelHandler; -import cc.smtweb.framework.core.mvc.service.DefaultListHandler; -import cc.smtweb.framework.core.session.UserSession; -import cc.smtweb.framework.core.util.SqlUtil; -import cc.smtweb.system.bpm.util.CodeGenerator; -import org.apache.commons.lang3.StringUtils; - -import java.sql.ResultSetMetaData; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Akmm at 2022/3/22 9:12 - */ -@SwService -public class ModelFormService extends AbstractCompService { - private final static String TYPE_CODE = "type_code"; - @Override - protected AbstractHandler createHandler(String type) { - switch (type) { - case TYPE_LOAD: - return new ModelFormLoadHandler(); - case TYPE_SAVE: - return new ModelFormSaveHandler(); - case TYPE_DEL: - return new DefaultDelHandler(ModelForm.ENTITY_NAME); - case TYPE_LIST: - return new DefaultListHandler(ModelForm.ENTITY_NAME); - case TYPE_CODE: - return new CodeBuildHandler(); - } - return null; - } - - //保存数据集 - public R saveDataset(@SwBody SwMap params, UserSession us) { - try { - ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE); - return handler.saveDataset(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //加载数据集 - public R loadDataset(@SwBody SwMap params, UserSession us) { - try { - ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); - return handler.loadDataset(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //保存页面模型 - public R saveModel(@SwBody SwMap params, UserSession us) { - try { - ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE); - return handler.saveModel(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //根据模板保存页面定义 - public R saveModelByTmpl(@SwBody SwMap params, UserSession us) { - try { - ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE); - return handler.saveModelByTmpl(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //加载页面模型 - public R loadModel(@SwBody SwMap params, UserSession us) { - try { - ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); - return handler.loadModel(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //加载引擎用页面模型 - public R model(@SwBody SwMap params, UserSession us) { - try { - ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); - return handler.loadForm(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //获取页面使用的控件的filter信息 - public R loadWidgetFilter(@SwBody SwMap params, UserSession us) { - try { - ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD); - return handler.loadWidgetFilter(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //获取自定义sql的字段信息,去库里查 - public R loadSqlFields(@SwBody SwMap params, UserSession us) { - try { - String sql = params.readString("sql"); - if (StringUtils.isEmpty(sql)) return R.error("没有传入的sql!"); - sql = sql.trim().toLowerCase(); - if (!sql.startsWith("select")) return R.error("非查询类sql,禁止执行!"); - if (sql.contains(";")) return R.error("sql内禁止出现分号!"); - sql = SqlUtil.replaceTable(sql); - List ret = DbEngine.getInstance().query(sql + " where 1=0", rs -> { - List fields = new ArrayList<>(); - ResultSetMetaData metaData = rs.getMetaData(); - - for (int i = 1, count = metaData.getColumnCount(); i <= count; i++) { - SwMap col = new SwMap(2); - col.put("name", metaData.getColumnLabel(i)); - SwEnum.DataTypeBean dtb = SwEnum.DataType.getBySqlType(metaData.getColumnType(i), metaData.getPrecision(i), metaData.getScale(i)); - col.put("dataType", dtb.value); - fields.add(col); - } - return fields; - }); - return R.success(ret); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //加载模板定义 - public R loadTmpls(@SwBody SwMap params, UserSession us) { - return R.success(CodeGenerator.getInstance().getModelTemplates()); - } - - //生成java代码 - public R buildJavaCode(@SwBody SwMap params, UserSession us) { - try { - CodeBuildHandler handler = (CodeBuildHandler) getHandler(params, us, TYPE_CODE); - return handler.buildJavaCode(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } - - //生成js代码 - public R buildJsCode(@SwBody SwMap params, UserSession us) { - try { - CodeBuildHandler handler = (CodeBuildHandler) getHandler(params, us, TYPE_CODE); - return handler.buildJsCode(); - } catch (Exception e) { - return R.error("操作失败!", e); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java deleted file mode 100644 index dddc39a..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java +++ /dev/null @@ -1,137 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form.define; - -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; - -/** - * Created by Akmm at 2022/4/18 14:20 - * 数据集定义 - */ -public class PageDataset { - //唯一标识 - public String id; - //名称 - public String name; - //中文名 - public String label; - //类别:list-列表;form-表单;editList-编辑列表;tree - public String type; - //主表 - public long masterTable; - public String masterTable_text; - //id字段 对应field的name - public String idField; - //list的自定义sql,仅列表支持,select fields from tables [condition] group by xxx order by xxx - public String sql; - //固定条件,如f1='a' and f2=:p1 - public String fixedCond; - //是否懒加载 - public boolean lazy; - //是否可编辑 - public boolean canEdit; - //select的字段 - public List fields; - public List filters; - public List data; - public PageDatasetDynCond dynCond; - public List sortFields; - - //按字段名的缓存 - private Map mapFieldName; - private Map mapFilterName; - //按字段Id的缓存 - private Map mapFieldId; - private Map mapFilterId; - - //依赖的数据集 - private Set linkDs = new HashSet<>(); - - public PageDatasetField findFieldByName(String name) { - if (mapFieldName == null) resetFields(); - return mapFieldName.get(name); - } - - public PageDatasetFilter findFilterByName(String name) { - if (mapFilterName == null) resetFields(); - return mapFilterName.get(name); - } - - public PageDatasetField findFieldById(String id) { - if (mapFieldId == null) resetFields(); - return mapFieldId.get(id); - } - - public PageDatasetFilter findFilterById(String id) { - if (mapFilterId == null) resetFields(); - return mapFilterId.get(id); - } - - /** - * 重置丰富字段信息 - */ - public void resetFields() { - mapFieldName = new HashMap<>(); - mapFieldId = new HashMap<>(); - linkDs.clear(); - resetFields(mapFieldName, mapFieldId, fields, false); - mapFilterName = new HashMap<>(); - mapFilterId = new HashMap<>(); - resetFields(mapFilterName, mapFilterId, filters, true); - - for (PageDatasetFilter filter : filters) { - if (StringUtils.isEmpty(filter.sqlName)) { - filter.sqlName = filter.field; - } - } - } - - private void resetFields(Map mapName, Map mapId, List list, boolean isFilter) { - ModelTableCache cache = ModelTableCache.getInstance(); - ModelTable table = null; - for (T field : list) { - mapName.put(field.name, field); - mapId.put(field.id, field); - if (field.table <= 0 || StringUtils.isEmpty(field.field)) continue; - if (table == null || table.getId() != field.table) { - table = cache.get(field.table); - } - if (table == null) continue; - ModelField mf = table.findField(field.field); - if (mf == null) throw new BizException("未找到表字段的定义信息(" + table.getName() + "." + field.field + ")"); - field.table_text = table.getTitle(); - field.fieldType = mf.getFieldType(); - field.notNull = mf.getNotNull(); - field.link = mf.getLink(); - - if (StringUtils.isEmpty(field.label)) field.label = mf.getTitle(); - if (StringUtils.isEmpty(field.dataType)) field.dataType = mf.getDataType(); - if (StringUtils.isEmpty(field.remark)) field.remark = mf.getRemark(); - if (StringUtils.isEmpty(field.editor)) field.editor = mf.getEditor(); - //过滤条件,需要建立依赖关系 - if (isFilter) { - PageDatasetFilter filter = (PageDatasetFilter) field; - if (StringUtils.isNotEmpty(filter.linkDb)) linkDs.add(filter.linkDb); - } - } - } - - public PageDatasetFilter findFilterByDs(String dsName) { - for (PageDatasetFilter filter : filters) { - if (SwEnum.FilterType.LINK.value.equals(filter.type) && dsName.equals(filter.linkDb)) { - return filter; - } - } - return null; - } - - public boolean hasDepends(String dsName) { - return linkDs.contains(dsName); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetDynCond.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetDynCond.java deleted file mode 100644 index 16efb8e..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetDynCond.java +++ /dev/null @@ -1,25 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form.define; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import org.apache.commons.lang3.StringUtils; - -import java.util.List; - -/** - * Created by Akmm at 2022/4/20 18:15 - */ //动态条件,一颗二叉树 -public class PageDatasetDynCond { - public String param; - public String opt; - public List children; - - @JsonIgnore - public boolean isEmpty() { - return StringUtils.isEmpty(param) && StringUtils.isEmpty(opt); - } - - @JsonIgnore - public boolean isCondOpt() { - return StringUtils.isEmpty(param); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetEnumData.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetEnumData.java deleted file mode 100644 index 2a71919..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetEnumData.java +++ /dev/null @@ -1,9 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form.define; - -/** - * Created by Akmm at 2022/4/20 18:15 - */ //简单枚举combo的数据 -public class PageDatasetEnumData { - public String value; - public String label; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetField.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetField.java deleted file mode 100644 index 0101386..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetField.java +++ /dev/null @@ -1,41 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form.define; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -/** - * Created by Akmm at 2022/4/20 18:15 - */ //字段要素 -public class PageDatasetField { - public String id; - //表 - public long table; - public String table_text; - //字段 - public String field = ""; - //有别名取别名,无别名同字段名 - public String name; - public String label; - //合计栏 - public String summary; - - public String remark; - //字段类型,如编码字段,参见FieldTypeDef - public int fieldType; - /** - * 数据类型,参见DataType - */ - public String dataType; - /** - * '禁止为空' - */ - public int notNull; - //外键关联表 - public long link; - //控件类型:TEXT/TextArea/NUMBER/COMBO - public String editor; - - @JsonIgnore - public boolean isFieldNotNull() { - return notNull == 1; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java deleted file mode 100644 index 4eb2538..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java +++ /dev/null @@ -1,20 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form.define; - -/** - * Created by Akmm at 2022/4/20 18:15 - */ //过滤条件信息 -public class PageDatasetFilter extends PageDatasetField { - //param-参数/link/const - public String type; - public String title; - //sql中的查询字段名,可能带前缀 - public String sqlName; - //type为link时,关联的数据集及字段 - public String linkDb; - public String linkField; - //type为const时,常量值 - public String value; - // 触发类型 click按钮触发;change监听触发 - public String trigger; - public boolean required = false; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetSortField.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetSortField.java deleted file mode 100644 index 46fb4f3..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetSortField.java +++ /dev/null @@ -1,9 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form.define; - -/** - * Created by Akmm at 2022/4/20 18:16 - */ -public class PageDatasetSortField { - public String field; - public String type; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java deleted file mode 100644 index def7f1d..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java +++ /dev/null @@ -1,57 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form.define; - -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import com.fasterxml.jackson.annotation.JsonIgnore; - -import java.util.*; - -/** - * Created by Akmm at 2022/5/25 15:53 - * 数据集集合 - */ -public class PageDatasets { - public List list; - - @JsonIgnore - private Map mapId = null; - @JsonIgnore - private Map mapName = null; - - public PageDatasets(PageDataset[] datasets) { - this.list = new ArrayList<>(datasets.length); - this.mapId = new HashMap<>(datasets.length); - this.mapName = new HashMap<>(datasets.length); - for (PageDataset ds : datasets) { - this.list.add(ds); - mapId.put(ds.id, ds); - mapName.put(ds.name, ds); - ds.masterTable_text = ModelTableCache.getInstance().getTableName(ds.masterTable); - ds.resetFields(); - } - //按依赖关系排序 - this.list.sort((o1, o2) -> { - if (o1.hasDepends(o2.name)) return 1; - if (o2.hasDepends(o1.name)) return -1; - return 0; - }); - } - - public PageDataset findMasterDataset() { - if (list == null || list.isEmpty()) return null; - return this.list.get(0); - } - - public long findMasterTableId() { - PageDataset ds = findMasterDataset(); - if (ds == null) return 0L; - return ds.masterTable; - } - - public PageDataset findById(String id) { - return mapId.get(id); - } - - public PageDataset findByName(String name) { - return mapName.get(name); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageModel.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageModel.java deleted file mode 100644 index 15dcf8f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageModel.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.smtweb.system.bpm.web.design.form.define; - -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 2022/4/20 15:39 - * 页面模型 - */ -public class PageModel { - public List> form; - public List> model; - public Map option; - public Map extra; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java deleted file mode 100644 index 09a506d..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java +++ /dev/null @@ -1,52 +0,0 @@ -package cc.smtweb.system.bpm.web.design.preview; - -import cc.smtweb.system.bpm.util.ITreeDataLevelHandler; -import lombok.Data; - -import java.util.List; - -@Data -public class MenuVO { - private Long id; - private Long parentId; - private int level; - private String name; - private String path; - private String icon; - private List children; - - // 树结构数据句柄 - public static ITreeDataLevelHandler createTreeHandler() { - return new ITreeDataLevelHandler () { - @Override - public Long getId (MenuVO node){ - return node.getId(); - } - - @Override - public Long getParentId (MenuVO node){ - return node.getParentId(); - } - - @Override - public List getChildren (MenuVO node){ - return node.children; - } - - @Override - public void setChildren (MenuVO node, List children){ - node.children = children; - } - - @Override - public int getLevel (MenuVO node){ - return node.level; - } - - @Override - public void setLevel (MenuVO node, int level){ - node.level = level; - } - } ; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java deleted file mode 100644 index e1a308d..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java +++ /dev/null @@ -1,53 +0,0 @@ -package cc.smtweb.system.bpm.web.design.preview; - -import cc.smtweb.framework.core.annotation.SwParam; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.session.UserSession; -import cc.smtweb.framework.core.util.CommUtil; -import cc.smtweb.system.bpm.util.TreeDataUtil; -import cc.smtweb.system.bpm.web.design.db.ModelProjectCache; -import cc.smtweb.system.bpm.web.design.form.ModelForm; -import cc.smtweb.system.bpm.web.design.form.ModelFormCache; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; - -@SwService -public class PreviewMenuTreeService { - @SwParam - private DbEngine dbEngine; - - public R treeAll(@SwParam("module") String module, UserSession us) { - String prj_id = ModelProjectCache.getInstance().getIdByModule(module); - List listForm; - if (StringUtils.isNotEmpty(prj_id)) { - listForm = new ArrayList<>(ModelFormCache.getInstance().getFormsByPrj(Long.parseLong(prj_id))); - } else { - listForm = new ArrayList<>(ModelFormCache.getInstance().getAll()); - } - listForm.sort((o1, o2) -> CommUtil.chineseCompare(o1.getTitle(), o2.getTitle())); - if (listForm.isEmpty()) throw new BizException("此项目无页面设计!"); - - List list = new ArrayList<>(listForm.size()); - for (ModelForm form: listForm) { - MenuVO menu = new MenuVO(); - menu.setId(form.getId()); - menu.setName(form.getTitle()); - menu.setPath("/bpm/" + form.getId()); -// menu.setParentId(-1L); - list.add(menu); - } - - MenuVO root = new MenuVO(); - root.setName("项目"); - root.setPath(module); - List data = TreeDataUtil.buildTree(root, list, MenuVO.createTreeHandler()); - - return R.success(data); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java deleted file mode 100644 index d91e643..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.mvc.service.AbstractHandler; -import cc.smtweb.framework.core.session.UserSession; -import cc.smtweb.system.bpm.web.design.form.ModelForm; -import cc.smtweb.system.bpm.web.design.form.ModelFormHelper; -import cc.smtweb.system.bpm.web.design.form.define.PageDataset; -import cc.smtweb.system.bpm.web.design.form.define.PageDatasets; - -/** - * Created by Akmm at 2022/4/21 17:53 - */ -public abstract class AbstractDynPageHandler extends AbstractHandler { - //页面定义id - protected long pageId; - protected PageDatasets datasets; - - protected DynPageProvider provider = new DynPageProvider(); - - @Override - public void init(SwMap params, UserSession us) { - super.init(params, us); - pageId = params.readLong("pageId"); - ModelForm form = ModelFormHelper.getFromCache(pageId); - if (form == null) throw new BizException("没有找到页面定义数据(" + pageId + ")!"); - datasets = form.getDatasets(); - if (datasets == null || datasets.list == null) throw new BizException("没有找到页面定义的数据集数据(" + pageId + ")!"); - - provider.pageId = pageId; - provider.datasets = datasets; - } - - protected PageDataset findDataset(String name) { - return datasets.findByName(name); - } - - //获取第一个,主数据集 - protected PageDataset findMasterDataset() { - return datasets.findMasterDataset(); - } - - //从参数读取数据集定义 - protected PageDataset readParamDs() { - //数据集 - String dbName = params.readString("dataset"); - //对应的数据集定义 - PageDataset pageDataSet = findDataset(dbName); - if (pageDataSet == null) throw new BizException("没有找到指定的的数据集定义:" + dbName + "!"); - return pageDataSet; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java deleted file mode 100644 index 7c3199f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java +++ /dev/null @@ -1,156 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.EntityHelper; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.system.bpm.web.design.form.define.PageDataset; -import cc.smtweb.system.bpm.web.design.form.define.PageDatasetFilter; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 2022/4/21 17:53 - * 删除操作 - */ -public class DynPageDelHandler extends AbstractDynPageHandler { - /** - * 删除指定数据集,入参{pageId, dataset, id} - * - * @return - */ - public R delOne() { - long id = params.readLong("id"); - if (id == 0) throw new BizException("没有收到待删除记录Id(" + id + ")!"); - //数据集 - PageDataset pageDataSet = readParamDs(); - - checkBean(pageDataSet, id); - - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable); - if (table == null) throw new BizException("没有找到指定的的表定义:" + pageDataSet.name + "!"); - EntityDao dao = DbEngine.getInstance().findDao(table.getName()); - dao.deleteEntity(id); - } - - @Override - public void doAfterDbCommit() { - ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable); - if (table.isNeedCache()) { - AbstractCache cache = CacheManager.getIntance().getCache(table.getName()); - cache.remove(id); - } - } - }); - return R.success(); - } - - public R delAll() { - long id = params.readLong("id"); - if (id == 0) throw new BizException("没有收到待删除记录Id(" + id + ")!"); - //校验主表即可 - PageDataset masterDs = findMasterDataset(); - if (masterDs == null || !masterDs.canEdit || !SwEnum.DatasetType.FORM.value.equals(masterDs.type)) - throw new BizException("主表不允许删除!"); - checkBean(masterDs, id); - - Map mapRemovableInfo = new HashMap<>(); - for (PageDataset pageDataSet : datasets.list) { - //非表单编辑,不管 - if (!pageDataSet.canEdit || !SwEnum.DatasetType.FORM.value.equals(pageDataSet.type)) continue; - ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable); - RemovableInfo info = mapRemovableInfo.computeIfAbsent(table.getName(), k -> { - RemovableInfo ret = new RemovableInfo(k); - if (pageDataSet != masterDs) {//非主表,记录一下关联字段 - PageDatasetFilter f = pageDataSet.findFilterByDs(masterDs.name); - if (f == null) { - throw new BizException("无法删除表【" + pageDataSet.name + "】,此表未关联主表!"); - } - ret.field = f.field; - } - return ret; - }); - - if (pageDataSet == masterDs || !table.isNeedCache()) { - //主表或没有缓存,直接按FK删除 - info.addId(id); - } else { - info.needCache = true; - //有缓存,需要先把id查出来 - EntityDao dao = DbEngine.getInstance().findDao(table.getName()); - List list = dao.queryIdListWhere(info.field + " = ?", id); - info.ids.addAll(list); - } - } - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - for (RemovableInfo info : mapRemovableInfo.values()) { - EntityDao dao = DbEngine.getInstance().findDao(info.tableName); - if (!info.needCache && StringUtils.isNotEmpty(info.field)) { - //按外键来删除 - dao.deleteEntity(" where " + info.field + "=?", id); - } else { - dao.deleteEntity(info.ids); - } - } - } - - @Override - public void doAfterDbCommit() { - for (RemovableInfo info : mapRemovableInfo.values()) { - if (!info.needCache) continue; - AbstractCache cache = CacheManager.getIntance().getCache(info.tableName); - cache.remove(id); - - } - } - }); - return R.success(); - } - - /** - * 删除校验 - * - * @param pageDataSet - * @param id - */ - protected void checkBean(PageDataset pageDataSet, long id) { - //校验外键引用关系 - EntityHelper.checkExists(pageDataSet.masterTable, id); - } - - /** - * 待删除信息 - */ - class RemovableInfo { - String tableName; - String field = null; - boolean needCache = false; - List ids = new ArrayList<>(); - - public RemovableInfo(String tableName) { - this.tableName = tableName; - } - - void addId(long id) { - ids.add(id); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java deleted file mode 100644 index 18f934e..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java +++ /dev/null @@ -1,238 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.common.SwConsts; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.SqlNamedPara; -import cc.smtweb.framework.core.util.MapUtil; -import cc.smtweb.system.bpm.web.design.form.define.*; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY; - -/** - * Created by Akmm at 2022/4/23 10:01 - * 动态页面辅助类 - */ -public class DynPageHelper { - /** - * 新建bean - * - * @param dataSet - * @return - */ - public static SwMap createBean(PageDataset dataSet) { - //主表 - ModelTable masterTable = ModelTableCache.getInstance().get(dataSet.masterTable); - EntityDao dao = DbEngine.getInstance().findDao(masterTable.getName()); - DefaultEntity bean = dao.createBean(); - return bean.getData(); - } - - /** - * 构建select fields from table - * - * @param dataSet - * @return - */ - public static SqlNamedPara buildSelectSql(PageDataset dataSet, Map params) { - StringBuilder sql = new StringBuilder(512); - - SqlNamedPara sqlNamedPara = buildWhereSql(dataSet, params); - - sql.append(buildSelFieldsSql(dataSet, sqlNamedPara)); - if (StringUtils.isNotEmpty(sqlNamedPara.sql)) { - sql.append(" where ").append(sqlNamedPara.sql); - } - if (dataSet.sortFields != null) { - String s = ""; - for (PageDatasetSortField sf : dataSet.sortFields) { - s += "," + sf.field + " " + sf.type; - } - if (StringUtils.isNotEmpty(s)) { - sql.append(" order by ").append(s.substring(1)); - } - } - sqlNamedPara.sql = sql.toString(); - sqlNamedPara.page = MapUtil.readInt(params, SwConsts.PARAM_PAGE); - sqlNamedPara.rows = MapUtil.readInt(params, SwConsts.PARAM_ROWS); - return sqlNamedPara; - } - - public static SqlNamedPara buildSumSql(PageDataset dataSet, Map params) { - SqlNamedPara sqlNamedPara = buildSelectSql(dataSet, params); - StringBuilder sql = new StringBuilder(256); - sql.append("select count(1) " + TOTAL_KEY); - for (PageDatasetField field : dataSet.fields) { - if (StringUtils.isEmpty(field.summary)) continue; - sql.append(","); - if (!SwEnum.SummaryType.instance.isText(field.summary)) { - sql.append(field.summary).append("(").append(field.name).append(") ").append(field.name); - } else { - sql.append("'").append(field.summary).append("' ").append(field.name); - } - } - sqlNamedPara.sql = sql.toString() + " from (" + sqlNamedPara.sql + ") xxxxa"; - return sqlNamedPara; - } - - private static String buildSelFieldsSql(PageDataset dataSet, SqlNamedPara sqlNamedPara) { - StringBuilder sql = new StringBuilder(512); - //主表 - ModelTable masterTable = ModelTableCache.getInstance().get(dataSet.masterTable); - //非查询列表,或sql为空,则自己组装select sql - if (!SwEnum.DatasetType.LIST.equals(dataSet.type) || StringUtils.isEmpty(dataSet.sql)) { - sql.append("select "); - for (PageDatasetField field : dataSet.fields) { - sql.append(field.field); - //加别名 - if (!field.field.equalsIgnoreCase(field.name)) { - sql.append(" ").append(field.name); - sqlNamedPara.addFieldAlias(field.field, field.name); - } - sql.append(","); - } - sql.setCharAt(sql.length() - 1, ' '); - sql.append(" from ").append(masterTable.getSchemaTableName()); - return sql.toString(); - } else { - return dataSet.sql; - } - } - - /** - * 构建where条件:组合固定和动态条件 - * - * @param dataSet - * @param params - * @return - */ - public static SqlNamedPara buildWhereSql(PageDataset dataSet, Map params) { - StringBuilder sql = new StringBuilder(512); - SwMap args = new SwMap(); - - if (StringUtils.isNotEmpty(dataSet.fixedCond)) { - sql.append("(").append(dataSet.fixedCond).append(")"); - } - //记录归属于固定条件的filter,最后设置参数 - Set setFixedFilter = new HashSet<>(); - for (PageDatasetFilter filter : dataSet.filters) { - setFixedFilter.add(filter.name); - } - if (!dataSet.dynCond.isEmpty()) { - String s = buildDynCondSql(dataSet, dataSet.dynCond, params, args, setFixedFilter); - if (StringUtils.isNotEmpty(s)) { - if (sql.length() > 0) sql.append(" and "); - sql.append(s); - } - } - for (String s : setFixedFilter) { - args.put(s, MapUtil.readString(params, s, "")); - } - return new SqlNamedPara(sql.toString(), args); - } - - /** - * 构建动态条件 - * - * @param dataSet - * @param dynCond - * @param params - * @param args - * @param setFixedFilter - * @return - */ - private static String buildDynCondSql(PageDataset dataSet, PageDatasetDynCond dynCond, Map params, SwMap args, Set setFixedFilter) { - if (dynCond.isCondOpt()) {//是and/or - if (dynCond.children == null || dynCond.children.isEmpty()) return ""; - StringBuilder sql = new StringBuilder(256); - boolean b = false; - //递归调用 - for (PageDatasetDynCond dc : dynCond.children) { - String s = buildDynCondSql(dataSet, dc, params, args, setFixedFilter); - if (StringUtils.isEmpty(s)) continue; - - if (b) sql.append(" ").append(dynCond.opt).append(" "); - sql.append(s); - b = true; - } - if (sql.length() > 0) { - return "(" + sql.toString() + ")"; - } - return ""; - } - - PageDatasetFilter filter = dataSet.findFilterById(dynCond.param); - if (filter == null) throw new BizException("没有找到filter(" + dynCond.param + ")!"); - - boolean isNameSelf = setFixedFilter.contains(filter.name); - setFixedFilter.remove(filter.name); - - Object value = null; - if (SwEnum.FilterType.CONST.value.equals(filter.type)) { - value = filter.value; - //todo 有变量的情况需要处理 - } else { - value = params.get(filter.name); - } - if (value == null || StringUtils.isEmpty(value.toString())) { - if (filter.required) { - throw new BizException("过滤条件不能为空(" + filter.name + ")!"); - } - return null; - } - IBuilderExpr builder = getBuilder(dynCond.opt); - String ns = isNameSelf ? filter.name : filter.name + "_" + dynCond.hashCode(); - return builder.build(dynCond.opt, filter.sqlName, ns, value, args); - } - - private static Map mapBuilder; - private static IBuilderExpr baseBuilder; - - static { - baseBuilder = (opt, field, name, value, args) -> { - args.put(name, value); - return field + " " + opt + " :" + name; - }; - mapBuilder = new HashMap<>(); - mapBuilder.put(SwEnum.OptType.LIKE.value, (opt, field, name, value, args) -> { - args.put(name, "%" + value + "%"); - return field + " like :" + name; - }); - - mapBuilder.put(SwEnum.OptType.PLIKE.value, (opt, field, name, value, args) -> { - args.put(name, value + "%"); - return field + " like :" + name; - }); - - mapBuilder.put(SwEnum.OptType.BT.value, (opt, field, name, value, args) -> { - String[] ss = value.toString().split(","); - if (ss.length != 2) throw new BizException("介于条件,参数值个数错误!"); - args.put(name + "_1", ss[0]); - args.put(name + "_2", ss[1]); - return "(" + field + ">=:" + name + "_1 and " + field + "<=:" + name + "_2)"; - }); - } - - private static IBuilderExpr getBuilder(String opt) { - IBuilderExpr builder = mapBuilder.get(opt); - return builder != null ? builder : baseBuilder; - } - - interface IBuilderExpr { - String build(String opt, String field, String name, Object value, Map args); - } - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java deleted file mode 100644 index 2d5078a..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java +++ /dev/null @@ -1,75 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityHelper; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.AbstractListHandler; -import cc.smtweb.framework.core.mvc.service.SqlNamedPara; -import cc.smtweb.framework.core.mvc.service.SqlPara; -import cc.smtweb.system.bpm.web.design.form.define.PageDataset; - -import java.util.List; - -import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY; - -/** - * Created by Akmm at 2022/5/26 15:58 - */ -public class DynPageListHandler extends AbstractListHandler { - protected long pageId; - //过滤条件 - private SwMap filter; - - //对应的数据集定义 - private PageDataset pageDataSet; - - public DynPageListHandler(long pageId, SwMap filter, PageDataset pageDataSet) { - this.pageId = pageId; - this.filter = filter; - this.pageDataSet = pageDataSet; - } - - @Override - protected String getCompId() { - return "dynpage_" + pageId + "_" + pageDataSet.id; - } - - @Override - protected String getPkFieldName() { - return pageDataSet.idField; - } - - @Override - protected SqlPara buildSqlPara() { - return DynPageHelper.buildSelectSql(pageDataSet, filter); - } - - @Override - protected List queryData(String sql, SqlPara sqlPara) { - List list; - SqlNamedPara sp = (SqlNamedPara)sqlPara; - if (sqlPara.page > 0 && sqlPara.rows > 0) { - list = DbEngine.getInstance().pagedQueryN(sql, SwMap.class, (sqlPara.page - 1) * sqlPara.rows, sqlPara.rows, sp.mapParas); - } else { - list = DbEngine.getInstance().queryN(sql, sp.mapParas, SwMap.class); - } - ModelTable masterTable = ModelTableCache.getInstance().get(pageDataSet.masterTable); - EntityHelper.loadBeanLink(masterTable.getName(), list, sp.mapFieldAlias); - return list; - } - - @Override - public R getTotal() { - SqlNamedPara sqlPara = DynPageHelper.buildSumSql(pageDataSet, filter); - - SwMap mapFooter = DbEngine.getInstance().queryEntityN(sqlPara.sql, sqlPara.mapParas, SwMap.class); - - SwMap r = new SwMap(); - r.put("total", mapFooter.get(TOTAL_KEY)); - r.put("footer", mapFooter); - return R.success(r); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageLoadHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageLoadHandler.java deleted file mode 100644 index 4f96b3d..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageLoadHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.mvc.service.SwListData; -import cc.smtweb.system.bpm.web.design.form.define.PageDataset; - -/** - * Created by Akmm at 2022/4/21 17:53 - */ -public class DynPageLoadHandler extends AbstractDynPageHandler { - //数据集 - private String dbName; - //过滤条件 - private SwMap filter = new SwMap(); - - //对应的数据集定义 - private PageDataset pageDataSet; - - //列表工具类 - public DynPageListHandler getListWorker(SwMap filter, PageDataset pageDataSet) { - DynPageListHandler listHandler = new DynPageListHandler(pageId, filter, pageDataSet); - listHandler.init(params, us); - return listHandler; - } - - //新增操作,初始化定义的数据集 - public R add() { - //返回的数据,以dataset.name为key,查出的结果(bean或list)为value - SwMap mapRet = new SwMap(); - for (PageDataset dataSet : datasets.list) { - if (!dataSet.canEdit) { - continue; - } - if (SwEnum.DatasetType.FORM.value.equals(dataSet.type)) {//单表 - SwMap data; - //懒加载,给个空对象 - if (dataSet.lazy) { - data = new SwMap(); - } else { - data = DynPageHelper.createBean(dataSet); - } - afterAddBean(dataSet, data); - mapRet.put(dataSet.name, DynRetBean.createBean(data)); - } else if (SwEnum.DatasetType.TREE.value.equals(dataSet.type)) {//树 - SwMap data = new SwMap(); - afterAddBean(dataSet, data); - mapRet.put(dataSet.name, DynRetBean.createBean(data)); - } else if (!SwEnum.DatasetType.ENUM.value.equals(dataSet.type)) {//非枚举 - SwListData listData = SwListData.create(null, 0); - afterAddList(dataSet, listData); - mapRet.put(dataSet.name, DynRetBean.createList(listData)); - } - } - return R.success(mapRet); - } - - //新增初始化 - bean - protected void afterAddBean(PageDataset dataset, SwMap bean){} - //新增初始化 - list - protected void afterAddList(PageDataset dataset, SwListData bean){} - - //新增操作,初始化定义的数据集 - public R addOne() { - //对应的数据集定义 - PageDataset dataset = readParamDs(); - - if (!dataset.canEdit) { - return R.error("指定数据集为只读数据集[" + dataset.label + "]!"); - } - //懒加载,给个空对象 - SwMap data = DynPageHelper.createBean(dataset); - afterAddBean(dataset, data); - return R.success(DynRetBean.createBean(data)); - } - - public R loadOne() { - //过滤条件 - SwMap filter = params.readMap("filter"); - //对应的数据集定义 - PageDataset pageDataSet = readParamDs(); - - DynRetBean bean = null; - if (SwEnum.DatasetType.LIST.value.equals(pageDataSet.type)) {//列表类 - bean = DynRetBean.createList(getListWorker(filter, pageDataSet).buildListData()); - } else if (SwEnum.DatasetType.TREE.value.equals(pageDataSet.type)) {//树类 -// return new DynRetBean(loadTree()); - } else {//列表类 - bean = DynRetBean.createBean(provider.loadData(filter, pageDataSet)); - } - - return R.success(bean); - } - - /** - * 计算分页数据 - * - * @return - */ - public R getTotal() { - //数据集 - PageDataset pageDataSet = readParamDs(); - //过滤条件 - SwMap filter = params.readMap("filter"); - - return getListWorker(filter, pageDataSet).getTotal(); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageProvider.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageProvider.java deleted file mode 100644 index 5babb69..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityHelper; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.AbstractCompProvider; -import cc.smtweb.framework.core.mvc.service.SqlNamedPara; -import cc.smtweb.system.bpm.web.design.form.define.PageDataset; -import cc.smtweb.system.bpm.web.design.form.define.PageDatasets; - -/** - * Created by Akmm at 2022/5/26 18:40 - */ -public class DynPageProvider extends AbstractCompProvider { - protected long pageId; - protected PageDatasets datasets; - - //加载表单类数据集(单条) - public SwMap loadData(SwMap filter, PageDataset pageDataSet) { - return doGetData(pageDataSet.id, () -> { - SqlNamedPara sqlPara = DynPageHelper.buildSelectSql(pageDataSet, filter); - SwMap map = DbEngine.getInstance().queryEntityN(sqlPara.sql, sqlPara.mapParas, SwMap.class); - if (map == null) { - throw new BizException("没有找到指定数据(ds=" + pageDataSet.name + ")"); - } - ModelTable masterTable = ModelTableCache.getInstance().get(pageDataSet.masterTable); - EntityHelper.loadBeanLink(masterTable.getName(), map, sqlPara.mapFieldAlias); - return map; - }); - - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageSaveHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageSaveHandler.java deleted file mode 100644 index 3e18418..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageSaveHandler.java +++ /dev/null @@ -1,270 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.cache.AbstractCache; -import cc.smtweb.framework.core.cache.CacheManager; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.exception.BizException; -import cc.smtweb.framework.core.exception.SwException; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelIndex; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.mvc.service.TreeHelper; -import cc.smtweb.framework.core.util.CommUtil; -import cc.smtweb.system.bpm.web.design.form.define.PageDataset; -import cc.smtweb.system.bpm.web.design.form.define.PageDatasetFilter; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 2022/4/21 17:53 - * 保存指定数据集操作 - * 入参:{pageId, data:} - */ -public class DynPageSaveHandler extends AbstractDynPageHandler { - private Map> mapTreeBean = new HashMap<>(); - - protected void setNewId(DefaultEntity bean) { - bean.setEntityId(DbEngine.getInstance().nextId()); - } - - /** - * 保存指定数据集操作,入参:{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}} - */ - public R saveOne() { - //数据集 - String dbName = params.readString("dataset"); - SwMap filter = params.readMap("filter"); - //待保存数据 - SwMap data = params.readMap("data"); - if (data == null) throw new BizException("没有收到待保存的的数据:" + dbName + "!"); - //对应的数据集定义 - PageDataset pageDataSet = findDataset(dbName); - if (pageDataSet == null) throw new BizException("没有找到指定的的数据集定义:" + dbName + "!"); - //读取待保存的bean - DefaultEntity bean = readBeanFromPage(pageDataSet, data); - if (filter != null && bean.isNew()) {//有过滤条件,将关联的值设上 - setLinkValue(pageDataSet, bean, f -> filter.get(f.name)); - } - checkBean(bean); - - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - saveBean(bean); - } - - @Override - public void doAfterDbCommit() { - afterCommit(bean); - } - - @Override - public void doAfterDbRollback() { - afterRollback(bean); - } - }); - return R.success(DynRetBean.createBean(bean.getData())); - } - - /** - * 保存对象,所有数据集数据对象,{ ds1: {form:{},list:{total:0,rows:[]}}} - * - * @return - */ - public R saveAll() { - SwMap data = params.readMap("data"); - if (data == null) throw new BizException("没有收到待保存的的数据!"); - SwMap filter = params.readMap("filter"); - - Map map = new LinkedHashMap<>(); - for (PageDataset pageDataSet : datasets.list) { - //非表单编辑,不管 - if (!pageDataSet.canEdit || !SwEnum.DatasetType.FORM.value.equals(pageDataSet.type)) continue; - SwMap dsData = data.readMap(pageDataSet.name); - if (dsData == null) continue; - - //读取待保存的bean - DefaultEntity bean = readBeanFromPage(pageDataSet, dsData.readMap("form")); - map.put(pageDataSet.name, bean); - SwMap dsFilter = filter.readMap(pageDataSet.name); - if (dsFilter != null && bean.isNew()) {//有过滤条件,将关联的值设上 - setLinkValue(pageDataSet, bean, f -> { - //link类型,去取另一个dataset的值 - if (SwEnum.FilterType.LINK.value.equals(f.type)) { - DefaultEntity lv = map.get(f.linkDb); - if (lv != null) return lv.get(f.linkField); - } - return dsFilter.get(f.name); - }); - } - checkBean(bean); - } - DbEngine.getInstance().doTrans(new AbsDbWorker() { - @Override - public void work() { - for (DefaultEntity bean: map.values()) { - saveBean(bean); - } - } - - @Override - public void doAfterDbCommit() { - for (DefaultEntity bean: map.values()) { - afterCommit(bean); - } - } - - @Override - public void doAfterDbRollback() { - for (DefaultEntity bean: map.values()) { - afterRollback(bean); - } - } - }); - Map mapRet = new HashMap<>(map.size()); - for (Map.Entry entry: map.entrySet()) { - mapRet.put(entry.getKey(), DynRetBean.createBean(entry.getValue().getData())); - } - return R.success(mapRet); - } - - /** - * 从页面获取待保存的bean - * - * @param pageDataSet - * @param data - * @return - */ - protected DefaultEntity readBeanFromPage(PageDataset pageDataSet, SwMap data) { - ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable); - if (table == null) throw new BizException("没有找到待保存的表定义:" + pageDataSet.name); - long id = data.readLong(table.getIdField()); - - EntityDao dao = DbEngine.getInstance().findDao(table.getName()); - DefaultEntity bean; - if (id <= 0) { - bean = dao.createBean(); - bean.setIsNew(true); - setNewId(bean); - } else { - bean = dao.queryEntity(id); - if (bean == null) { - throw new BizException("没有找到待保存的记录:" + table.getName() + "." + id); - } - } - //暂时不考虑list保存的情况 - bean.getData().putAll(data); - return bean; - } - - /** - * 保存校验 - * - * @param bean - */ - protected void checkBean(DefaultEntity bean) { - ModelTable table = ModelTableCache.getInstance().getByName(bean.getTableName()); - for (ModelField field : table.getFields()) { - String value = bean.getStr(field.getName()); - //非空校验 - if (field.isNotNull() && StringUtils.isEmpty(value)) { - throw new BizException("字段不允许为空:" + field.getTitle()); - } - - //长度校验 - if (StringUtils.isNotEmpty(value)) { - int len = SwEnum.DataType.instance.getByValue(field.getDataType()).dataLength; - if (len > 0 && CommUtil.getStrLenB(value) > len) { - throw new BizException("字段值超长:" + field.getTitle()); - } - } - } - //唯一键校验 - EntityDao dao = DbEngine.getInstance().findDao(bean.getTableName()); - for (ModelIndex mi : table.getIndexes()) { - if (mi.isUnique()) { - dao.checkUnique(bean, mi.getFields().split(",")); - } - } - } - - protected void saveBean(DefaultEntity bean) { - final String tableName = bean.getTableName(); - EntityDao dao = DbEngine.getInstance().findDao(tableName); - if (bean.isNew()) { - dao.insertEntity(bean); - } else { - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value); - if (field != null) bean.put(field.getName(), us.getUserId()); - - dao.updateEntity(bean); - if (table.getType() == SwEnum.TableType.TYPE_TREE.value) { - List listTreeBean = TreeHelper.getTreeHelper(tableName).resetTreeLevel(bean); - mapTreeBean.put(tableName, listTreeBean); - } - } - } - - protected void afterCommit(DefaultEntity bean) { - final String tableName = bean.getTableName(); - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table.isNeedCache()) { - AbstractCache cache = CacheManager.getIntance().getCache(tableName); - List listTreeBean = mapTreeBean.get(tableName); - //树型表,父亲改变了,要多处理下缓存;还有个东东:级次码 - if (listTreeBean != null && !listTreeBean.isEmpty()) { - for (DefaultEntity b : listTreeBean) { - cache.put(b); - } - } else { - cache.put(bean); - } - } - } - - protected void afterRollback(DefaultEntity bean) { - final String tableName = bean.getTableName(); - ModelTable table = ModelTableCache.getInstance().getByName(tableName); - if (table.isNeedCache()) { - AbstractCache cache = CacheManager.getIntance().getCache(tableName); - cache.reset(bean); - } - } - - //将关联的值设上 - protected void setLinkValue(PageDataset pageDataSet, DefaultEntity bean, IGetValue iGetValue) { - ModelTable table = ModelTableCache.getInstance().getByName(bean.getTableName()); - for (PageDatasetFilter f : pageDataSet.filters) { - String v = bean.getStr(f.field); - //有值,就不管 - if (v != null && !v.equals(table.findField(f.field).getDefaultValue())) continue; - - if (SwEnum.FilterType.CONST.value.equals(f.type)) {//常量 - bean.put(f.field, f.value); - } else if (SwEnum.FilterType.PARAM.value.equals(f.type)) {//参数 - bean.put(f.field, f.value); - } else if (SwEnum.FilterType.LINK.value.equals(f.type)) {//参数 - Object value = iGetValue.getValue(f); - if (value != null) { - bean.put(f.field, value); - } - } - } - } - - interface IGetValue { - Object getValue(PageDatasetFilter f); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageService.java deleted file mode 100644 index 3803864..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageService.java +++ /dev/null @@ -1,70 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.annotation.SwBody; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.mvc.service.AbstractCompService; -import cc.smtweb.framework.core.mvc.service.AbstractHandler; -import cc.smtweb.framework.core.session.UserSession; - -/** - * Created by Akmm at 2022/4/21 17:43 - * 动态页面引擎 - */ -@SwService -public class DynPageService extends AbstractCompService { - - @Override - protected AbstractHandler createHandler(String type) { - switch (type) { - case TYPE_LOAD: - return new DynPageLoadHandler(); - case TYPE_SAVE: - return new DynPageSaveHandler(); - case TYPE_DEL: - return new DynPageDelHandler(); - } - return null; - } - - //新增 - public R add(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((DynPageLoadHandler)handler).add()); - } - - //新增 - public R addOne(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((DynPageLoadHandler)handler).addOne()); - } - - //加载 - public R loadOne(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((DynPageLoadHandler)handler).loadOne()); - } - - //保存指定数据集 - public R saveOne(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_SAVE, handler -> ((DynPageSaveHandler)handler).saveOne()); - } - - //保存指定数据集 - public R save(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_SAVE, handler -> ((DynPageSaveHandler)handler).saveAll()); - } - - //删除指定数据集 - public R delOne(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_DEL, handler -> ((DynPageDelHandler)handler).delOne()); - } - - //删除数据 - public R del(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_DEL, handler -> ((DynPageDelHandler)handler).delAll()); - } - - //列表总记录数及合计栏 - public R total(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_LOAD, handler -> ((DynPageLoadHandler)handler).getTotal()); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynRetBean.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynRetBean.java deleted file mode 100644 index 4fd3159..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynRetBean.java +++ /dev/null @@ -1,35 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.dynPage; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.mvc.service.SwListData; -import lombok.Data; - -/** - * Created by Akmm at 2022/4/21 19:26 - * 动态页面加载 - */ -@Data -public class DynRetBean { - //单个表单 - private SwMap form = null; - //列表返回 - private SwListData list = null; - - public static DynRetBean createBean(SwMap form) { - DynRetBean bean = new DynRetBean(); - bean.form = form; - return bean; - } - - public static DynRetBean createList(SwListData list) { - DynRetBean bean = new DynRetBean(); - bean.list = list; - return bean; - } -/* - public static DynRetBean createTree(SwListData list) { - DynRetBean bean = new DynRetBean(); - bean.list = list; - return bean; - }*/ -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java deleted file mode 100644 index 21c5b91..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowInstance.java +++ /dev/null @@ -1,65 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow; - -import cc.smtweb.system.bpm.web.design.flow.ModelProc; -import cc.smtweb.system.bpm.web.engine.flow.define.ProcinstEntity; -import cc.smtweb.system.bpm.web.engine.flow.define.TaskEntity; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by Akmm at 2020/3/4 11:35 - * 单据流程实例组件 - */ -public class FlowInstance { - //流程定义 - public ModelProc proc_def; - - //流程实例 - public ProcinstEntity proc_inst; - - //活动任务 - public TaskEntity act_inst; - - //操作类型 新增/编辑/查看 - public int opt_mode = 0;//CmEnum.OperatorType.VIEW; - - //流程执行变量 -// public Map variables = new HashMap<>(); - - public List> tasks = new ArrayList<>(); - - public FlowInstance() { -// this.context = context; - } - - //能否编辑 - public boolean canEdit() { -// return opt_mode == CmEnum.OperatorType.NEW || proc_inst.getstatu() == FlowConsts.InstanceStatu.BEGIN.value; - return false; - } - - public boolean notMakeCanEdit() { - /*Map mapPermisson = MenuHelper.getPermission(context); - boolean othCanEdit = BillFlowWfHelper.getPropBool(proc_def.getEntityId(), FlowConsts.NULL_STR, FlowConsts.ProcProperty.CAN_EDIT_OTHER); - ActivityEntity act = ActivityEntityBuffer.getInstance().get(act_inst.getActId()); - return act != null && !act_inst.isMake() && act.getActEdit() && othCanEdit && MenuHelper.hasPermisson(mapPermisson, CmEnum.MenuFuncRight.UPD.value);*/ - return false; - } - - public boolean isHandleMake() { -// ActivityEntity act = ActivityEntityBuffer.getInstance().get(act_inst.getActId()); -// return !act_inst.isMake() && isHandleMakeEx(act); - return false; - } - - - private boolean isHandleMakeEx(TaskEntity act) { -// if (EntityUtil.isNull(act)) return false; -// return BillFlowWfHelper.getPropInt(proc_inst.getProcDefId(), act.getActId(), FlowConsts.ProcProperty.HANDLER_RANGE) == CmEnum.HandlerRange.MAKE.value; - return false; - } - - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java deleted file mode 100644 index 0b34f57..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/FlowService.java +++ /dev/null @@ -1,15 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow; - -import cc.smtweb.framework.core.mvc.service.AbstractCompService; -import cc.smtweb.framework.core.mvc.service.AbstractHandler; - -/** - * Created by Akmm at 2022/5/24 14:21 - * 工作流 - */ -public class FlowService extends AbstractCompService { - @Override - protected AbstractHandler createHandler(String type) { - return null; - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CandidateEntity.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CandidateEntity.java deleted file mode 100644 index ed03bf6..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CandidateEntity.java +++ /dev/null @@ -1,57 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow.define; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/5/23 14:25 - * 候选信息人 - */ -@SwTable("WF_CANDIDATE") -public class CandidateEntity extends DefaultEntity { - public static final String ENTITY_NAME = "WF_CANDIDATE"; - - public CandidateEntity() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("cnd_id"); - } - - public void setId(long cndId) { - put("cnd_id", cndId); - } - - public long getPriId() { - return getLong("cnd_pri_id"); - } - - public void setPriId(long cndPriId) { - put("cnd_pri_id", cndPriId); - } - - public long getTskId() { - return getLong("cnd_tsk_id"); - } - - public void setTskId(long cndTskId) { - put("cnd_tsk_id", cndTskId); - } - - public long getUserId() { - return getLong("cnd_user_id"); - } - - public void setUserId(long cndUserId) { - put("cnd_user_id", cndUserId); - } - - public int getIsSign() { - return getInt("cnd_is_sign"); - } - - public void setIsSign(int cndIsSign) { - put("cnd_is_sign", cndIsSign); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CareEntity.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CareEntity.java deleted file mode 100644 index 437a1bf..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CareEntity.java +++ /dev/null @@ -1,49 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow.define; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/5/23 14:25 - * 候选信息人 - */ -@SwTable("WF_CARE") -public class CareEntity extends DefaultEntity { - public static final String ENTITY_NAME = "WF_CARE"; - - public CareEntity() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("cr_id"); - } - - public void setId(long crId) { - put("cr_id", crId); - } - - public long getPriId() { - return getLong("cr_pri_id"); - } - - public void setPriId(long crPriId) { - put("cr_pri_id", crPriId); - } - - public long getUserId() { - return getLong("cr_user_id"); - } - - public void setUserId(long crUserId) { - put("cr_user_id", crUserId); - } - - public long getTime() { - return getLong("cr_time"); - } - - public void setTime(long crTime) { - put("cr_time", crTime); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CommentEntity.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CommentEntity.java deleted file mode 100644 index b2670d7..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/CommentEntity.java +++ /dev/null @@ -1,65 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow.define; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/5/23 14:25 - * 审批意见 - */ -@SwTable("WF_COMMENT") -public class CommentEntity extends DefaultEntity { - public static final String ENTITY_NAME = "WF_COMMENT"; - - public CommentEntity() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("cmt_id"); - } - - public void setId(long cmtId) { - put("cmt_id", cmtId); - } - - public long getPriId() { - return getLong("cmt_pri_id"); - } - - public void setPriId(long cmtPriId) { - put("cmt_pri_id", cmtPriId); - } - - public long getTskId() { - return getLong("cmt_tsk_id"); - } - - public void setTskId(long cmtTskId) { - put("cmt_tsk_id", cmtTskId); - } - - public long getUserId() { - return getLong("cmt_user_id"); - } - - public void setUserId(long cmtUserId) { - put("cmt_user_id", cmtUserId); - } - - public String getContent() { - return getStr("cmt_content"); - } - - public void setContent(String cmtContent) { - put("cmt_content", cmtContent); - } - - public long getTime() { - return getLong("cmt_time"); - } - - public void setTime(long cmtTime) { - put("cmt_time", cmtTime); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/ProcinstEntity.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/ProcinstEntity.java deleted file mode 100644 index 4080977..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/ProcinstEntity.java +++ /dev/null @@ -1,129 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow.define; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/5/23 14:25 - * 流程实例 - */ -@SwTable("WF_PROCINST") -public class ProcinstEntity extends DefaultEntity { - public static final String ENTITY_NAME = "WF_PROCINST"; - - public ProcinstEntity() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("pri_id"); - } - - public void setId(long priId) { - put("pri_id", priId); - } - - public String getBillCode() { - return getStr("pri_bill_code"); - } - - public void setBillCode(String priBillCode) { - put("pri_bill_code", priBillCode); - } - - public long getMakeDate() { - return getLong("pri_make_date"); - } - - public void setMakeDate(long priMakeDate) { - put("pri_make_date", priMakeDate); - } - - public int getBillType() { - return getInt("pri_bill_type"); - } - - public void setBillType(int priBillType) { - put("pri_bill_type", priBillType); - } - - public long getPartyId() { - return getLong("pri_party_id"); - } - - public void setPartyId(long priPartyId) { - put("pri_party_id", priPartyId); - } - - public long getDeptId() { - return getLong("pri_dept_id"); - } - - public void setDeptId(long priDeptId) { - put("pri_dept_id", priDeptId); - } - - public String getBillDesc() { - return getStr("pri_bill_desc"); - } - - public void setBillDesc(String priBillDesc) { - put("pri_bill_desc", priBillDesc); - } - - public long getPrcId() { - return getLong("pri_prc_id"); - } - - public void setPrcId(long priPrcId) { - put("pri_prc_id", priPrcId); - } - - public long getStartTime() { - return getLong("pri_start_time"); - } - - public void setStartTime(long priStartTime) { - put("pri_start_time", priStartTime); - } - - public long getEndTime() { - return getLong("pri_end_time"); - } - - public void setEndTime(long priEndTime) { - put("pri_end_time", priEndTime); - } - - public long getUserId() { - return getLong("pri_user_id"); - } - - public void setUserId(long priUserId) { - put("pri_user_id", priUserId); - } - - public long getTaskId() { - return getLong("pri_task_id"); - } - - public void setTaskId(long priTaskId) { - put("pri_task_id", priTaskId); - } - - public int getStatu() { - return getInt("pri_statu"); - } - - public void setStatu(int priStatu) { - put("pri_statu", priStatu); - } - - public String getBillInfo() { - return getStr("pri_bill_info"); - } - - public void setBillInfo(String priBillInfo) { - put("pri_bill_info", priBillInfo); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/SignEntity.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/SignEntity.java deleted file mode 100644 index 4693005..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/SignEntity.java +++ /dev/null @@ -1,74 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow.define; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/5/23 14:25 - * 会签信息 - */ -@SwTable("WF_SIGN") -public class SignEntity extends DefaultEntity { - public static final String ENTITY_NAME = "WF_SIGN"; - - public SignEntity() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("sgn_id"); - } - - public void setId(long sgnId) { - put("sgn_id", sgnId); - } - - public long getPriId() { - return getLong("sgn_pri_id"); - } - - public void setPriId(long sgnPriId) { - put("sgn_pri_id", sgnPriId); - } - - public long getTskId() { - return getLong("sgn_tsk_id"); - } - - public void setTskId(long sgnTskId) { - put("sgn_tsk_id", sgnTskId); - } - - public long getUserId() { - return getLong("sgn_user_id"); - } - - public void setUserId(long sgnUserId) { - put("sgn_user_id", sgnUserId); - } - - public int getAgree() { - return getInt("sgn_agree"); - } - - public void setAgree(int sgnAgree) { - put("sgn_agree", sgnAgree); - } - - public String getContent() { - return getStr("sgn_content"); - } - - public void setContent(String sgnContent) { - put("sgn_content", sgnContent); - } - - public long getTime() { - return getLong("sgn_time"); - } - - public void setTime(long sgnTime) { - put("sgn_time", sgnTime); - } - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java deleted file mode 100644 index d21dcab..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskEntity.java +++ /dev/null @@ -1,161 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow.define; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/5/23 14:25 - * 活动实例 - */ -@SwTable("WF_TASK") -public class TaskEntity extends DefaultEntity { - public static final String ENTITY_NAME = "WF_TASK"; - - public TaskEntity() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("tsk_id"); - } - - public void setId(long tskId) { - put("tsk_id", tskId); - } - - public long getPriId() { - return getLong("tsk_pri_id"); - } - - public void setPriId(long tskPriId) { - put("tsk_pri_id", tskPriId); - } - - public long getPrcId() { - return getLong("tsk_prc_id"); - } - - public void setPrcId(long tskPrcId) { - put("tsk_prc_id", tskPrcId); - } - - public String getActId() { - return getStr("tsk_act_id"); - } - - public void setActId(String tskActId) { - put("tsk_act_id", tskActId); - } - - public String getActName() { - return getStr("tsk_act_name"); - } - - public void setActName(String tskActName) { - put("tsk_act_name", tskActName); - } - - public long getHandler() { - return getLong("tsk_handler"); - } - - public void setHandler(long tskHandler) { - put("tsk_handler", tskHandler); - } - - public long getStartTime() { - return getLong("tsk_start_time"); - } - - public void setStartTime(long tskStartTime) { - put("tsk_start_time", tskStartTime); - } - - public long getEndTime() { - return getLong("tsk_end_time"); - } - - public void setEndTime(long tskEndTime) { - put("tsk_end_time", tskEndTime); - } - - public int getStatu() { - return getInt("tsk_statu"); - } - - public void setStatu(int tskStatu) { - put("tsk_statu", tskStatu); - } - - public String getSubmitIdea() { - return getStr("tsk_submit_idea"); - } - - public void setSubmitIdea(String tskSubmitIdea) { - put("tsk_submit_idea", tskSubmitIdea); - } - - public boolean isMake() { - return getBool("tsk_is_make"); - } - - public void setMake(boolean tskIsMake) { - setBool("tsk_is_make", tskIsMake); - } - - public boolean isSign() { - return getBool("tsk_is_sign"); - } - - public void setSign(boolean tskIsSign) { - setBool("tsk_is_sign", tskIsSign); - } - - public String getSignTotal() { - return getStr("tsk_sign_total"); - } - - public void setSignTotal(String tskSignTotal) { - put("tsk_sign_total", tskSignTotal); - } - - public int getSignPass() { - return getInt("tsk_sign_pass"); - } - - public void setSignPass(int tskSignPass) { - put("tsk_sign_pass", tskSignPass); - } - - public int getSignAgree() { - return getInt("tsk_sign_agree"); - } - - public void setSignAgree(int tskSignAgree) { - put("tsk_sign_agree", tskSignAgree); - } - - public boolean getIsReject() { - return getBool("tsk_is_reject"); - } - - public void setReject(boolean tskIsReject) { - setBool("tsk_is_reject", tskIsReject); - } - - public boolean isRetake() { - return getBool("tsk_is_retake"); - } - - public void setIsRetake(boolean tskIsRetake) { - setBool("tsk_is_retake", tskIsRetake); - } - - public boolean isAuto() { - return getBool("tsk_is_auto"); - } - - public void setIsAuto(boolean tskIsAuto) { - setBool("tsk_is_auto", tskIsAuto); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskRelEntity.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskRelEntity.java deleted file mode 100644 index d06feab..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/engine/flow/define/TaskRelEntity.java +++ /dev/null @@ -1,49 +0,0 @@ -package cc.smtweb.system.bpm.web.engine.flow.define; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by Akmm at 2022/5/23 14:25 - * 活动之间的关系 - */ -@SwTable("WF_CARE") -public class TaskRelEntity extends DefaultEntity { - public static final String ENTITY_NAME = "WF_CARE"; - - public TaskRelEntity() { - super(ENTITY_NAME); - } - - public long getId() { - return getLong("trl_id"); - } - - public void setId(long trlId) { - put("trl_id", trlId); - } - - public long getPriId() { - return getLong("trl_pri_id"); - } - - public void setPriId(long trlPriId) { - put("trl_pri_id", trlPriId); - } - - public long getSrcTaskId() { - return getLong("trl_src_task_id"); - } - - public void setSrcTaskId(long trlSrcTaskId) { - put("trl_src_task_id", trlSrcTaskId); - } - - public long getDstTaskId() { - return getLong("trl_dst_task_id"); - } - - public void setDstTaskId(long trlDstTaskId) { - put("trl_dst_task_id", trlDstTaskId); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/AuthService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/AuthService.java deleted file mode 100644 index ab05c4f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/AuthService.java +++ /dev/null @@ -1,86 +0,0 @@ -package cc.smtweb.system.bpm.web.login; - -import cc.smtweb.framework.core.annotation.*; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.session.SessionManager; -import cc.smtweb.framework.core.session.UserSession; -import cc.smtweb.framework.core.db.DbEngine; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang3.StringUtils; - -@Slf4j -@SwService -public class AuthService { - @SwParam - private DbEngine dbEngine; - - @SwParam - private SessionManager sessionManager; - - @SwPerm(SwPerm.NONE) - public R login(@SwBody LoginVO loginPO) { - /*if (StringUtils.isBlank(loginPO.getUsername())) { - return R.error("账号不能为空"); - } - - if (StringUtils.isBlank(loginPO.getPassword())) { - return R.error("密码不能为空"); - } - - UserPO user = dbEngine.queryEntity("select user_id,user_nick_name,user_nick_code,user_pwd,user_create_party_id from sw_user.sys_user where user_nick_code=?", UserPO.class, loginPO.getUsername()); - - if (user == null) { - return R.error("账号不存在"); - } - - // digest:md5("goodpj" + user.userId + password) - String pass = DigestUtils.md5Hex("goodpj" + user.getUserId() + loginPO.getPassword()); - - if (!pass.equals(user.getUserPwd())) { - return R.error("账号或者密码出错"); - }*/ - - UserSession userSession = new UserSession(); - userSession.setUserId(1); - userSession.setSiteId(1); - - String token = sessionManager.login(userSession); - - LoginAckVO data = new LoginAckVO(); - - data.setUserId(1L); - data.setUserName("管理员"); - data.setUserAvatar(""); - data.setToken(token); - - return R.success(data); - } - - @SwPerm() - public R ping(@SwParam("msg") String msg) { - return R.success(msg); - } - - @SwPerm("user:edit") - public R config(@SwParam("username") String username) { - return R.success("config: " + username); - } - - - /** - * 退出登录 - * @return code - */ - public R logout() { - sessionManager.logout(); - return R.success(); - } - - // defaultRun 命名的函数是默认函数 -// @SwPerm(SwPerm.NONE) -// public R defaultRun(@SwPathParam String path) { -// return R.success(path).put("dao", authDao); -// } - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginAckVO.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginAckVO.java deleted file mode 100644 index 00f8734..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginAckVO.java +++ /dev/null @@ -1,11 +0,0 @@ -package cc.smtweb.system.bpm.web.login; - -import lombok.Data; - -@Data -public class LoginAckVO { - private Long userId; - private String userAvatar; - private String userName; - private String token; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginVO.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginVO.java deleted file mode 100644 index ad841f9..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/LoginVO.java +++ /dev/null @@ -1,12 +0,0 @@ -package cc.smtweb.system.bpm.web.login; - -import lombok.Data; - -import java.io.Serializable; - -@Data -public class LoginVO implements Serializable { - private String username; - - private String password; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/MenuPO.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/MenuPO.java deleted file mode 100644 index 933b334..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/MenuPO.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.smtweb.system.bpm.web.login; - -import cc.smtweb.framework.core.annotation.SwColumn; -import cc.smtweb.framework.core.annotation.SwTable; -import lombok.Data; - -import java.io.Serializable; - -@Data -@SwTable("sw_user.sys_menu") -public class MenuPO implements Serializable { - @SwColumn(type={SwColumn.Type.ID}) - private Long menuId; - - @SwColumn(type={SwColumn.Type.PARENT_ID}) - private Long menuParentId; - - private String menuName; - - private Long menuSiteId; - - - private String menuPermiss; - - private String menuUrl; - - @SwColumn(type={SwColumn.Type.ORDER}) - private Integer menuSort; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/UserPO.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/UserPO.java deleted file mode 100644 index af5c679..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/login/UserPO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cc.smtweb.system.bpm.web.login; - -import cc.smtweb.framework.core.annotation.SwColumn; -import cc.smtweb.framework.core.annotation.SwTable; -import lombok.Data; - -import java.io.Serializable; - -@Data -@SwTable("sw_user.sys_user") -public class UserPO implements Serializable { - @SwColumn(type={SwColumn.Type.ID}) - private Long userId; - - private String userNickCode; - - private String userNickName; - - private Long userCreatePartyId; - - private String userPwd; - - private String userPhone; - - private Integer userStatus; - - private String userAvatar; -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/Area.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/Area.java deleted file mode 100644 index 484fbd3..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/Area.java +++ /dev/null @@ -1,109 +0,0 @@ -package cc.smtweb.system.bpm.web.sys.user.area; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by 1 at 2022-06-17 07:58:14 - * 实体【[行政区划](SYS_AREA)】的Entity类 - */ -@SwTable("SYS_AREA") -public class Area extends DefaultEntity { - public static final String ENTITY_NAME = "SYS_AREA"; - - public Area() { - super(ENTITY_NAME); - } - - /** 主键 */ - public long getId() { - return getLong("ar_id"); - } - - /** 主键 */ - public void setId(long ar_id) { - put("ar_id", ar_id); - } - /** 编码 */ - public String getCode() { - return getStr("ar_code"); - } - - /** 编码 */ - public void setCode(String ar_code) { - put("ar_code", ar_code); - } - /** 名称 */ - public String getName() { - return getStr("ar_name"); - } - - /** 名称 */ - public void setName(String ar_name) { - put("ar_name", ar_name); - } - /** 父ID */ - public long getParentId() { - return getLong("ar_parent_id"); - } - - /** 父ID */ - public void setParentId(long ar_parent_id) { - put("ar_parent_id", ar_parent_id); - } - /** 级次码 */ - public String getLevelCode() { - return getStr("ar_level_code"); - } - - /** 级次码 */ - public void setLevelCode(String ar_level_code) { - put("ar_level_code", ar_level_code); - } - /** 全称 */ - public String getFullName() { - return getStr("ar_full_name"); - } - - /** 全称 */ - public void setFullName(String ar_full_name) { - put("ar_full_name", ar_full_name); - } - /** 级次 */ - public int getType() { - return getInt("ar_type"); - } - - /** 级次 */ - public void setType(int ar_type) { - put("ar_type", ar_type); - } - /** 状态 */ - public boolean isStatu() { - return getBool("ar_statu"); - } - - /** 状态 */ - public void set(boolean ar_statu) { - setBool("ar_statu", ar_statu); - } - /** 备注 */ - public String getRemark() { - return getStr("ar_remark"); - } - - /** 备注 */ - public void setRemark(String ar_remark) { - put("ar_remark", ar_remark); - } - /** 排序码 */ - public int getSeq() { - return getInt("ar_seq"); - } - - /** 排序码 */ - public void setSeq(int ar_seq) { - put("ar_seq", ar_seq); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaCache.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaCache.java deleted file mode 100644 index ec000b5..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaCache.java +++ /dev/null @@ -1,42 +0,0 @@ -package cc.smtweb.system.bpm.web.sys.user.area; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.AbstractEntityCache; -import cc.smtweb.framework.core.cache.CacheManager; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Set; - -/** - * Created by 1 at 2022-06-17 07:58:14 - * 实体【[行政区划](SYS_AREA)】的缓存类 - */ -@SwCache(ident = "SYS_AREA", title = "行政区划") -public class AreaCache extends AbstractEntityCache { - //缓存key:按父ID - public final static String mk_pr = "pr"; - //缓存key:按编码 - public final static String mk_code = "code"; - - public static AreaCache getInstance() { - return CacheManager.getIntance().getCache(AreaCache.class); - } - - public AreaCache() { - //缓存key:按父ID - regList(mk_pr, "ar_parent_id"); - //缓存key:按编码 - regList(mk_code, "ar_code"); - } - - //缓存key:按父ID - public final Set getByPr(String key) { - return getListByKey(mk_pr, key); - } - //缓存key:按编码 - public final Set getByCode(String key) { - return getListByKey(mk_code, key); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaHandler.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaHandler.java deleted file mode 100644 index 42cee9b..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -package cc.smtweb.system.bpm.web.sys.user.area; - -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.impl.DefaultEntity; -import cc.smtweb.system.bpm.web.design.form.define.PageDataset; -import cc.smtweb.system.bpm.web.engine.dynPage.DynPageLoadHandler; -import cc.smtweb.system.bpm.web.engine.dynPage.DynPageSaveHandler; - -/** - * Created by Akmm at 2022/7/1 15:47 - * 区划保存 - */ -public class AreaHandler { - static class AreaSaveHandler extends DynPageSaveHandler { - @Override - protected void setNewId(DefaultEntity bean) { - if (bean instanceof Area) { - Area area = (Area) bean; - area.setEntityId(Long.parseLong(area.getCode())); - } else { - super.setNewId(bean); - } - } - } - - static class AreaLoadHandler extends DynPageLoadHandler { - @Override - protected void afterAddBean(PageDataset dataset, SwMap bean) { - super.afterAddBean(dataset, bean); - Area area = new Area(); - area.setData(bean); -// area.setSeq(); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaService.java b/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaService.java deleted file mode 100644 index 7d724b7..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/area/AreaService.java +++ /dev/null @@ -1,39 +0,0 @@ -package cc.smtweb.system.bpm.web.sys.user.area; - -import cc.smtweb.framework.core.annotation.SwBody; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.system.bpm.web.engine.dynPage.DynPageDelHandler; -import cc.smtweb.system.bpm.web.engine.dynPage.DynPageLoadHandler; -import cc.smtweb.system.bpm.web.engine.dynPage.DynPageSaveHandler; -import cc.smtweb.system.bpm.web.engine.dynPage.DynPageService; -import cc.smtweb.framework.core.mvc.service.AbstractHandler; -import cc.smtweb.framework.core.session.UserSession; - -/** - * Created by 1 at 2022-06-17 07:58:14 - * 页面【[区划卡片]的服务类 - */ -@SwService -public class AreaService extends DynPageService { - //public final static String TYPE_DEMO = "demo"; - @Override - protected AbstractHandler createHandler(String type) { - switch (type) { - case TYPE_SAVE: - return new AreaHandler.AreaSaveHandler(); - case TYPE_LOAD: - return new AreaHandler.AreaLoadHandler(); - } - return super.createHandler(type); - } - -/* demo - //自定义 - public R demo(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_DEMO, handler -> ((DemoHandler)handler).demo()); - } -*/ - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/META-INF/spring.factories b/smtweb-framework/sw-system-bpm/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 86f1fdb..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - cc.smtweb.system.bpm.spring.BpmAutoConfiguration diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/dataset.ts b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/dataset.ts deleted file mode 100644 index 45ed53b..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/dataset.ts +++ /dev/null @@ -1,730 +0,0 @@ -import {onMounted, watch} from 'vue'; -import {RouteLocationNormalizedLoaded, useRoute} from 'vue-router'; -import Schema, {ErrorList, FieldErrorList} from 'async-validator'; -import api from '/@/api'; -import commonUtil from '/@/utils/commonUtil'; -import {confirm, notify} from '/@/utils/message'; -import {IPageParams} from './page.types'; -import {tabRouter} from '/@/pages/layout/tab/useTab'; - -interface IDatasetEvent { - action: string - dataset: any - row: any -} - -export class PageDataset { - private params: IPageParams; - readonly data: any; - readonly page: any; - private eventHandle?: Function; - - constructor(route: RouteLocationNormalizedLoaded, data: any, page: any) { - // title: this.$route.query.title, - // 页面参数 - - this.params = { - pageId: route.params.pageI || page.id, - id: route.params.id as string, - parentId: route.params.parentId as string, - }; - - this.data = data; - this.page = page; - // 混入的主页面需要提供 page 和 data - } - - setEventHandle(eventHandle: Function) { - this.eventHandle = eventHandle; - } - - // 通过dataset对象读取数据 - async loadDataset(dataset: any, row?: any, params?: any, callFn?: Function) { - if (row && dataset.masterFields) { - // 处理子表过滤条件 - const filter = []; - - for (const mapField of dataset.masterFields) { - filter.push({ field: mapField.slave, keyword: row[mapField.master] }); - } - - dataset.filter = filter; - } - - switch (dataset.listModel) { - case 1: - await this.loadList(dataset.name, params, callFn); - break; - case 2: - await this.loadTree(dataset.name, params, callFn); - break; - default: - await this.loadCard(dataset.name, params, callFn); - break; - } - } - - // async searchList() { - // // 点击搜索按钮 - // if (this.getMainDatasetId()) { - // await this.loadList(this.getMainDatasetId(), 0); - // } - // } - // - // async resetList() { - // // 重置按钮 - // if (this.getMainDatasetId()) { - // const dataset = this.getDatasetById(this.getMainDatasetId()); - // // this.$set(dataset, 'form', {}); - // dataset.form = {}; - // await this.loadList(this.getMainDatasetId(), 0); - // } - // } - // - // getMainDatasetId(): string | null { - // const { datasets } = this.page; - // if (datasets && datasets.length > 0) { - // return datasets[0].id; - // } - // return null; - // } - - findDatasetMeta(datasetName: string): any { - return this.page.datasets[datasetName]; - // 得到 datasets - // return this.page.datasets.find((e: any) => e.id === datasetId || e.name === datasetId); - // return Object.values(this.page.datasets).find((dataset: any) => { - // return dataset.id === datasetId || dataset.name === datasetId; - // }); - } - - // async loadDatasetById(datasetId: string) { - // await this.loadDataset(this.findDataset(datasetId)); - // } - - async loadDatasetByName(name: string, params?: any, callFn?: Function) { - await this.loadDataset(this.page.datasets[name], null, params, callFn); - } - - async doApi(name: string, params: any): Promise { - const dataset = this.findDatasetMeta(params.dataset); - let url = null; - if (dataset && dataset.apis) { - url = dataset.apis[name]; - } - - if (!url) { - switch (name) { - case 'cardGet': - url = 'bpm/DynFormCard/load'; - break; - case 'cardSave': - url = 'bpm/DynFormCard/save'; - break; - case 'cardDel': - url = 'bpm/DynFormCard/remove'; - break; - case 'listGet': - url = 'bpm/DynFormList/list'; - break; - case 'listCount': - url = 'bpm/DynFormList/count'; - break; - case 'treeAll': - url = 'bpm/DynFormTree/treeAll'; - break; - case 'treeGet': - url = 'bpm/DynFormTree/tree'; - break; - case 'treeMove': - url = 'bpm/DynFormTree/move'; - break; - } - } - if (url) { - return await api.post(url, params); - // return await api.post(url, params); - } - - return {}; - } - - // async doCustomApi(apiName: string, params: any, callFn: Function) { - // // 执行自定义的API - // const re = await api.post(apiName, params); - // if (callFn) { - // callFn(re); - // } - // } - - async loadCard(datasetName: string, params: any, callFn?: Function) { - const ds = this.loadDatasetData(datasetName); - console.log('loadCard= ', this.params.id, ds); - if (this.params.id) { - // 查询一条数据 - const { data } = await this.doApi('cardGet', { - pageId: this.page.id, - dataset: datasetName, - id: this.params.id, - filter: ds.filter, - }); - - if (data) { - ds.form = data; - - this.scrollDataset(datasetName, data); - } - - if (callFn) { - callFn(data); - } - } - } - - loadDatasetData(datasetName: string | null): any { - if (datasetName) { - return this.data[datasetName]; - } - - return null; - } - - async loadList(datasetName: string | null, pageIndex: number, callFn?: Function) { - const ds = this.loadDatasetData(datasetName); - - if (!ds) { - console.error(`not find dataset name: ${datasetName}`); - return; - } - - const params = { - pageId: this.page.id, - parentId: this.params.parentId, - dataset: datasetName, - pageIndex, - pageSize: ds.list.pageSize, - filter: ds.list.filter, - // search: ds.list.search || [], - // searchType: ds.list.searchType, - // params: { ...(ds.form || {}), ..._search }, - }; - - ds.list.loading = true; - const { data } = await this.doApi('listGet', params); - ds.list.loading = false; - - if (data) { - ds.list.data = data.rows; - - // console.log(this.data, data.rows.length); - - if (ds.list.total < 0) { // 不需要每次都查询条数和统计 - try { - // 更新总数 - if (data.total < 0) { - // 异步加载数据总数和统计数据 - const retCount = await this.doApi('listCount', params); - if (retCount.data) { - ds.list.total = retCount.data.total / 1; // (sql条数是java long类型) - ds.list.summary = retCount.data; - } - } else { - ds.list.total = data.total; - } - } catch (e) { - console.log('e', e); - } - } - - this.scrollDataset(datasetName!); - } - - if (callFn) { - callFn(data); - } - } - - async loadTree(datasetName: string, params = {}, callFn?: Function) { - // 加载树数据 - const ds = this.loadDatasetData(datasetName); - - ds.list.loading = true; - const ret = await this.doApi('treeAll', { - ...params, - pageId: this.page.id, - dataset: datasetName, - }); - ds.list.loading = false; - if (ret.data) { - ds.list.data = ret.data || []; - this.scrollDataset(datasetName, null); - if (callFn) { - callFn(); - } - } - } - - scrollDataset(datasetName: string, row?: any) { - // 加载从表数据 - Object.values(this.page.datasets).forEach((dataset: any) => { - if (dataset && dataset.tableType === 2 && dataset.master === datasetName) { - if (row) { - this.loadDataset(dataset, row); - } else { - // 直接清空 - this.scrollDataset(dataset.id, null); - const slaveData = this.loadDatasetData(dataset.name); - slaveData.list.data.length = 0; - } - } - }); - - this.doEvent({ action: 'afterScroll', dataset: datasetName, row }); - } - - _removeItem(listData: any, id: string, _mainField: string) { - if (!_mainField) { - _mainField = 'id'; // 对比的键 - } - for (let i = 0; i < listData.length; i++) { - const child = listData[i]; - if (child[_mainField] === id) { - listData.splice(i, 1); - return true; - } - - if (child.children) { - if (this._removeItem(child.children, id, _mainField)) { - return true; - } - } - } - - return false; - } - - _doSave(datasetName: string, formData: any, callFn: Function) { - this.doApi('cardSave', { - ...formData, - pageId: this.page.id, - id: this.params.id, - parentId: this.params.parentId, - dataset: datasetName, - }).then((ret) => { - this.params.id = ret.data; - notify.success('操作成功'); - if (callFn) { - callFn(ret); - } - }); - } - - onSubmit(datasetName: string, isReturn = false) { - if (datasetName) { - const ds = this.loadDatasetData(datasetName); - const formData = ds.form; - formData.parentId = this.params.parentId; - const dataset = this.findDatasetMeta(datasetName); - console.log('onSubmit', formData, dataset); - - if (dataset && dataset.rules && !commonUtil.isEmptyObj(dataset.rules)) { - const validator = new Schema(dataset.rules); - validator.validate(formData, {}, (errors: ErrorList, fields: FieldErrorList) => { - if (errors) { - // validation failed, errors is an array of all errors - // fields is an object keyed by field name with an array of - // errors per field - console.log(errors, fields); - notify.error('验证失败'); - } else { - this._doSave(datasetName, formData, () => { - if (isReturn) { - this.goBack(); - } - }); - } - // validation passed - }); - } else { - if (!this.customValidator(datasetName)) { - return; - } - this._doSave(datasetName, formData, () => { - if (isReturn) { - this.goBack(); - } - }); - } - } - } - - customValidator(datasetName: string) { - // 验证成功 返回 true 失败 返回 false - // 自定义 输入 验证 - const ds = this.loadDatasetData(datasetName); - if (ds) { - const formData = ds.form || {}; - let _b = true; - console.log('customValidator', formData); - if (this.page && this.page.widgets) { - const { widgets = {} } = this.page; - // 验证必填 (只验证是否有值,不能格式) - Object.values(widgets).forEach((_widget: any) => { - if (_widget.dataset === datasetName && _widget.required) { - const _name = _widget.name || _widget.field; - if (!commonUtil.isEmpty(_name)) { - if (commonUtil.isEmpty(formData[_name])) { - _b = false; - _widget.showError = true; - } else { - _widget.showError = false; - } - } - } - }); - } - return _b; - } - return false; - } - - goBack() { - // 返回上一页面 - tabRouter.back(); - // router.back(); - } - - getIdFieldByDataset(datasetName: string) { - // 得到 dataset 的ID属性值 - if (this.page && this.page.datasets && this.page.datasets[datasetName]) { - return this.page.datasets[datasetName].idField; - } - return null; - } - - // 生成查询条件用于向后台提交参数 - _buildSearch(datasetId: string, ds: any): Array { - // 用户输入的搜索条件 - const result: any[] = []; - - const { widgets } = this.page; - - Object.keys(this.page.widgets).forEach((key) => { - const widget = widgets[key]; - if (widget.dataset === datasetId && widget.field && widget.filterType) { - const keyword = ds.form[widget.field]; - if (keyword) { - result.push({ field: widget.field, keyword, op: widget.filterType }); - } - } - }); - - // const _search = {}; - // if (ds.list.search && ds.list.search.length > 0) { - // for (const _obj of ds.list.search) { - // if (_obj.field) { - // _search[_obj.field] = _obj.keyword; - // } - // } - // } - - return result; - } - - // 界面按钮产生的数据集动作 - async onWidgetAction(datasetName: string, params: any) { - const ds = this.loadDatasetData(datasetName); - const dsMeta = this.findDatasetMeta(datasetName); - // 得到主键值 - if (params.row && dsMeta && dsMeta.idField) { - params.id = params.row[dsMeta.idField]; - // params.mainField = _mainField; - } - - console.log('onWidgetAction', params, ds); - - if (params.link) { - const routeName = this.page.ref.routes[`id_${params.link}`]; - - if (routeName) { - const query = { - // pageId: params.link, - action: params.action, - } as any; - - switch (params.action) { - case 'button:add': - query.parentId = this.params.parentId; - // query.dataParentId = params.parentId; - break; - case 'button:edit': - // query.parentId = params.id || ''; - query.id = params.id; - // row = JSON.stringify(params.row || {}), - break; - } - await tabRouter.push(routeName, query); - // await router.push({ name: routeName, params: query }); - // } else { - // await router.push({ - // path: `/form/${params.link}`, - // query: { parentId: this.params.id }, - // }); - } else { - console.error(`not find link page by id ${params.link}`); - } - } else { - switch (params.action) { - case 'list:page': // list控件事件 - if (params.reset) { - ds.list.total = -1; - } - ds.list.pageSize = params.pageSize; - - await this.loadList(datasetName, params.pageIndex); - break; - case 'list:filter': // list控件事件,快速查询 - ds.list.total = -1; - ds.list.search = params.search; - ds.list.searchType = params.searchType; - ds.list.pageSize = params.pageSize; - - await this.loadList(datasetName, 0); - break; - case 'button:search': // 搜索按钮 - ds.list.total = -1; - ds.list.filter = this._buildSearch(datasetName, ds); - ds.list.pageSize = params.pageSize; - - await this.loadList(datasetName, 0); - break; - case 'button:return': - this.goBack(); - break; - case 'button:add': - // this._load({pageId: params.link, dataParentId: params.parentId, filter: ds.filter}); - // 弹出新页面 - // this.$router.push({ path: '/form/' + params.link, query: { dataParentId: params.parentId, filter: ds.filter }}); - // 替换当前新页面,path需要相同 - - // router.push({ - // path: `/form/${this.page.id}`, - // query: { - // pageId: params.link, - // parentId: this.params.parentId, - // dataParentId: params.parentId, - // filter: ds.filter, - // // title: this.title, - // }, - // }); - notify.warning('未配置链接页面'); - break; - case 'button:edit': - // this._load({pageId: params.link, id: params.id}); - // 替换当前新页面,path需要相同 - // router.push({ - // path: `/form/${this.page.id}`, - // query: { - // pageId: params.link, - // parentId: params.parentId, - // id: params.id, - // filter: ds.filter, - // // title: this.title, - // row: JSON.stringify(params.row || {}), - // }, - // }); - break; - case 'button:save': - this.onSubmit(datasetName, false); - break; - case 'button:saveAndReturn': - this.onSubmit(datasetName, true); - break; - case 'button:submit': { - const { isReturn } = params; - this.onSubmit(datasetName, isReturn); - } - break; - case 'button:remove': - // 删除一条数据 - this.onWidgetActionRemove('此操作将删除当前记录, 是否继续?', datasetName, [params.id], { - mainField: params.mainField || 'id', - }); - break; - case 'button:batchRemove': - if (params.sels && params.sels.length > 0) { - const ids = []; - - for (const item of params.sels) { - ids.push(item.id); - } - - this.onWidgetActionRemove(`此操作将删除选中的 "${ids.length}" 条记录, 是否继续?`, datasetName, ids); - } - break; - case 'button:move': - await this.doApi('treeMove', { - pageId: this.page.id, - dataset: datasetName, - id: params.id, - parentId: params.parentId, - dataOrders: params.orders, - }); - break; - case 'list:selected': - this.scrollDataset(datasetName, params.row); - break; - case 'tree:loadTreeAll': - await this.loadTree(params.dataset); - break; - // case 'event': { - // const { events, name, eventName } = params; - // params.datasetId = datasetId; - // if ((events && events.click) || name) { - // let _funName = null; - // if (events && events.click) { - // _funName = events.click; - // } else if (name || eventName) { - // _funName = eventName || name; - // } - // if (_funName && this[_funName]) { - // this[_funName](params); - // console.info(`call [${_funName}] function success`); - // } else { - // console.error(`dataset not found [${_funName}] function`); - // } - // } - // } - // break; - default: - console.log('unknown action', params); - break; - } - } - } - - onWidgetActionRemove(title: string, datasetName: string, ids: Array, otherArgsObj?: any, callFn?: Function) { - // console.log('onWidgetActionRemove', ids, ids.join()); - - confirm('删除确认', () => { - (async() => { - const ret = await this.doApi('cardDel', { - pageId: this.page.id, - dataset: datasetName, - ids: ids.join(), - }); - if (ret && (ret.data || ret.isSuccess)) { - const listData = this.loadDatasetData(datasetName).list.data; - let _mainField = null; - - if (otherArgsObj) { - _mainField = otherArgsObj.mainField; - } else { - _mainField = this.getIdFieldByDataset(datasetName); - } - - for (const id of ids) { - this._removeItem(listData, id, _mainField); - } - - callFn && callFn(); - notify.success('删除成功'); - } else { - notify.error('删除失败'); - } - })(); - }); - } - - // 处理事件 - doEvent(evtValue: IDatasetEvent) { - if (this.eventHandle) { - this.eventHandle(evtValue); - } - } - - getWidgetByName(name: string) { - if (this.page.widgets && name) { - Object.values(this.page.widgets).find((value: any) => { return value.name === name; }); - // for (const _key in this.page.widgets) { - // if (this.page.widgets[_key].name === name) { - // return this.page.widgets[_key]; - // } - // } - } - return null; - } - - updateData(params: any = {}) { - // 根据列表组件 更新 row 字段值 - const { dataset, id, fieldName, value } = params; - const ds = this.loadDatasetData(dataset); - const idField = this.getIdFieldByDataset(dataset); - if (ds && idField) { - const data = ds.list.data; - for (const _obj of data) { - if (_obj[idField] === id) { - _obj[fieldName] = value; - break; - } - } - } - } - - async init(loadLookup: boolean) { - const values = Object.values(this.page.datasets) as any[]; - - if (loadLookup) { - for (const dataset of values) { - if (dataset.tableType === 3) { - await this.loadDataset(dataset); - } - } - } - - for (const dataset of values) { - if (dataset.tableType === 1) { - await this.loadDataset(dataset); - } - } - // Object.values(this.page.datasets).forEach((dataset: any) => { - // if (dataset.tableType === 1 || dataset.tableType === 3) { // master/lookup - // this.loadDataset(dataset); - // } - // }); - } - - update(route: RouteLocationNormalizedLoaded) { - // title: this.$route.query.title, - // 页面参数 - const id = route.params.id as string; - - if (id !== this.params.id) { - this.params.id = id; - this.params.parentId = route.params.parentId as string; - this.init(false); - } - } -} - -export const useDataset = (props: any, data: any, page: any) => { - // console.log('useDataset', route.params); - const route = useRoute(); - - const pageDataset = new PageDataset(route, data, page); - - onMounted(() => { - pageDataset.init(true); - }); - - watch(() => props.id, () => { - pageDataset.update(route); - // console.log('watch', val, route.params); - }); - - // watch('$route.params.id', (val: any) => { - // console.log(page.id, val); - // }); - - return pageDataset; -}; diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/events.ts b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/events.ts deleted file mode 100644 index c9bff89..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/events.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {PageDataset} from './dataset'; - -export class PageEvents { - private dataset: PageDataset; - - constructor(dataset: PageDataset) { - this.dataset = dataset; - } - - onWidgetAction(datasetId: string, params: any) { - this.dataset.onWidgetAction(datasetId, params); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/formatter.ts b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/formatter.ts deleted file mode 100644 index f292db8..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/formatter.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 常用 table formatter 方法 - */ -export default { - methods: { - timeFormatter(row: string, column: any, cellValue: string) { - // 日期时间 - // temp 20210226113627 -> 2021-02-26 11:36:27 - if (cellValue && cellValue.length >= 14) { - const pattern = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/; - return cellValue.replace(pattern, '$1-$2-$3 $4:$5:$6'); - } else { - return cellValue || ''; - } - }, - statusFormatter(row: any, column: any, cellValue: any) { - if (cellValue === '0') { - return '正常'; - } else if (cellValue === '1') { - return '停用'; - } else if (cellValue === '2') { - return '锁定'; - } else { - return cellValue; - } - }, - }, -}; diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/page.less b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/page.less deleted file mode 100644 index 43509f2..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/page.less +++ /dev/null @@ -1,14 +0,0 @@ -.sw-container { - height: 100%; -} - -.sw-layout { - &-col1 {} - &-col2 {grid-column-start: span 2;} - &-col3 {grid-column-start: span 3;} - &-col4 {grid-column-start: span 4;} - &-col5 {grid-column-start: span 5;} - &-col6 {grid-column-start: span 6;} - &-col7 {grid-column-start: span 7;} - &-col8 {grid-column-start: span 8;} -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/page.types.ts b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/page.types.ts deleted file mode 100644 index f4d5425..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/ts/page.types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface IPageParams { - pageId: string - id?: string - parentId?: string -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/dataset.ts.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/dataset.ts.vm deleted file mode 100644 index f9295e7..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/dataset.ts.vm +++ /dev/null @@ -1,2 +0,0 @@ -// 数据集 -export default $vmTool.json($page.datasets); diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/events.ts.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/events.ts.vm deleted file mode 100644 index 52bc7d2..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/events.ts.vm +++ /dev/null @@ -1,6 +0,0 @@ -export default { - create({ pageDataset }) { - this.pageDataset = pageDataset; - } -} - diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/index.vue.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/index.vue.vm deleted file mode 100644 index 8d4cf15..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/index.vue.vm +++ /dev/null @@ -1,62 +0,0 @@ - - -#macro(printWidget $widget, $path) - <$widget.type - #if($widget.props.name && $widget.vars['$ref']) - ref="$widget.props.name.$ref" - #end - #if($widget.layout.col) - class="sw-layout-col$widget.layout.col" - #end - #foreach($prop in $widget.props.entrySet()) - #if($widget.vars[$prop.key]) - :$prop.key="wigets.$widget.props.name.$prop.key" - #else - $vmTool.htmlProp($prop.key, $prop.value) - #end - #end - #if($widget.props.dataset) - @action="onAction('$widget.props.dataset', $event)" - #end - #foreach($event in $widget.events.entrySet()) - @$event.key="onEvent('$widget.name', '$event.value', $event)" - #end - #if($widget.children) - > - #foreach($child in $widget.children) - #printWidget($child) - #end - - #else - /> - #end -#end - - - - - diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/router.ts.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/router.ts.vm deleted file mode 100644 index 007ce08..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/router.ts.vm +++ /dev/null @@ -1,17 +0,0 @@ -import {AppRouteRecordRaw} from "/@/router/types"; -// 导出根节点路由 -export const rootRoutes: AppRouteRecordRaw[] = []; -// 导出layout下的路由 -export const layoutRoutes: AppRouteRecordRaw[] = [ - #foreach($router in $routers) - { - path: "/$router.path", - name: "$router.name", - component: () => import("/@/pages/$router.filePath/index.vue"), - props: (route: any) => ({ json: route.params.json || "{}" }), - meta: { - title: "$router.title", - }, - }, - #end -]; diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/CardService.java.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/CardService.java.vm deleted file mode 100644 index 7411373..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/CardService.java.vm +++ /dev/null @@ -1,37 +0,0 @@ -package $package; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.system.bpm.core.ui.worker.IDatasetLoadWorker; -import cc.smtweb.system.bpm.core.ui.worker.IDatasetRemoveWorker; -import cc.smtweb.system.bpm.core.ui.worker.IDatasetSaveWorker; -import cc.smtweb.system.bpm.web.ui.DatasetCardService; - -import cc.smtweb.system.bpm.web.ui.DatasetCardService; - -/** - * 卡片数据模型服务 - * - * @author bpm - */ -@SwService -public class $className extends DatasetCardService { - @Override - protected String datasetPath() { - return "$resourceUrl/$dataset.name"; - } - - @Override - protected void onSetupLoad(IDatasetLoadWorker worker) { - // TODO 自定义表单读取处理方法 - } - - @Override - protected void onSetupSave(IDatasetSaveWorker worker) { - // TODO 自定义表单保存处理方法 - } - - @Override - protected void onSetupRemove(IDatasetRemoveWorker worker) { - // TODO 自定义表单删除处理方法 - } -} - diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/ListService.java.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/ListService.java.vm deleted file mode 100644 index 7e632ba..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/ListService.java.vm +++ /dev/null @@ -1,28 +0,0 @@ -package $package; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.system.bpm.core.ui.worker.IDatasetListAllWorker; -import cc.smtweb.system.bpm.core.ui.worker.IDatasetListPartWorker; -import cc.smtweb.system.bpm.web.ui.DatasetListService; - -/** - * 列表数据模型服务 - * - * @author bpm - */ -@SwService -public class $className extends DatasetListService { - @Override - protected String datasetPath() { - return "$resourceUrl"; - } - - @Override - protected void onSetupListPart(IDatasetListPartWorker worker) { - // TODO 自定义部分表(支持翻页)查询 - } - - @Override - protected void onSetupListAll(IDatasetListAllWorker worker) { - // TODO 自定义全表查询 - } -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/TreeService.java.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/TreeService.java.vm deleted file mode 100644 index 4542d58..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/TreeService.java.vm +++ /dev/null @@ -1,30 +0,0 @@ -package $package; - -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.system.bpm.core.ui.worker.IDatasetTreePartWorker; -import cc.smtweb.system.bpm.core.ui.worker.IDatasetTreeAllWorker; -import cc.smtweb.system.bpm.web.ui.DatasetTreeService; - -/** - * 树数据模型服务 - * - * @author LowCode - */ -@SwService -public class $className extends DatasetTreeService { - @Override - protected String datasetPath() { - return "$resourceUrl"; - } - - @Override - protected void onSetupTreePart(IDatasetTreePartWorker worker) { - // TODO 自定义部分树(延迟加载)查询 - }; - - @Override - protected void onSetupTreeAll(IDatasetTreeAllWorker worker) { - // TODO 自定义全树查询 - }; -} - diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/entity.java.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/entity.java.vm deleted file mode 100644 index 7d8be58..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/entity.java.vm +++ /dev/null @@ -1,23 +0,0 @@ -package $package; -import cc.smtweb.framework.core.annotation.SwColumn; -import cc.smtweb.framework.core.annotation.SwTable; -import lombok.Data; -/** - * 以下是机器生成代码,请勿修改! - * - * @author LowCode - * $table.name - * $table.remark - */ -@Data -@SwTable("$table.dbName.$table.name") -public class $vmTool.toUpperHump($table.name) { - #foreach($field in $table.fields) - /** $field.label $!{field.remark} */ - #if ($field.name == $table.idField) - @SwColumn(type = SwColumn.Type.ID) - #end - private $vmTool.javaType($field.dataType) $vmTool.toHump($field.name); - #end -} - diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/event.js.vm b/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/event.js.vm deleted file mode 100644 index 31a8031..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/codegen/vm/server/event.js.vm +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 页面 ${url} 事件处理,有默认属性: - * $refs map, 控件ref引用,可以访问控件函数 - * $model map, 数据集对象 - * $widgets map, 控件响应变量 - */ -window["$swEvent"].setup("$url", { - /** - * FxPage的setup中调用的初始化对象函数 - * @param props FxPage的控件属性,其中用页面params参数 - * @param context FxPage的vue3上下文对象,包括常用的emit事件属性 - */ - init(props, context) { - }, - - page$onMounted(e) { - }, - - page$onUnmounted(e) { - }, - -#foreach($child in $events) - ${child}(e) { - console.log("${child}", e); - }, - -#end -}); diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/config/application.yaml b/smtweb-framework/sw-system-bpm/src/main/resources/config/application.yaml deleted file mode 100644 index 3c54545..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/config/application.yaml +++ /dev/null @@ -1,43 +0,0 @@ -smtweb: - machine-id: 1 - file: - local-path: /data/sw/files/ - url: http://127.0.0.1:8888/sw/files/ - bpm: - debug: true - code-java-path: 'e:/jujia/git/6.0/smtweb2/smtweb-framework' - db: - type: mysql - default: - rule: - prefix: _smt_ - replace: smt_ -server: - port: 8888 - servlet: - context-path: / -logging: - level: - root: INFO - cc.smtweb: DEBUG -spring: - redis: - host: 127.0.0.1 - port: 6379 - password: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/smt_asp?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false - username: root - password: root - servlet: - multipart: - max-file-size: 104857600000 - max-request-size: 10485760000000 - cache: - type: caffeine - cache-names: - - core - - bpm - caffeine: - spec: maximumSize=1024,expireAfterWrite=2h diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/config/logback.xml b/smtweb-framework/sw-system-bpm/src/main/resources/config/logback.xml deleted file mode 100644 index ddd583f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/config/logback.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/event/defaultEvent.js b/smtweb-framework/sw-system-bpm/src/main/resources/static/event/defaultEvent.js deleted file mode 100644 index 87f0f6e..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/event/defaultEvent.js +++ /dev/null @@ -1,87 +0,0 @@ -// 注册事件类 -window.$swEvent.setup("defaultEvent", { - /** - * - * @param page 当前页面对象 - * 1)page.$params 参数对象 - * 示例:给参数p1赋值: page.$params.p1 = “xxxx”; - * - * 2)page.$refs 控件的ref引用,ref引用指向控件的实例,可访问控件实例的属性和函数 - * 示例:调用页面的 标签的validate方法: page.$refs.form1.validate() - * - * 3)page.$model 数据集,内含data(数据对象)和dataset(数据集定义) - * 示例: 获取数据集ds1的表单数据 page.$model.ds1.data.form - * 获取数据集ds1的列表数据 page.$model.ds1.data.list - * 获取数据集ds1表单中a1的值 page.$model.ds1.getFormVal("a1") - * 给数据集ds1的表中的a1赋值 page.$model.ds1.setFormVal("a1","xxxx"); - * - * 4)page.$widgets 控件的属性,控制控件的响应属性 - * 示例 : 获取控件名为w1的required属性的值 page.$widgets.w1.required - * - * 5)page.$utils 工具包 - * $$message 消息提示 - * $$cookie, cookie - * $$driver, 用户操作引导引擎 - * $$http, http请求 - * $$validate, 校验 - * $$date, 日期处理工具 - * $$UtilPub, 其他 - * 示例: - * 弹出成功消息框:page.$utils.$$message.notify.success("xxx") - * post请求:page.$utils.$$http.post("/api/bpm/save",{id:"xxx"}) - * - * 6)page.$tabRouter 页面路由,控制页面切换 - * 示例:跳转到登录页:page.$tabRouter.push("login"); - * 返回: page.$tabRouter.back(); - * - * 7) page.$api 页面提供的公用api - * add: () => void 页面新增初始化(所有可编辑的数据集) - * addOne: (dataset: string) => void 指定数据集新增初始 - * load: (force?: boolean, params?: any) => void // 页面加载 - * loadOne: (dataset: string, params?: any) => void // 指定数据集加载 - * total: (dataset: string, params?: any) => void // 指定数据集求合计栏信息 - * save: (params?: any) => void // 页面保存 (所有可编辑的数据集) - * saveOne: (dataset: string, params?: any) => void // 指定数据集保存 - * del: () => void 页面删除 - * delOne: (dataset: string, row?: any) => void // 指定数据集删除 - * closeDialog: (dialogKey?: string) => void // 关闭弹出框 - * 示例: - * 加载数据集ds1:page.$api.loadOne("ds1"); - * - * @returns 返回给页面可配置的api方法 - * 如 : return { - * demoFunc(){ - * XXXX - * }, - * } - */ - setup(page){ - const { $params,$refs, $widgets, $model, $utils, $tabRouter, $api } = page; - const { $$message, $$http } = $utils || {}; - // 示例 - const demoFunc = () => { - // 1.从参数中获取p1 - const p1 = $params.p1; - // 2.从控件w1获取color属性 - const color = $widgets.w1.props.color; - // 3.调用控件w1的calc函数 - const calcVal = $refs.w1.calc(p1,color); - // 4.数据集ds1加载数据 - $api.loadOne("ds1"); - // 5.给数据集ds1的表单中的f1字段赋值calcVal - $model.ds1.setFormVal("f1",calcVal); - // 6.获取数据集ds1的表单数据 - const data = $model.ds1.data.form || {}; - // 7.调用http交互 - $$http.post("ap1/demo/doOpt",data).then((rt) => { - // 8.弹出成功消息 - $$message.notify.success("操作成功"); - // 9.返回上一个页面 - $tabRouter.back(); - }); - }; - return { - demoFunc, - } - } -}); diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/index.html b/smtweb-framework/sw-system-bpm/src/main/resources/static/index.html deleted file mode 100644 index 2042999..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - BPM - - - - - diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/demo.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/demo.ftl deleted file mode 100644 index f29f6b9..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/demo.ftl +++ /dev/null @@ -1,5 +0,0 @@ -{ - "form": [ - { - "page": { - "id": "p \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_filter.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_filter.ftl deleted file mode 100644 index f4bb800..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_filter.ftl +++ /dev/null @@ -1,76 +0,0 @@ -<#assign fields = group.cfilters> - { - "id": "${newId()}", - "type": "fx-form-panel", - "shape": "panel", - "props": { - "paddingY": 5, - "paddingX": 10, - "size": "35", - "colNum": 2 - }, - "children": [ -<#list fields as filter> - { - "id": "id${newId()}", - "type": "fx-${filter.editor}", - "props": { - "label": "${filter.label}", - "type": "text", - <#if filter.maxlength gt 0> - "maxlength": ${filter.maxlength}, - - "placeholder": "请输入查询内容", - "labelWidth": 100, - "dataset": "${filter.dataset}", - "field": "${filter.id}", - "name": "${filter.name}" - }, - "events": {} - }, - - { - "id": "id${newId()}", - "type": "fx-button-group", - "props": { - "menus": [] - }, - "slots": { - "default": [ - { - "type": "fx-button", - "props": { - "label": "查询", - "leftIcon": "history-query", - "type": "primary", - "action": "button:search", - "dataset": "${group.dataset}" - }, - "id": "id${newId()}" - }, - { - "type": "fx-button", - "props": { - "label": "重置", - "type": "danger", - "action": "button:reset", - "leftIcon": "figma-reset-instance" - }, - "id": "id${newId()}" - }, - { - "id": "id${newId()}", - "type": "fx-button", - "props": { - "label": "新增", - "type": "success", - "leftIcon": "shield-add", - "action": "button:add", - "dataset": "${group.dataset}" - } - } - ] - } - } - ] - }, \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_form.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_form.ftl deleted file mode 100644 index 5ef0af9..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_form.ftl +++ /dev/null @@ -1,33 +0,0 @@ -<#assign fields = group.fields> - { - "shape": "panel", - "id": "form_panel", - "type": "fx-form-panel", - "props": { - "colNum": 2, - "paddingX": 5, - "paddingY": 5, - "size": "0" - }, - "children": [ -<#list fields as field> - { - "id": "id${newId()}", - "type": "fx-${field.editor}", - "props": { - "label": "${field.label}", - "type": "text", - <#if field.maxlength gt 0> - "maxlength": ${field.maxlength}, - - "placeholder": "请输入内容", - "labelWidth": 100, - "dataset": "${field.dataset}", - "field": "${field.id}", - "name": "${field.name}" - }, - "events": {} - }<#if field_has_next>, - - ] - } \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_grid_opt.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_grid_opt.ftl deleted file mode 100644 index 70220b4..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_grid_opt.ftl +++ /dev/null @@ -1,67 +0,0 @@ -{ - "shape": "panel", - "id": "form_panel", - "type": "fx-form-panel", - "props": { - "colNum": 0, - "paddingX": 5, - "paddingY": 5, - "align": "full" - }, - "children": [ - { - "id": "id${newId()}", - "type": "fx-table", - "props": { - "label": "表格", - "border": true, - "stripe": true, - "showHeader": true, - "fit": true, - "dataset": "${group.dataset}", - "actionWidth": 120 - }, - "slots": { -<#assign fields = group.fields> - "default": [ -<#list fields as col> - { - "id": "id${newId()}", - "type": "fx-table-column", - "props": { - "field": "${col.id}", - "label": "${col.label}" - } - }<#if col_has_next>, - - ], - "button": [ - { - "type": "fx-button", - "props": { - "label": "编", - "type": "text", - "leftIcon": "edit", - "action": "button:edit", - "linkType": "dialog", - "dataset": "${group.dataset}" - }, - "id": "id1813718bf36" - }, - { - "type": "fx-button", - "props": { - "label": "删", - "type": "text", - "leftIcon": "delete", - "action": "button:del", - "dataset": "${group.dataset}" - }, - "id": "id${newId()}" - } - ] - }, - "events": {} - } - ] - } \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_model.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_model.ftl deleted file mode 100644 index bdda13c..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/incModel/inc_model.ftl +++ /dev/null @@ -1,28 +0,0 @@ -{ - "dataset": "${dataset.id}", - "label": "${dataset.label}", - "fields": [ - <#list dataset.fields as field> - { - "id": "${field.id}", - "field": "${field.field}"<#if field.widget gt 0>, - "lookup": { - "widgetId": "${field.widget?c}", - "widgetId_text": "${field.widgetText}", - "filters": [] - } - - }<#if field_has_next>, - - ], - "filters": [ - <#list dataset.filters as field> - { - "id": "${field.id}", - "field": "${field.field!0}", - "required": ${field.required?string ("true","false")}, - "type": "input" - }<#if field_has_next>, - - ] - } \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/index.yaml b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/index.yaml deleted file mode 100644 index 8e2128e..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/index.yaml +++ /dev/null @@ -1,35 +0,0 @@ -model: - - - name: 'model_list' - label: '简单列表' - # list/card/view - type: 'list' - # 布局 - layout: - - - name: 'c1' - label: '简单列表' - type: 'list' - hasGroup: false - # 变量 - param: - - - name: 'queryDs' - type: 'ds' - - - name: 'model_card' - label: '简单卡片' - # list/card/view - type: 'card' - # 布局 - layout: - - - name: 'c1' - label: '客户区' - type: 'card' - hasGroup: false - # 变量 -# param: -# - -# name: 'p1' -# type: 'ds' diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_bean.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_bean.ftl deleted file mode 100644 index eca1672..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_bean.ftl +++ /dev/null @@ -1,42 +0,0 @@ -package ${packageName}; - -import cc.smtweb.framework.core.annotation.SwTable; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.impl.DefaultEntity; - -/** - * Created by ${user} at ${sysTime} - * 实体【[${tableTitle}](${tableName})】的Entity类 - */ -@SwTable("${tableName}") -public class ${beanName} extends DefaultEntity { - public static final String ENTITY_NAME = "${tableName}"; - - public ${beanName}() { - super(ENTITY_NAME); - } - - <#list fields as field> - <#if field.javaType == "boolean"> - /** ${field.title} */ - public boolean is${field.javaName}() { - return getBool("${field.name}"); - } - - /** ${field.title} */ - public void set${javaName}(boolean ${field.name}) { - setBool("${field.name}", ${field.name}); - } - <#else > - /** ${field.title} */ - public ${field.javaType} get${field.javaName}() { - return get${field.shortJavaType}("${field.name}"); - } - - /** ${field.title} */ - public void set${field.javaName}(${field.javaType} ${field.name}) { - put("${field.name}", ${field.name}); - } - - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_cache.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_cache.ftl deleted file mode 100644 index 81fc0ad..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_cache.ftl +++ /dev/null @@ -1,51 +0,0 @@ -package ${packageName}; - -import cc.smtweb.framework.core.annotation.SwCache; -import cc.smtweb.framework.core.cache.AbstractEntityCache; -import cc.smtweb.framework.core.cache.CacheManager; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Set; - -/** - * Created by ${user} at ${sysTime} - * 实体【[${tableTitle}](${tableName})】的缓存类 - */ -@SwCache(ident = "${tableName}", title = "${tableTitle}") -public class ${beanName}Cache extends AbstractEntityCache<${beanName}> { -<#list caches as cache> - //缓存key:${cache.title} - public final static String mk_${cache.name} = "${cache.name}"; - - - public static ${beanName}Cache getInstance() { - return CacheManager.getIntance().getCache(${beanName}Cache.class); - } - - public ${beanName}Cache() { -<#list caches as cache> - //缓存key:${cache.title} - <#if cache.type=="M"> - regMap(mk_${cache.name}, "${cache.fields}"); - <#else> - regList(mk_${cache.name}, "${cache.fields}"); - - - } - -<#list caches as cache> - <#if cache.type=="M"> - //缓存key:${cache.title} - public final ${beanName} getBy${cache.nameUF}(String key) { - return getByKey(mk_${cache.name}, key); - } - <#else> - //缓存key:${cache.title} - public final Set<${beanName}> getBy${cache.nameUF}(String key) { - return getListByKey(mk_${cache.name}, key); - } - - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_service.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_service.ftl deleted file mode 100644 index aff420f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/java_service.ftl +++ /dev/null @@ -1,30 +0,0 @@ -package ${packageName}; - -import cc.smtweb.framework.core.annotation.SwBody; -import cc.smtweb.framework.core.annotation.SwService; -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.system.bpm.web.engine.dynPage.DynPageService; -import cc.smtweb.framework.core.mvc.service.AbstractHandler; -import cc.smtweb.framework.core.session.UserSession; - -/** - * Created by ${user} at ${sysTime} - * 页面【[${formTitle}]的服务类 - */ -@SwService -public class ${service}Service extends DynPageService { - //public final static String TYPE_DEMO = "demo"; - @Override - protected AbstractHandler createHandler(String type) { - return super.createHandler(type); - } - -/* demo - //自定义 - public R demo(@SwBody SwMap params, UserSession us) { - return pageHandler(params, us, TYPE_DEMO, handler -> ((DemoHandler)handler).demo()); - } -*/ - -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/js_event.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/js_event.ftl deleted file mode 100644 index d74d428..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/js_event.ftl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Created by ${user} at ${sysTime} - * 注册事件类【${title}】,参看event.defaultEvent.js -*/ -window.$swEvent.setup("${eventPath}", { - setup(page){ - const { $params,$refs, $widgets, $model, $utils, $tabRouter, $api } = page; - const { $$message, $$http } = $utils; - // 示例 - const demoFunc = () => { - - }; - return { - demoFunc, - } - } -}); \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_card.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_card.ftl deleted file mode 100644 index 713b23f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_card.ftl +++ /dev/null @@ -1,116 +0,0 @@ -{ - "form": [ - { - "page": { - "id": "p${newId()}", - "type": "fx-page", - "props": { - "title": "${title}", - "key": "${newId()}" - } - }, - "graph": { - "shape": "panel", - "id": "root_panel", - "type": "fx-split-panel", - "props": { - "horizontal": false, - "shadow": "never" - }, - "children": [ -<#list layout.c1 as group> - <#if (group.type == "list")> - <#if (group.cfilters?size>0)> - <#include "incModel/inc_filter.ftl"/> - - <#include "incModel/inc_grid_opt.ftl"/> - <#elseif (group.type == "card")> - <#include "incModel/inc_form.ftl"/> - , - -{ - "id": "${newId()}", - "type": "fx-form-panel", - "shape": "panel", - "props": { - "paddingY": 3, - "paddingX": 10, - "size": 20 - }, - "children": [ - { - "id": "id${newId()}", - "type": "fx-button-group", - "props": { - "menus": [], - "textAlign": "center" - }, - "slots": { - "default": [ - { - "type": "fx-button", - "props": { - "label": "新增", - "leftIcon": "plus", - "type": "primary", - "action": "button:add" - }, - "id": "id${newId()}" - }, - { - "type": "fx-button", - "props": { - "label": "保存并新增", - "type": "primary", - "action": "button:saveAndAdd" - }, - "id": "id${newId()}" - }, - { - "type": "fx-button", - "props": { - "label": "保存", - "leftIcon": "save", - "type": "success", - "action": "button:save" - }, - "id": "id${newId()}" - }, - { - "type": "fx-button", - "props": { - "label": "删除", - "leftIcon": "delete", - "type": "danger", - "action": "button:remove" - }, - "id": "id${newId()}" - }, - { - "type": "fx-button", - "props": { - "label": "返回", - "leftIcon": "return", - "action": "button:return" - }, - "id": "id${newId()}" - } - ] - } - } - ] - } - ] - } - } - ], - "model": [ -<#list datasets as dataset> - <#include "incModel/inc_model.ftl"/><#if dataset_has_next>, - - ], - "option": { - "widgetRef": [${widgetRef}], - "vars": [] - } -} \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_list.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_list.ftl deleted file mode 100644 index 1399c2f..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_list.ftl +++ /dev/null @@ -1,392 +0,0 @@ -{ -<#list layout.c1 as group> - "form": - [ - { - "page": { - "id": "p${newId()}", - "type": "fx-page", - "props": { - "title": "${title}", - "key": "${newId()}" - } - }, - "graph": { - "shape": "panel", - "id": "root_panel", - "type": "fx-split-panel", - "props": { - "horizontal": false, - "shadow": "" - }, - "children": [ - { - "shape": "panel", - "id": "form_panel", - "type": "fx-form-panel", - "props": { - "colNum": 3, - "name": "query", - "label": "按钮区", - "size": "80", - "shadow": "", - "alignY": "center", - "paddingRight": 10 - }, - "children": [ - - <#if (group.cfilters?size>0)> - <#assign fields = group.cfilters> - <#list fields as filter> - { - "id": "id${newId()}", - "type": "fx-${filter.editor}", - "props": { - "label": "${filter.label}", - "type": "text", - <#if filter.maxlength gt 0> - "maxlength": ${filter.maxlength}, - - "placeholder": "请输入查询内容", - "labelWidth": 100, - "dataset": "${filter.dataset}", - "field": "${filter.id}", - "name": "${filter.name}" - }, - "events": {} - }, - - - - { - "id": "id${newId()}", - "type": "fx-button-group", - "props": { - "menus": [], - "textAlign": "right" - }, - "slots": { - "default": [ - { - "type": "fx-button", - "props": { - "label": "重置", - "leftIcon": "clear", - "type": "", - "action": "button:reset", - "dataset": "", - "link": false, - "linkType": "" - }, - "id": "id${newId()}" - }, - { - "type": "fx-button", - "props": { - "label": "查询", - "leftIcon": "search", - "type": "primary", - "action": "button:search", - "dataset": "${param.queryDs}" - }, - "id": "id${newId()}" - } - <#if (group.sfilters?size>0)> - ,{ - "type": "fx-button", - "props": { - "label": "高级筛选", - "leftIcon": "hamburger-button", - "action": "button:link", - "link": true, - "linkType": "drawer", - "fxLink": "dialog:qrueydialog" - }, - "id": "id${newId()}" - } - - ] - }, - "layout": { - "col": 1 - } - } - ] - }, - { - "id": "${newId()}", - "type": "fx-form-panel", - "shape": "panel", - "props": { - "size": "20", - "backgroundColor": "transparent" - }, - "children": [] - }, - { - "id": "${newId()}", - "type": "fx-form-panel", - "shape": "panel", - "props": { - "size": "68", - "label": "查询条件", - "colNum": 2, - "alignY": "center", - "paddingLeft": 32, - "paddingRight": 32, - "shadow": "" - }, - "children": [ - { - "id": "id${newId()}", - "type": "fx-title", - "props": { - "label": "${title}", - "fontSize": 16, - "color": "#01070D", - "fontWeight": "bold", - "showPrefix": false, - "prefixWidth": 5, - "prefixHeight": 24, - "prefixColor": "#1E90FF" - } - }, - { - "id": "id${newId()}", - "type": "fx-button-group", - "props": { - "menus": [], - "textAlign": "right" - }, - "slots": { - "default": [ - { - "type": "fx-button", - "props": { - "label": "新增", - "leftIcon": "plus", - "type": "primary", - "action": "button:add", - "link": false, - "linkType": "", - "fxLink": "", - "dataset": "" - }, - "id": "id${newId()}" - } - ] - } - } - ] - }, - { - "id": "${newId()}", - "type": "fx-form-panel", - "shape": "panel", - "props": { - "size": "", - "label": "列表", - "colNum": 0, - "paddingLeft": 32, - "paddingRight": 32, - "shadow": "" - }, - "children": [ - { - "id": "id${newId()}", - "type": "fx-table", - "props": { - "label": "表格", - "border": true, - "stripe": true, - "showHeader": true, - "fit": true, - "dataset": "${group.dataset}", - "actionWidth": 150 - }, - "slots": { - <#if (group.fields?size>0)> - <#assign fields = group.fields> - "default": [ - <#list fields as col> - { - "id": "id${newId()}", - "type": "fx-table-column", - "props": { - "field": "${col.id}", - "label": "${col.label}" - } - }<#if col_has_next>, - - ], - - "button": [ - { - "type": "fx-button", - "props": { - "label": "编辑", - "type": "text", - "leftIcon": "edit", - "action": "button:edit", - "dataset": "", - "link": true, - "linkType": "", - "nextAction": "", - "fxLink": "" - }, - "id": "id${newId()}" - }, - { - "type": "fx-button", - "props": { - "label": "删除", - "type": "text", - "leftIcon": "delete-themes", - "action": "button:remove", - "preAction": "", - "link": true, - "confirm": "" - }, - "id": "id${newId()}" - } - ] - }, - "events": {} - } - ] - }, - { - "id": "${newId()}", - "type": "fx-form-panel", - "shape": "panel", - "props": { - "size": "24", - "backgroundColor": "transparent" - }, - "children": [] - } - ] - } - }, - { - "page": { - "id": "id${newId()}", - "type": "fx-dialog", - "props": { - "title": "查询条件", - "key": "qrueydialog", - "destroyOnClose": true, - "closeOnClickModal": true, - "width": "20%", - "height": "" - }, - "events": { - } - } - <#if (group.sfilters?size>0)> - ,"graph": { - "shape": "panel", - "id": "root_panel", - "type": "fx-split-panel", - "props": { - "horizontal": false, - "shadow": "never" - }, - "children": [ - { - "shape": "panel", - "id": "form_panel", - "type": "fx-form-panel", - "props": { - "colNum": 1, - "name": "query", - "label": "查询条件", - "size": "", - "paddingTop": 20, - "scroll": true - }, - "children": [ - - <#assign fields = group.sfilters> - <#list fields as filter> - { - "id": "id${newId()}", - "type": "fx-${filter.editor}", - "props": { - "label": "${filter.label}", - "type": "text", - <#if filter.maxlength gt 0> - "maxlength": ${filter.maxlength}, - - "placeholder": "请输入查询内容", - "labelWidth": 100, - "dataset": "${filter.dataset}", - "field": "${filter.id}", - "name": "${filter.name}" - }, - "events": {} - } - <#if filter_has_next>, - - - ] - }, - { - "id": "${newId()}", - "type": "fx-form-panel", - "shape": "panel", - "props": { - "size": "56", - "alignY": "center" - }, - "children": [ - { - "id": "id${newId()}", - "type": "fx-button-group", - "props": { - "menus": [], - "textAlign": "center" - }, - "slots": { - "default": [ - { - "type": "fx-button", - "props": { - "label": "重置", - "leftIcon": "clear", - "action": "button:return" - }, - "id": "id${newId()}" - }, - { - "type": "fx-button", - "props": { - "label": "查询", - "leftIcon": "save", - "type": "success", - "action": "button:search", - "dataset": "${param.queryDs}" - }, - "id": "id${newId()}" - } - ] - } - } - ] - } - ] - } - - } - ], - -"model": [ -<#list datasets as dataset> - <#include "incModel/inc_model.ftl"/><#if dataset_has_next>, - -], -"option": { -"widgetRef": [${widgetRef}], -"vars": [] -} -} diff --git a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_simple.ftl b/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_simple.ftl deleted file mode 100644 index 7973c99..0000000 --- a/smtweb-framework/sw-system-bpm/src/main/resources/static/template/model_simple.ftl +++ /dev/null @@ -1,45 +0,0 @@ -{ - "form": [ - { - "page": { - "id": "p${newId()}", - "type": "fx-page", - "props": { - "title": "${title}", - "key": "${newId()}" - } - }, - "graph": { - "shape": "panel", - "id": "root_panel", - "type": "fx-split-panel", - "props": { - "horizontal": false, - "shadow": "never" - }, - "children": [ -<#list layout.c1 as group> - <#if (group.type == "list")> - <#if (group.cfilters?size>0)> - <#include "incModel/inc_filter.ftl"/> - - <#include "incModel/inc_grid_opt.ftl"/> - <#elseif (group.type == "card")> - <#include "incModel/inc_form.ftl"/> - - <#if group_has_next>, - - ] - } - } - ], - "model": [ -<#list datasets as dataset> - <#include "incModel/inc_model.ftl"/><#if dataset_has_next>, - - ], - "option": { - "widgetRef": [${widgetRef}], - "vars": [] - } -} \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/BpmTest.java b/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/BpmTest.java deleted file mode 100644 index c408dcb..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/BpmTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package cc.smtweb.system.bpm.test; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.mvc.controller.MethodAccessManager; -import cc.smtweb.system.bpm.spring.BpmApplication; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import java.util.Map; - -@ExtendWith(SpringExtension.class) -@SpringBootTest(classes = {BpmApplication.class}) -public class BpmTest { - @Autowired - private MethodAccessManager methodAccessManager; - - private R invoke(String url, Map body) throws Exception { -// Map params = new HashMap<>(); -// return methodAccessManager.invokeDirect(url, params, JsonUtil.encodeString(body)); - return null; - } - - @Test - public void load() throws Exception { - R r = invoke("bpm/BpmTaskCard/load", SwMap.of("flowId", 476347272070696960L)); - - System.out.println(r); - - Assertions.assertEquals(0, r.readInt("code")); - Assertions.assertNotEquals(null, r.get("data")); - } - -} diff --git a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/BuildJavaBean.java b/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/BuildJavaBean.java deleted file mode 100644 index be57d3a..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/BuildJavaBean.java +++ /dev/null @@ -1,54 +0,0 @@ -package cc.smtweb.system.bpm.test; - -import cc.smtweb.system.bpm.util.CodeGenUtil; -import org.apache.commons.lang3.StringUtils; -import org.junit.Test; - -/** - * Created by Akmm at 2022/3/1 9:41 - * 生成bean - */ -public class BuildJavaBean { - @Test - public void buildBean() { - String str = "`trl_id` bigint(20) NOT NULL COMMENT 'null',\n" + - " `trl_pri_id` bigint(20) DEFAULT NULL COMMENT 'null',\n" + - " `trl_src_task_id` bigint(20) DEFAULT NULL COMMENT 'null',\n" + - " `trl_dst_task_id` bigint(20) DEFAULT NULL COMMENT 'null',\n"; - String[] ss = str.split("\n"); - for (String s: ss) { - String[] s0 = s.trim().split(" "); - if (StringUtils.isEmpty(s0[0])) continue; - String tn = s0[0].substring(1, s0[0].indexOf("`", 2)); - String tnu = CodeGenUtil.underlineToUpperHump(tn.substring(tn.indexOf("_") + 1)); - String tnn = CodeGenUtil.underlineToHump(tn); - - String tt = s0[1]; - String ttj; - if (tt.contains("(")) tt = tt.substring(0, tt.indexOf("(")); - switch (tt) { - case "bigint": - tt = "long"; - ttj = "Long"; - break; - case "tinyint": - case "smallint": - case "int": - tt = "int"; - ttj = "Int"; - break; - default: - tt = "String"; - ttj = "Str"; - break; - } - System.out.println("public " + tt + " get" + tnu + "(){\n" + - "return get" + ttj + "(\"" + tn + "\");\n" + - "}\n" + - "" + - "public void set" + tnu + "(" + tt + " " + tnn + "){\n" + - "put(\"" + tn + "\", " + tnn + ");\n" + - "}\n"); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/HexTest.java b/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/HexTest.java deleted file mode 100644 index 277a042..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/HexTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package cc.smtweb.system.bpm.test; - -import org.apache.commons.codec.binary.Hex; -import org.junit.jupiter.api.Test; - -import java.io.FileInputStream; -import java.nio.charset.StandardCharsets; -import java.util.HashSet; -import java.util.Set; - -public class HexTest { - - @Test - public void hexToText() throws Exception { - - FileInputStream fis = new FileInputStream("/var/1.txt"); - - byte[] data = new byte[2 * 1024 * 1024]; - int len = fis.read(data); - - byte[] buf = Hex.decodeHex(new String(data, 0, len)); - - System.out.println(new String(buf, StandardCharsets.UTF_8)); - } - - @Test - public void joinTest() { - Set ids = new HashSet<>(); - ids.add("1"); - ids.add("2"); - ids.add("3"); - ids.add("1"); - - System.out.println(String.join(",", ids)); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/ModelFormTest.java b/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/ModelFormTest.java deleted file mode 100644 index f1b4be8..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/ModelFormTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package cc.smtweb.system.bpm.test; - -import cc.smtweb.framework.core.common.R; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.system.bpm.spring.BpmApplication; -import cc.smtweb.system.bpm.web.design.form.ModelForm; -import cc.smtweb.system.bpm.web.design.form.ModelFormHelper; -import cc.smtweb.system.bpm.web.design.form.ModelFormService; -import cc.smtweb.system.bpm.web.engine.dynPage.DynPageService; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Akmm at 2022/4/26 9:46 - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = BpmApplication.class) -public class ModelFormTest { - @Test - public void testLoad() { - SwMap params = new SwMap(); - params.put("pageId", 1); - params.put("dataset", "modelProject"); - SwMap filter = new SwMap(); - filter.put("prj_name", "测试"); - params.put("filter", filter); - DynPageService service = new DynPageService(); - R r = service.load(params, null); - System.out.println(r.readSuccess()); - } - - @Test - public void testSave() { - //{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}} - SwMap params = new SwMap(); - params.put("pageId", 1); - params.put("dataset", "modelProject"); - SwMap data = new SwMap(); - SwMap form = new SwMap(); - form.put("prj_id", "12345"); - form.put("prj_name", "test12345"); - form.put("prj_desc", "this is test12345"); - data.put("form", form); - params.put("data", data); - SwMap filter = new SwMap(); - filter.put("prj_name", "测试"); - params.put("filter", filter); - DynPageService service = new DynPageService(); - R r = service.saveOne(params, null); - System.out.println(r.readSuccess()); - } - - @Test - public void testDel() { - //{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}} - SwMap params = new SwMap(); - params.put("pageId", 1); - params.put("id", 12345); - - DynPageService service = new DynPageService(); - R r = service.del(params, null); - System.out.println(r.readSuccess()); - } - - @Test - public void testBuildModelByTmpl() { - ModelForm form = new ModelForm(); - form.setTitle("测试呀"); - form.setDataset("[{\"id\":\"ds_18147381016\",\"name\":\"master\",\"label\":\"主数据集\",\"type\":\"form\",\"masterTable\":\"2\",\"masterTable_text\":\"目录\",\"idField\":\"mc_id\",\"lazy\":false,\"canEdit\":true,\"fields\":[{\"id\":\"id_1814738101b\",\"table\":\"2\",\"field\":\"mc_id\",\"name\":\"mc_id\",\"fieldType\":1,\"notNull\":1,\"link\":\"0\"},{\"id\":\"id_1814738101c\",\"table\":\"2\",\"field\":\"mc_parent_id\",\"name\":\"mc_parent_id\",\"fieldType\":4,\"notNull\":0,\"link\":\"2\"},{\"id\":\"id_1814738101d\",\"table\":\"2\",\"field\":\"mc_level_code\",\"name\":\"mc_level_code\",\"fieldType\":5,\"notNull\":0,\"link\":\"0\"},{\"id\":\"id_1814738101e\",\"table\":\"2\",\"field\":\"mc_prj_id\",\"name\":\"mc_prj_id\",\"fieldType\":0,\"notNull\":1,\"link\":\"1\"},{\"id\":\"id_1814738101f\",\"table\":\"2\",\"field\":\"mc_code\",\"name\":\"mc_code\",\"fieldType\":2,\"notNull\":0,\"link\":\"0\"},{\"id\":\"id_18147381020\",\"table\":\"2\",\"field\":\"mc_name\",\"name\":\"mc_name\",\"fieldType\":3,\"notNull\":0,\"link\":\"0\"}],\"filters\":[],\"data\":[],\"dynCond\":{\"opt\":\"and\"},\"sortFields\":[]}]"); - form.setTmpl("{\"param\":{},\"layout\":{\"c1\":[{\"id\":\"id18147381019\",\"name\":\"group1\",\"label\":\"分组1\",\"type\":\"card\",\"fields\":[{\"field\":\"id_1814738101c\",\"field_text\":\"mc_parent_id\",\"field_label\":\"父ID\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"},{\"field\":\"id_1814738101d\",\"field_text\":\"mc_level_code\",\"field_label\":\"级次码\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"},{\"field\":\"id_1814738101e\",\"field_text\":\"mc_prj_id\",\"field_label\":\"所属项目\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"},{\"field\":\"id_1814738101f\",\"field_text\":\"mc_code\",\"field_label\":\"编码\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"},{\"field\":\"id_18147381020\",\"field_text\":\"mc_name\",\"field_label\":\"编码\",\"dataset\":\"ds_18147381016\",\"dataset_text\":\"master\"}],\"sfilters\":[],\"cfilters\":[]}]}}"); - ModelFormHelper.buildSaveModelByTmpl(form, "model_simple"); - System.out.println(form.getContent()); - } - - @Test - public void testBuildJavaBean() { - //{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}} - SwMap params = new SwMap(); - params.put("pageId", 718479207767740416L); - params.put("service", true); - List table = new ArrayList<>(); - params.put("table", table); - SwMap map = new SwMap(); - map.put("tableId", 718391823709507584L); - map.put("bean", true); - map.put("cache", true); - table.add(map); - - ModelFormService service = new ModelFormService(); - R r = service.buildJavaCode(params, null); - System.out.println(r.readSuccess()); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/SpelTest.java b/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/SpelTest.java deleted file mode 100644 index ad0990f..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/SpelTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package cc.smtweb.system.bpm.test; - -import cc.smtweb.framework.core.common.SwMap; -import lombok.Data; -import org.junit.jupiter.api.Test; -import org.springframework.expression.Expression; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; - -public class SpelTest { - @Test - public void test() { - //创建ExpressionParser解析表达式 - ExpressionParser parser = new SpelExpressionParser(); - //表达式放置 -// Expression exp = parser.parseExpression("T(java.lang.Math).random() + name + obj['name']"); - Expression exp = parser.parseExpression("T(java.lang.Math).random() > 10"); - - //向容器内添加bean - SpelContext spelContext = new SpelContext(); - spelContext.setName("ddd999"); - spelContext.getObj().put("name", "111abc"); -// ctx.setVariable("obj", beanA); - - StandardEvaluationContext ctx = new StandardEvaluationContext(spelContext); - /** 如果使用其他的容器,则用下面的方法 */ - //setRootObject并非必须;一个EvaluationContext只能有一个RootObject,引用它的属性时,可以不加前缀 -// ctx.setRootObject(XXX); - - //getValue有参数ctx,从新的容器中根据SpEL表达式获取所需的值 - Object value = exp.getValue(ctx, Boolean.class); - System.out.println(value); - } -} - -@Data -class SpelContext { - private String name; - private SwMap obj = new SwMap(); -} \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/TestMain.java b/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/TestMain.java deleted file mode 100644 index 606cd02..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/TestMain.java +++ /dev/null @@ -1,18 +0,0 @@ -package cc.smtweb.system.bpm.test; - -import cc.smtweb.framework.core.util.JsonUtil; -import cc.smtweb.system.bpm.web.design.form.ModelFormHelper; -import cc.smtweb.system.bpm.web.design.form.define.PageDatasetDynCond; - -/** - * Created by Akmm at 2021/12/25 22:21 - */ -public class TestMain { - - public static void main(String[] args) throws Exception { - PageDatasetDynCond dc = new PageDatasetDynCond(); - dc.opt = "and"; - dc.param = "f1"; - System.out.println(JsonUtil.encodeString(dc)); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/ToolTest.java b/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/ToolTest.java deleted file mode 100644 index bb385c8..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/ToolTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package cc.smtweb.system.bpm.test; - -import cc.smtweb.framework.core.common.SwEnum; -import cc.smtweb.framework.core.common.SwMap; -import cc.smtweb.framework.core.db.DbEngine; -import cc.smtweb.framework.core.db.EntityDao; -import cc.smtweb.framework.core.db.cache.ModelTableCache; -import cc.smtweb.framework.core.db.vo.ModelField; -import cc.smtweb.framework.core.db.vo.ModelTable; -import cc.smtweb.framework.core.util.JsonUtil; -import cc.smtweb.system.bpm.spring.BpmApplication; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by Akmm at 2022/5/24 18:40 - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = BpmApplication.class) -public class ToolTest { - @Test - public void resetTable() { - ModelTableCache cache = ModelTableCache.getInstance(); - EntityDao dao = DbEngine.getInstance().findDao(ModelTable.class); - Collection list = new ArrayList<>(cache.getAll()); - for (ModelTable table: list) { - table.setName(table.getName().toUpperCase()); - List fields = table.getFields(); - for (ModelField field: fields) { - field.setName(field.getName().toLowerCase()); - if ("COMMENT".equalsIgnoreCase(field.getDataType())) field.setDataType(SwEnum.DataType.REMARK.value); - SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(field.getDataType()); - if (dtb == null) { - System.out.println(table.getName() + "." + field.getName() + "字段类型错误:[" + field.getDataType() + "]"); - continue; - } - field.setDataType(dtb.value); - } - SwMap map = new SwMap(); - map.put("fields", table.getFields()); - map.put("indexes", table.getIndexes()); - map.put("caches", table.getCaches()); - table.getData().put("tb_content", JsonUtil.encodeString(map)); - dao.updateEntity(table); - cache.put(table); - } - } -} diff --git a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/TreeDataBuilderTest.java b/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/TreeDataBuilderTest.java deleted file mode 100644 index 06f5271..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/java/cc/smtweb/system/bpm/test/TreeDataBuilderTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package cc.smtweb.system.bpm.test; - -import cc.smtweb.system.bpm.util.ITreeDataLevelHandler; -import cc.smtweb.system.bpm.util.TreeDataUtil; -import lombok.Data; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.List; - -public class TreeDataBuilderTest { - @Test - public void testFindParent() { - // 树结构数据句柄 - TreeDataHandler handler = new TreeDataHandler(); - - List list = new ArrayList<>(); - list.add(new TreeData(1L, null)); - list.add(new TreeData(2L, 1L)); - list.add(new TreeData(3L, 2L)); - list.add(new TreeData(4L, 3L)); - list.add(new TreeData(5L, 6L)); - - TreeData root = new TreeData(); - - TreeDataUtil.buildTree(root, list, handler); - - { - TreeData node = TreeDataUtil.findParent(root, 4L, 1, handler); - Assertions.assertEquals(1L, node.getId()); - } - - { - TreeData node = TreeDataUtil.findParent(root, 3L, 1, handler); - Assertions.assertEquals(1L, node.getId()); - } - - { - TreeData node = TreeDataUtil.findParent(root, 3L, 2, handler); - Assertions.assertEquals(2L, node.getId()); - } - - { - TreeData node = TreeDataUtil.findParent(root, 1L, 2, handler); - Assertions.assertNull(node); - } - } -} - -@Data -class TreeData { - private Long id; - private Long parentId; - private int level; - private List children; - - TreeData() { - } - - TreeData(Long id, Long parentId) { - this.id = id; - this.parentId = parentId; - } -} - -class TreeDataHandler implements ITreeDataLevelHandler { - @Override - public Long getId(TreeData node) { - return node.getId(); - } - - @Override - public Long getParentId(TreeData node) { - return node.getParentId(); - } - - @Override - public List getChildren(TreeData node) { - return node.getChildren(); - } - - @Override - public void setChildren(TreeData node, List children) { - node.setChildren(children); - } - - @Override - public int getLevel(TreeData node) { - return node.getLevel(); - } - - @Override - public void setLevel(TreeData node, int level) { - node.setLevel(level); - } -} diff --git a/smtweb-framework/sw-system-bpm/src/test/resources/code/index.vue b/smtweb-framework/sw-system-bpm/src/test/resources/code/index.vue deleted file mode 100644 index b0cf895..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/resources/code/index.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - diff --git a/smtweb-framework/sw-system-bpm/src/test/resources/code/index.vue.tmp b/smtweb-framework/sw-system-bpm/src/test/resources/code/index.vue.tmp deleted file mode 100644 index 44e8a73..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/resources/code/index.vue.tmp +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - diff --git a/smtweb-framework/sw-system-bpm/src/test/resources/code/list.xml b/smtweb-framework/sw-system-bpm/src/test/resources/code/list.xml deleted file mode 100644 index 22bebe5..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/resources/code/list.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/smtweb-framework/sw-system-bpm/src/test/resources/db/smt_uc.json b/smtweb-framework/sw-system-bpm/src/test/resources/db/smt_uc.json deleted file mode 100644 index 3505ab3..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/resources/db/smt_uc.json +++ /dev/null @@ -1 +0,0 @@ -{"type":"chart","props":{"name":"_test_user","label":"测试用户数据库"},"nodes":[{"id":"node-172fda7eb8f","type":"table","props":{"label":"用户信息","name":"sys_user"},"columns":[{"type":"field","props":{"label":"ID","name":"user_id","dataType":"long","notNull":true,"keyType":"primary"},"id":"column-172fda7eb90"},{"id":"col-173284e59df","type":"field","label":"name","props":{"label":"姓名","name":"user_name","dataType":"char","notNull":true,"dataLength":"50"}},{"id":"column-175ba645939","type":"field","props":{"label":"部门ID","name":"user_dept_id","dataType":"long","keyType":"foreign","fkTable":"sys_dept"}},{"id":"column-175ba64593b","type":"field","props":{"label":"性别","name":"user_sex","dataType":"int","defaultValue":"0"}}],"left":101.3125,"top":34,"selected":false},{"id":"node-1746c68deac","type":"table","props":{"name":"sys_dept","label":"部门"},"columns":[{"id":"column-1746c68dead","type":"field","props":{"name":"dept_id","label":"ID","dataType":"long","notNull":true,"keyType":"primary"}},{"id":"column-175923f5b94","type":"field","props":{"label":"名称","name":"dept_name","dataType":"char"}},{"id":"column-175923f5b95","type":"field","props":{"label":"上级ID","name":"dept_parent_id","dataType":"long","keyType":"foreign","fkTable":"sys_dept"}},{"id":"column-175923f5b96","type":"field","props":{"label":"显示顺序","name":"dept_order","dataType":"int","defaultValue":"0"}}]},{"id":"node-174b89aabaf","type":"table","props":{"name":"fire_base_info","label":"基本概况"},"columns":[{"id":"column-174b89aabb0","type":"field","props":{"label":"ID","name":"bi_id","dataType":"long","keyType":"primary","notNull":true}},{"id":"column-174b89aabb1","type":"field","props":{"label":"单位名称","dataType":"char"}},{"id":"column-174b89aabb2","type":"field","props":{"label":"地址","dataType":"char"}},{"id":"column-174b89aabb3","type":"field","props":{"label":"登记类别","dataType":"char"}},{"id":"column-174b89aabb4","type":"field","props":{"label":"消防安全重点单位序码","dataType":"char"}},{"id":"column-174b89aabb5","type":"field","props":{"label":"单位性质","dataType":"char"}},{"id":"column-174b89aabb6","type":"field","props":{"label":"上级主管部门","dataType":"char"}},{"id":"column-174b89aabb7","type":"field","props":{"label":"消防安全责任人","dataType":"char"}},{"id":"column-174b89aabb8","type":"field","props":{"label":"消防安全责任人联系电话","dataType":"char"}},{"id":"column-174b89aabb9","type":"field","props":{"label":"消防安全责任人归口管理部门负责人","dataType":"char"}},{"id":"column-174b89aabba","type":"field","props":{"label":"消防安全责任人联系电话","dataType":"char"}},{"id":"column-174b89aabbb","type":"field","props":{"label":"消防安全管理人","dataType":"char"}},{"id":"column-174b89aabbc","type":"field","props":{"label":"消防安全管理人联系电话","dataType":"char"}},{"id":"column-174b89aabbd","type":"field","props":{"label":"消防安全管理人归口管理部门负责人","dataType":"char"}},{"id":"column-174b89aabbe","type":"field","props":{"label":"消防安全管理人联系电话","dataType":"char"}},{"id":"column-174b89aabbf","type":"field","props":{"label":"专职消防队负责人","dataType":"char"}},{"id":"column-174b89aabc0","type":"field","props":{"label":"专职消防队人数","dataType":"char"}},{"id":"column-174b89aabc1","type":"field","props":{"label":"专职消防队电话","dataType":"char"}},{"id":"column-174b89aabc2","type":"field","props":{"label":"主要灭火装备","dataType":"char"}},{"id":"column-174b89aabc3","type":"field","props":{"label":"供电情况","dataType":"char"}},{"id":"column-174b89aabc4","type":"field","props":{"label":"电力负荷等级","dataType":"char"}},{"id":"column-174b89aabc5","type":"field","props":{"label":"用电设备负荷(KW)","dataType":"char"}},{"id":"column-174b89aabc6","type":"field","props":{"label":"实际用电量(KW)","dataType":"char"}},{"id":"column-174b89aabc7","type":"field","props":{"label":"市政进水管数量及管径","dataType":"char"}},{"id":"column-174b89aabc8","type":"field","props":{"label":"天然消防水源数及容量","dataType":"char"}},{"id":"column-174b89aabc9","type":"field","props":{"label":"室内管网形式","dataType":"char"}},{"id":"column-174b89aabca","type":"field","props":{"label":"室外管网形式","dataType":"char"}},{"id":"column-174b89aabcb","type":"field","props":{"label":"室内最不利点消火栓压力","dataType":"char"}},{"id":"column-174b89aabcc","type":"field","props":{"label":"室外最不利点消火栓压力","dataType":"char"}},{"id":"column-174b89aabcd","type":"field","props":{"label":"消防安全重点部位名称","dataType":"char"}},{"id":"column-174b89aabce","type":"field","props":{"label":"是否已审核","dataType":"bool","notNull":true,"defaultValue":"false"}},{"id":"column-174b89aabcf","type":"field","props":{"label":"是否已验收","dataType":"bool","notNull":true,"defaultValue":"false"}},{"id":"column-174b89aabd0","type":"field","props":{"label":"备注","dataType":"char"}}]},{"id":"node-174b89aabd1","type":"table","props":{"name":"fire_emergency_plan","label":"灭火和应急疏散方案"},"columns":[{"id":"column-174b89aabd2","type":"field","props":{"label":"ID","name":"ep_id","dataType":"long","notNull":true,"keyType":"primary"}},{"id":"column-174b89aabd3","type":"field","props":{"label":"单位名称","dataType":"char"}},{"id":"column-174b89aabd4","type":"field","props":{"label":"单位地址","dataType":"char"}},{"id":"column-174b89aabd5","type":"field","props":{"label":"辖区公安消防队","dataType":"char"}},{"id":"column-174b89aabd6","type":"field","props":{"label":"增援消防队","dataType":"char"}},{"id":"column-174b89aabd7","type":"field","props":{"label":"消防安全责任人","dataType":"char"}},{"id":"column-174b89aabd8","type":"field","props":{"label":"联系电话","dataType":"char"}},{"id":"column-174b89aabd9","type":"field","props":{"label":"专职消防队队长","dataType":"char"}},{"id":"column-174b89aabda","type":"field","props":{"label":"专职消防队人数","dataType":"char"}},{"id":"column-174b89aabdb","type":"field","props":{"label":"专职消防队车辆数","dataType":"char"}},{"id":"column-174b89aabdc","type":"field","props":{"label":"义务消防队队长","dataType":"char"}},{"id":"column-174b89aabdd","type":"field","props":{"label":"义务消防队人数","dataType":"char"}},{"id":"column-174b89aabde","type":"field","props":{"label":"义务消防队主要装备","dataType":"char"}},{"id":"column-174b89aabdf","type":"field","props":{"label":"机构组织总指挥","dataType":"char"}},{"id":"column-174b89aabe0","type":"field","props":{"label":"机构组织副总指挥","dataType":"char"}},{"id":"column-174b89aabe1","type":"field","props":{"label":"机构组织灭火组","dataType":"char"}},{"id":"column-174b89aabe2","type":"field","props":{"label":"机构组织通讯组","dataType":"char"}},{"id":"column-174b89aabe3","type":"field","props":{"label":"机构组织疏散组","dataType":"char"}},{"id":"column-174b89aabe4","type":"field","props":{"label":"机构组织救护组","dataType":"char"}},{"id":"column-174b89aabe5","type":"field","props":{"label":"报警方式","dataType":"char"}},{"id":"column-174b89aabe6","type":"field","props":{"label":"报警和接警程序","dataType":"char"}},{"id":"column-174b89aabe7","type":"field","props":{"label":"重点部位1","dataType":"char"}},{"id":"column-174b89aabe8","type":"field","props":{"label":"重点部位2","dataType":"char"}},{"id":"column-174b89aabe9","type":"field","props":{"label":"应急疏散程序及措施","dataType":"char"}},{"id":"column-174b89aabea","type":"field","props":{"label":"扑救初起火灾程序及措施","dataType":"char"}},{"id":"column-174b89aabeb","type":"field","props":{"label":"通讯联络、安全防护的程序和措施","dataType":"char"}}]},{"id":"node-174de176370","type":"table","props":{"name":"fire_important_part","label":"消防安全重点部位","remark":"基本概况的子表"},"columns":[{"id":"column-174de176371","type":"field","props":{"label":"ID","name":"ip_id","dataType":"long","keyType":"primary","notNull":true}},{"id":"column-174de176373","type":"field","props":{"label":"基本概况","name":"ip_bi_id","keyType":"foreign","notNull":true,"remark":"基本概况ID","fkTable":"fire_base_info"}},{"id":"column-174de176372","type":"field","props":{"label":"部位名称","name":"ip_name","dataType":"char"}}]}]} \ No newline at end of file diff --git a/smtweb-framework/sw-system-bpm/src/test/resources/template/index.vm b/smtweb-framework/sw-system-bpm/src/test/resources/template/index.vm deleted file mode 100644 index 65568b5..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/resources/template/index.vm +++ /dev/null @@ -1,63 +0,0 @@ -#set($ui_widgets = []) -#macro(ui_print_vue $parent) - #if($parent.shape == 'ui-panel') - <$parent.data.type v-bind="pages.widgets.$parent.data.id"> - #foreach($child in $parent.children) - #ui_print_vue(${child}) - #end - - #else - <$parent.data.type v-bind="pages.widgets.$parent.data.id" @action="onWidgetAction($parent.data.id.props.dataset, $event)" :data="data"/> - #end - $ui_widgets.add($parent.data) -#end - - - - - diff --git a/smtweb-framework/sw-system-bpm/src/test/resources/ui/508660168293093376.json b/smtweb-framework/sw-system-bpm/src/test/resources/ui/508660168293093376.json deleted file mode 100644 index 3eb4063..0000000 --- a/smtweb-framework/sw-system-bpm/src/test/resources/ui/508660168293093376.json +++ /dev/null @@ -1,1115 +0,0 @@ -{ - "version": 2, - "page": { - "type": "fx-page", - "props": { - "title": "基本情况编辑" - } - }, - "graph": { - "x": 1, - "y": 1, - "w": 1000, - "h": 720, - "zIndex": 1, - "shape": "ui-panel", - "data": { - "id": "root", - "type": "fz-split-panel", - "layout": { - "name": "split" - }, - "props": { - "horizontal": true - } - }, - "children": [{ - "x": 1, - "y": 1, - "w": 1000, - "h": 720, - "zIndex": 2, - "shape": "ui-panel", - "data": { - "id": "p1", - "type": "fz-form-panel", - "layout": { - "name": "form" - }, - "props": { - "paddingX": 4, - "paddingY": 4, - "label": "面板", - "colNum": 2, - "minHeight": 400, - "dataset": "widget-17424353df4" - } - }, - "children": [{ - "x": 503, - "y": 797, - "w": 494, - "h": 40, - "zIndex": 101, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9fb", - "type": "fx-switch", - "props": { - "label": "是否已验收", - "labelWidth": 120, - "activeValue": "1", - "inactiveValue": "0", - "activeColor": "#409EFF", - "inactiveColor": "#C0CCDA", - "field": "id-1755410a9db", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 797, - "w": 494, - "h": 40, - "zIndex": 102, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f8", - "type": "fx-text", - "props": { - "label": "室外最不利点消火栓压力", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d8", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 753, - "w": 494, - "h": 40, - "zIndex": 103, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f6", - "type": "fx-text", - "props": { - "label": "室外管网形式", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d6", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 753, - "w": 494, - "h": 40, - "zIndex": 104, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f1", - "type": "fx-text", - "props": { - "label": "用电设备负荷(KW)", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d1", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 709, - "w": 494, - "h": 40, - "zIndex": 105, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9ec", - "type": "fx-text", - "props": { - "label": "人数", - "type": "text", - "maxlength": 50, - "placeholder": "专职消防队人数", - "labelWidth": 120, - "field": "id-1755410a9cc", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 709, - "w": 494, - "h": 40, - "zIndex": 106, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9ea", - "type": "fx-text", - "props": { - "label": "联系电话", - "type": "text", - "maxlength": 50, - "placeholder": "归口管理部门负责人联系电话", - "labelWidth": 120, - "field": "id-1755410a9ca", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 665, - "w": 494, - "h": 40, - "zIndex": 107, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e8", - "type": "fx-text", - "props": { - "label": "联系电话", - "type": "text", - "maxlength": 50, - "placeholder": "消防安全管理人联系电话", - "labelWidth": 120, - "field": "id-1755410a9c8", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 665, - "w": 494, - "h": 40, - "zIndex": 108, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e6", - "type": "fx-text", - "props": { - "label": "联系电话", - "type": "text", - "maxlength": 50, - "placeholder": "归口管理部门负责人联系电话", - "labelWidth": 120, - "field": "id-1755410a9c6", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 621, - "w": 494, - "h": 40, - "zIndex": 109, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e4", - "type": "fx-text", - "props": { - "label": "联系电话", - "type": "text", - "maxlength": 50, - "placeholder": "消防安全责任人联系电话", - "labelWidth": 120, - "field": "id-1755410a9c4", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 621, - "w": 494, - "h": 40, - "zIndex": 110, - "shape": "vue-shape", - "data": { - "id": "widget-1755456a2bc", - "type": "fx-textarea", - "props": { - "label": "备注", - "type": "textarea", - "maxlength": 200, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9dc", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 577, - "w": 494, - "h": 40, - "zIndex": 111, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9df", - "type": "fx-text", - "props": { - "label": "登记类别", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9bf", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 577, - "w": 494, - "h": 40, - "zIndex": 112, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e0", - "type": "fx-text", - "props": { - "label": "消防安全重点单位序码", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9c0", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 533, - "w": 494, - "h": 40, - "zIndex": 113, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9fa", - "type": "fx-switch", - "props": { - "label": "是否已审核", - "labelWidth": 120, - "activeValue": "1", - "inactiveValue": "0", - "activeColor": "#409EFF", - "inactiveColor": "#C0CCDA", - "field": "id-1755410a9da", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 533, - "w": 494, - "h": 40, - "zIndex": 114, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f5", - "type": "fx-text", - "props": { - "label": "室内管网形式", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d5", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 489, - "w": 494, - "h": 40, - "zIndex": 115, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f0", - "type": "fx-text", - "props": { - "label": "电力负荷等级", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d0", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 489, - "w": 494, - "h": 40, - "zIndex": 116, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e1", - "type": "fx-text", - "props": { - "label": "单位性质", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9c1", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 445, - "w": 494, - "h": 40, - "zIndex": 117, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e2", - "type": "fx-text", - "props": { - "label": "上级主管部门", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9c2", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 445, - "w": 494, - "h": 40, - "zIndex": 118, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f3", - "type": "fx-text", - "props": { - "label": "市政进水管数量及管径", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d3", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 401, - "w": 494, - "h": 40, - "zIndex": 119, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f4", - "type": "fx-text", - "props": { - "label": "天然消防水源数及容量", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d4", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 401, - "w": 494, - "h": 40, - "zIndex": 120, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f9", - "type": "fx-text", - "props": { - "label": "消防安全重点部位名称", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d9", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 357, - "w": 494, - "h": 40, - "zIndex": 121, - "shape": "vue-shape", - "data": { - "id": "widget-1755456a2bb", - "type": "fx-divider", - "props": { - "label": "", - "contentPosition": "left", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 357, - "w": 494, - "h": 40, - "zIndex": 122, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f7", - "type": "fx-text", - "props": { - "label": "室内最不利点消火栓压力", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d7", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 313, - "w": 494, - "h": 40, - "zIndex": 123, - "shape": "vue-shape", - "data": { - "id": "widget-1755456a2ba", - "type": "fx-divider", - "props": { - "label": "消防给水情况", - "contentPosition": "left", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 313, - "w": 494, - "h": 40, - "zIndex": 124, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9f2", - "type": "fx-text", - "props": { - "label": "实际用电量(KW)", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9d2", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 269, - "w": 494, - "h": 40, - "zIndex": 125, - "shape": "vue-shape", - "data": { - "id": "widget-1755456a2b9", - "type": "fx-divider", - "props": { - "label": "供电情况", - "contentPosition": "left", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 269, - "w": 494, - "h": 40, - "zIndex": 126, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9ee", - "type": "fx-text", - "props": { - "label": "主要灭火装备", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9ce", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 225, - "w": 494, - "h": 40, - "zIndex": 127, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9ed", - "type": "fx-text", - "props": { - "label": "电话", - "type": "text", - "maxlength": 50, - "placeholder": "专职消防队电话", - "labelWidth": 120, - "field": "id-1755410a9cd", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 225, - "w": 494, - "h": 40, - "zIndex": 128, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9eb", - "type": "fx-text", - "props": { - "label": "负责人", - "type": "text", - "maxlength": 50, - "placeholder": "专职消防队负责人", - "labelWidth": 120, - "field": "id-1755410a9cb", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 181, - "w": 494, - "h": 40, - "zIndex": 129, - "shape": "vue-shape", - "data": { - "id": "widget-1755456a2b8", - "type": "fx-divider", - "props": { - "label": "专职消防队", - "contentPosition": "left", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 181, - "w": 494, - "h": 40, - "zIndex": 130, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e9", - "type": "fx-text", - "props": { - "label": "归口管理部门负责人", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9c9", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 137, - "w": 494, - "h": 40, - "zIndex": 131, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e7", - "type": "fx-text", - "props": { - "label": "消防安全管理人", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9c7", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 137, - "w": 494, - "h": 40, - "zIndex": 132, - "shape": "vue-shape", - "data": { - "id": "widget-1755456a2b7", - "type": "fx-divider", - "props": { - "label": "消防安全管理人", - "contentPosition": "left", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 93, - "w": 494, - "h": 40, - "zIndex": 133, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e5", - "type": "fx-text", - "props": { - "label": "归口管理部门负责人", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9c5", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 93, - "w": 494, - "h": 40, - "zIndex": 134, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9e3", - "type": "fx-text", - "props": { - "label": "消防安全责任人", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9c3", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 49, - "w": 494, - "h": 40, - "zIndex": 135, - "shape": "vue-shape", - "data": { - "id": "widget-1755456a2b6", - "type": "fx-divider", - "props": { - "label": "消防安全责任人", - "contentPosition": "left", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 49, - "w": 494, - "h": 40, - "zIndex": 136, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9de", - "type": "fx-text", - "props": { - "label": "地址", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9be", - "required": true, - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 503, - "y": 5, - "w": 494, - "h": 40, - "zIndex": 137, - "shape": "vue-shape", - "data": { - "id": "id-1755410a9dd", - "type": "fx-text", - "props": { - "label": "单位名称", - "type": "text", - "maxlength": 50, - "placeholder": "请输入内容", - "labelWidth": 120, - "field": "id-1755410a9bc", - "required": true, - "dataset": "widget-17424353df4" - } - }, - "children": [] - }, { - "x": 5, - "y": 5, - "w": 494, - "h": 40, - "zIndex": 138, - "shape": "vue-shape", - "data": { - "id": "widget-175547b3b04", - "type": "fx-button-group", - "props": { - "gutter": 16, - "LineSpace": 8, - "buttons": [{ - "id": "col-175547b3b11", - "type": "fx-button", - "w": 1, - "h": 1, - "value": null, - "props": { - "label": "返回", - "span": 8, - "type": "success", - "size": "mini", - "plain": true, - "action": "return" - } - }, { - "type": "fx-button", - "props": { - "label": "提交", - "type": "primary", - "size": "mini", - "plain": false, - "round": false, - "circle": false, - "autofocus": false, - "action": "submit" - }, - "id": "id-175547b3b05" - }, { - "id": "col-175547b3b09", - "type": "fx-button", - "w": 1, - "h": 1, - "value": null, - "props": { - "label": "删除", - "span": 8, - "type": "danger", - "size": "mini", - "action": "remove" - } - }], - "lineSpace": 8, - "justifyContent": "flex-start", - "slot": "header", - "dataset": "widget-17424353df4" - } - }, - "children": [] - }] - }] - }, - "model": [{ - "id": "widget-17424353df4", - "type": "fz-dataset", - "value": null, - "props": { - "label": "数据集", - "fields": [{ - "id": "id-1755410a9bc", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb1", - "label": "单位名称" - } - }, { - "id": "id-1755410a9bd", - "type": "fz-field-long", - "props": { - "field": "column-174b89aabb0", - "name": "bi_id", - "label": "ID" - } - }, { - "id": "id-1755410a9be", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb2", - "label": "地址" - } - }, { - "id": "id-1755410a9bf", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb3", - "label": "登记类别" - } - }, { - "id": "id-1755410a9c0", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb4", - "label": "消防安全重点单位序码" - } - }, { - "id": "id-1755410a9c1", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb5", - "label": "单位性质" - } - }, { - "id": "id-1755410a9c2", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb6", - "label": "上级主管部门" - } - }, { - "id": "id-1755410a9c3", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb7", - "label": "消防安全责任人" - } - }, { - "id": "id-1755410a9c4", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb8", - "label": "消防安全责任人联系电话" - } - }, { - "id": "id-1755410a9c5", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabb9", - "label": "消防安全责任人归口管理部门负责人" - } - }, { - "id": "id-1755410a9c6", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabba", - "label": "消防安全责任人联系电话" - } - }, { - "id": "id-1755410a9c7", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabbb", - "label": "消防安全管理人" - } - }, { - "id": "id-1755410a9c8", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabbc", - "label": "消防安全管理人联系电话" - } - }, { - "id": "id-1755410a9c9", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabbd", - "label": "消防安全管理人归口管理部门负责人" - } - }, { - "id": "id-1755410a9ca", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabbe", - "label": "消防安全管理人联系电话" - } - }, { - "id": "id-1755410a9cb", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabbf", - "label": "专职消防队负责人" - } - }, { - "id": "id-1755410a9cc", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc0", - "label": "专职消防队人数" - } - }, { - "id": "id-1755410a9cd", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc1", - "label": "专职消防队电话" - } - }, { - "id": "id-1755410a9ce", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc2", - "label": "主要灭火装备" - } - }, { - "id": "id-1755410a9cf", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc3", - "label": "供电情况" - } - }, { - "id": "id-1755410a9d0", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc4", - "label": "电力负荷等级" - } - }, { - "id": "id-1755410a9d1", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc5", - "label": "用电设备负荷(KW)" - } - }, { - "id": "id-1755410a9d2", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc6", - "label": "实际用电量(KW)" - } - }, { - "id": "id-1755410a9d3", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc7", - "label": "市政进水管数量及管径" - } - }, { - "id": "id-1755410a9d4", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc8", - "label": "天然消防水源数及容量" - } - }, { - "id": "id-1755410a9d5", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabc9", - "label": "室内管网形式" - } - }, { - "id": "id-1755410a9d6", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabca", - "label": "室外管网形式" - } - }, { - "id": "id-1755410a9d7", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabcb", - "label": "室内最不利点消火栓压力" - } - }, { - "id": "id-1755410a9d8", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabcc", - "label": "室外最不利点消火栓压力" - } - }, { - "id": "id-1755410a9d9", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabcd", - "label": "消防安全重点部位名称" - } - }, { - "id": "id-1755410a9da", - "type": "fz-field-bool", - "props": { - "field": "column-174b89aabce", - "label": "是否已审核" - } - }, { - "id": "id-1755410a9db", - "type": "fz-field-bool", - "props": { - "field": "column-174b89aabcf", - "label": "是否已验收" - } - }, { - "id": "id-1755410a9dc", - "type": "fz-field-char", - "props": { - "field": "column-174b89aabd0", - "label": "备注" - } - }], - "datasource": "smt_uc", - "table": "node-174b89aabaf", - "tableType": "master" - }, - "events": {}, - "apis": {} - }] -}