From 6c430e7835e5e0707c57faf4f7f92a7d395e82ff Mon Sep 17 00:00:00 2001 From: wangbing Date: Sun, 7 Feb 2021 17:57:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nginx-admin.db | Bin 12288 -> 0 bytes nginx-admin.db3 | Bin 0 -> 36864 bytes pom.xml | 108 +- src/main/java/xyz/wbsite/Application.java | 26 +- .../wbsite/action/GlobalErrorController.java | 81 + .../wbsite/action/ajax/admin/ConfigAjax.java | 108 + .../action/ajax/admin/ConfigDataAjax.java | 108 + .../action/ajax/admin/LocationsAjax.java | 108 + .../wbsite/action/ajax/conf/MappingAjax.java | 60 - .../wbsite/action/ajax/conf/NginxAjax.java | 119 -- .../wbsite/action/ajax/system/UserAjax.java | 63 - .../wbsite/action/ajax/wframe/DictAjax.java | 23 + .../wbsite/action/api/conf/MappingApi.java | 33 - .../xyz/wbsite/action/control/Header.java | 15 - .../action/{ => page}/screen/Index.java | 14 +- .../java/xyz/wbsite/action/screen/Home.java | 23 - .../java/xyz/wbsite/config/NginxConfig.java | 69 - .../xyz/wbsite/frame/base/DictEntity.java | 44 + .../wbsite/frame/base/DictLoadResponse.java | 23 + .../frame/{auth => base}/LocalData.java | 75 +- .../xyz/wbsite/frame/base/LogTaskEntity.java | 92 + .../xyz/wbsite/frame/base/LoginRequest.java | 60 + .../base/LoginResponse.java} | 6 +- .../xyz/wbsite/frame/base/LogoutResponse.java | 14 + .../xyz/wbsite/frame/base/SqlTaskEntity.java | 71 + .../wbsite/frame/{auth => base}/Token.java | 29 +- .../wbsite/frame/base/VerifyCodeRequest.java | 14 + .../java/xyz/wbsite/frame/excel/WCell.java | 47 - .../java/xyz/wbsite/frame/excel/WColumn.java | 146 -- .../java/xyz/wbsite/frame/excel/WRow.java | 34 - .../frame/excel/annotation/ColumnName.java | 40 - .../{ColumnList.java => ExcelSelect.java} | 4 +- .../{Ignore.java => ExcelSheet.java} | 8 +- .../excel/converter/BooleanConverter.java | 40 +- .../excel/converter/CharacterConverter.java | 28 - .../frame/excel/converter/DateConverter.java | 51 - .../excel/converter/DoubleConverter.java | 28 - .../frame/excel/converter/FloatConverter.java | 33 - .../frame/excel/converter/ShortConverter.java | 28 - .../excel/exception/ReadErrorException.java | 17 - .../exception/ValueConverterException.java | 15 - .../frame/excel/handler/HeadWriteHandler.java | 24 + .../excel/handler/WCellWriteHandler.java | 50 + .../frame/excel/style/BaseCellStyle.java | 57 - .../wbsite/frame/excel/style/BaseFont.java | 29 - .../wbsite/frame/excel/style/NormalFont.java | 18 - .../frame/excel/style/SuccessCellStyle.java | 22 - .../wbsite/frame/listener/FrameListener.java | 46 + .../wbsite/frame/listener/IErrorListener.java | 9 + .../wbsite/frame/provider/DictProvider.java | 15 + .../wbsite/frame/provider/FrameProvider.java | 74 + .../frame/provider/LogTaskCollector.java | 7 + .../frame/provider/SimpleProfileProvider.java | 51 + .../frame/provider/SimpleTokenProvider.java | 38 + .../frame/provider/SimpleUserProvider.java | 23 + .../frame/provider/SqlTaskProvider.java | 9 + .../wbsite/frame/provider/TokenProvider.java | 13 + .../wbsite/frame/provider/UserProvider.java | 8 + .../frame/provider/VisitorProvider.java | 8 + .../frame/schedule/RunDelayRepeatTask.java | 8 + .../frame/schedule/RunFixRepeatTask.java | 7 + .../xyz/wbsite/frame/schedule/RunSqlTask.java | 40 - .../xyz/wbsite/frame/schedule/RunTask.java | 84 +- src/main/java/xyz/wbsite/frame/sse/Sser.java | 58 + .../xyz/wbsite/frame/utils/Base64Util.java | 1 + .../xyz/wbsite/frame/utils/ClassUtil.java | 214 +- .../xyz/wbsite/frame/utils/CookieUtil.java | 7 +- .../java/xyz/wbsite/frame/utils/MD5Util.java | 22 +- .../xyz/wbsite/frame/utils/RandomUtil.java | 33 + .../xyz/wbsite/frame/utils/RequestUtil.java | 84 + .../xyz/wbsite/frame/utils/ResourceUtil.java | 141 +- .../java/xyz/wbsite/frame/utils/SqlUtil.java | 129 ++ .../xyz/wbsite/frame/utils/StringUtil.java | 110 +- .../wbsite/frame/utils/VerifyCodeUtil.java | 182 ++ .../java/xyz/wbsite/frame/utils/ZipUtil.java | 14 +- .../xyz/wbsite/module/admin/ent/Services.java | 119 ++ .../admin/mgr/ConfigDataManagerImpl.java | 168 ++ .../module/admin/mgr/ConfigManager.java | 57 + .../mgr/ConfigManagerImpl.java} | 120 +- .../module/admin/mgr/LocationsManager.java | 57 + .../admin/mgr/LocationsManagerImpl.java | 168 ++ .../module/admin/mgr/ServicesManagerImpl.java | 194 ++ .../module/admin/mpr/ConfigDataMapper.xml | 187 ++ .../wbsite/module/admin/mpr/ConfigMapper.xml | 177 ++ .../module/admin/mpr/LocationsMapper.java | 100 + .../module/admin/mpr/ServicesMapper.xml | 207 ++ .../admin/req/ConfigDataCreateRequest.java | 93 + .../admin/req/ConfigDataFindRequest.java | 123 ++ .../module/admin/req/ConfigFindRequest.java | 110 + .../module/admin/req/ConfigUpdateRequest.java | 93 + .../admin/req/LocationsDeleteRequest.java | 30 + .../admin/req/LocationsFindRequest.java | 144 ++ .../admin/req/ServicesCreateRequest.java | 122 ++ .../admin/req/ServicesUpdateRequest.java | 137 ++ .../rsp/ConfigDataDeleteResponse.java} | 10 +- .../admin/rsp/LocationsCreateResponse.java | 26 + .../admin/rsp/ServicesCreateResponse.java | 26 + .../rsp/ServicesDeleteResponse.java} | 8 +- .../admin/rsp/ServicesFindResponse.java | 14 + .../xyz/wbsite/module/conf/ent/Mapping.java | 86 - .../xyz/wbsite/module/conf/ent/Message.java | 24 - .../wbsite/module/conf/ent/MessageType.java | 6 - .../xyz/wbsite/module/conf/ent/State.java | 18 - .../module/conf/req/NginxStartRequest.java | 7 - .../module/conf/req/NginxStopRequest.java | 7 - .../module/conf/rsp/NginxStartResponse.java | 7 - .../module/system/req/UserLoginRequest.java | 37 - .../module/system/req/UserLogoutRequest.java | 14 - src/main/java/xyz/wbsite/task/StatusTask.java | 40 - src/main/resources/application-dev.properties | 72 + src/main/resources/application.properties | 77 +- src/main/resources/dbtool/nginx-admin.xml | 35 - src/main/resources/logback-spring-dev.xml | 19 + src/main/resources/logback-spring-prod.xml | 105 + src/main/resources/nginx-admin.db | Bin 12288 -> 0 bytes .../pt/ADMIN_table/SQLite_ALL_TABLE.sql | 24 - .../pt/admina_table/SQLite_ALL_TABLE.sql | 87 + .../admina_table/SQLite_CONFIG.sql} | 16 +- .../SQLite_CONFIG_DATA.sql | 0 .../pt/admina_table/SQLite_LOCATIONS.sql | 22 + .../SQLite_SERVICES.sql | 0 src/main/resources/pt/nginx-admin.xml | 76 +- src/main/resources/start.bat | 3 - .../static/dist/echarts/echarts.min.js | 22 + src/main/resources/static/dist/index.min.js | 2 +- src/main/resources/static/dist/lib.min.js | 2 +- src/main/resources/static/favicon.ico | Bin 4286 -> 4286 bytes src/main/resources/static/img/start.png | Bin 2354 -> 0 bytes src/main/resources/static/img/start_.png | Bin 2051 -> 0 bytes src/main/resources/templates/control/nav.ftl | 1875 ++++++++++------- .../resources/templates/layout/default.ftl | 2 +- src/main/resources/templates/nginx.conf.ftl | 66 - .../templates/screen/admin/config.ftl | 289 +++ .../templates/screen/admin/locations.ftl | 355 ++++ .../resources/templates/screen/helpDev.ftl | 1591 ++++++++++++++ src/main/resources/templates/screen/login.ftl | 177 +- .../java/xyz/wbsite/admin/ConfigDataTest.java | 116 + .../java/xyz/wbsite/admin/ConfigTest.java | 111 + .../java/xyz/wbsite/admin/ServicesTest.java | 127 ++ .../java/xyz/wbsite/config/TestConfig.java | 16 +- .../java/xyz/wbsite/wframe/ExcelTest.java | 74 + src/test/resources/application.properties | 25 +- .../main/java/xyz/wbsite/wsqlite/Client.java | 144 -- .../java/xyz/wbsite/wsqlite/ObjectClient.java | 319 --- .../main/java/xyz/wbsite/wsqlite/Where.java | 94 - .../wbsite/wsqlite/anonation/TableField.java | 13 - 146 files changed, 9079 insertions(+), 3153 deletions(-) delete mode 100644 nginx-admin.db create mode 100644 nginx-admin.db3 create mode 100644 src/main/java/xyz/wbsite/action/GlobalErrorController.java create mode 100644 src/main/java/xyz/wbsite/action/ajax/admin/ConfigAjax.java create mode 100644 src/main/java/xyz/wbsite/action/ajax/admin/ConfigDataAjax.java create mode 100644 src/main/java/xyz/wbsite/action/ajax/admin/LocationsAjax.java delete mode 100644 src/main/java/xyz/wbsite/action/ajax/conf/MappingAjax.java delete mode 100644 src/main/java/xyz/wbsite/action/ajax/conf/NginxAjax.java delete mode 100644 src/main/java/xyz/wbsite/action/ajax/system/UserAjax.java create mode 100644 src/main/java/xyz/wbsite/action/ajax/wframe/DictAjax.java delete mode 100644 src/main/java/xyz/wbsite/action/api/conf/MappingApi.java delete mode 100644 src/main/java/xyz/wbsite/action/control/Header.java rename src/main/java/xyz/wbsite/action/{ => page}/screen/Index.java (59%) delete mode 100644 src/main/java/xyz/wbsite/action/screen/Home.java delete mode 100644 src/main/java/xyz/wbsite/config/NginxConfig.java create mode 100644 src/main/java/xyz/wbsite/frame/base/DictEntity.java create mode 100644 src/main/java/xyz/wbsite/frame/base/DictLoadResponse.java rename src/main/java/xyz/wbsite/frame/{auth => base}/LocalData.java (51%) create mode 100644 src/main/java/xyz/wbsite/frame/base/LogTaskEntity.java create mode 100644 src/main/java/xyz/wbsite/frame/base/LoginRequest.java rename src/main/java/xyz/wbsite/{module/system/rsp/UserLoginResponse.java => frame/base/LoginResponse.java} (70%) create mode 100644 src/main/java/xyz/wbsite/frame/base/LogoutResponse.java create mode 100644 src/main/java/xyz/wbsite/frame/base/SqlTaskEntity.java rename src/main/java/xyz/wbsite/frame/{auth => base}/Token.java (69%) create mode 100644 src/main/java/xyz/wbsite/frame/base/VerifyCodeRequest.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/WCell.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/WColumn.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/WRow.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/annotation/ColumnName.java rename src/main/java/xyz/wbsite/frame/excel/annotation/{ColumnList.java => ExcelSelect.java} (86%) rename src/main/java/xyz/wbsite/frame/excel/annotation/{Ignore.java => ExcelSheet.java} (64%) delete mode 100644 src/main/java/xyz/wbsite/frame/excel/converter/CharacterConverter.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/converter/DateConverter.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/converter/DoubleConverter.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/converter/FloatConverter.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/converter/ShortConverter.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/exception/ReadErrorException.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/exception/ValueConverterException.java create mode 100644 src/main/java/xyz/wbsite/frame/excel/handler/HeadWriteHandler.java create mode 100644 src/main/java/xyz/wbsite/frame/excel/handler/WCellWriteHandler.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/style/BaseCellStyle.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/style/BaseFont.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/style/NormalFont.java delete mode 100644 src/main/java/xyz/wbsite/frame/excel/style/SuccessCellStyle.java create mode 100644 src/main/java/xyz/wbsite/frame/listener/FrameListener.java create mode 100644 src/main/java/xyz/wbsite/frame/listener/IErrorListener.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/DictProvider.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/FrameProvider.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/LogTaskCollector.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/SimpleProfileProvider.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/SimpleTokenProvider.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/SimpleUserProvider.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/SqlTaskProvider.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/TokenProvider.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/UserProvider.java create mode 100644 src/main/java/xyz/wbsite/frame/provider/VisitorProvider.java delete mode 100644 src/main/java/xyz/wbsite/frame/schedule/RunSqlTask.java create mode 100644 src/main/java/xyz/wbsite/frame/sse/Sser.java create mode 100644 src/main/java/xyz/wbsite/frame/utils/RandomUtil.java create mode 100644 src/main/java/xyz/wbsite/frame/utils/SqlUtil.java create mode 100644 src/main/java/xyz/wbsite/frame/utils/VerifyCodeUtil.java create mode 100644 src/main/java/xyz/wbsite/module/admin/ent/Services.java create mode 100644 src/main/java/xyz/wbsite/module/admin/mgr/ConfigDataManagerImpl.java create mode 100644 src/main/java/xyz/wbsite/module/admin/mgr/ConfigManager.java rename src/main/java/xyz/wbsite/module/{conf/mgr/MappingManagerImpl.java => admin/mgr/ConfigManagerImpl.java} (52%) create mode 100644 src/main/java/xyz/wbsite/module/admin/mgr/LocationsManager.java create mode 100644 src/main/java/xyz/wbsite/module/admin/mgr/LocationsManagerImpl.java create mode 100644 src/main/java/xyz/wbsite/module/admin/mgr/ServicesManagerImpl.java create mode 100644 src/main/java/xyz/wbsite/module/admin/mpr/ConfigDataMapper.xml create mode 100644 src/main/java/xyz/wbsite/module/admin/mpr/ConfigMapper.xml create mode 100644 src/main/java/xyz/wbsite/module/admin/mpr/LocationsMapper.java create mode 100644 src/main/java/xyz/wbsite/module/admin/mpr/ServicesMapper.xml create mode 100644 src/main/java/xyz/wbsite/module/admin/req/ConfigDataCreateRequest.java create mode 100644 src/main/java/xyz/wbsite/module/admin/req/ConfigDataFindRequest.java create mode 100644 src/main/java/xyz/wbsite/module/admin/req/ConfigFindRequest.java create mode 100644 src/main/java/xyz/wbsite/module/admin/req/ConfigUpdateRequest.java create mode 100644 src/main/java/xyz/wbsite/module/admin/req/LocationsDeleteRequest.java create mode 100644 src/main/java/xyz/wbsite/module/admin/req/LocationsFindRequest.java create mode 100644 src/main/java/xyz/wbsite/module/admin/req/ServicesCreateRequest.java create mode 100644 src/main/java/xyz/wbsite/module/admin/req/ServicesUpdateRequest.java rename src/main/java/xyz/wbsite/module/{conf/rsp/MappingUpdateResponse.java => admin/rsp/ConfigDataDeleteResponse.java} (60%) create mode 100644 src/main/java/xyz/wbsite/module/admin/rsp/LocationsCreateResponse.java create mode 100644 src/main/java/xyz/wbsite/module/admin/rsp/ServicesCreateResponse.java rename src/main/java/xyz/wbsite/module/{conf/rsp/MappingDeleteResponse.java => admin/rsp/ServicesDeleteResponse.java} (65%) create mode 100644 src/main/java/xyz/wbsite/module/admin/rsp/ServicesFindResponse.java delete mode 100644 src/main/java/xyz/wbsite/module/conf/ent/Mapping.java delete mode 100644 src/main/java/xyz/wbsite/module/conf/ent/Message.java delete mode 100644 src/main/java/xyz/wbsite/module/conf/ent/MessageType.java delete mode 100644 src/main/java/xyz/wbsite/module/conf/ent/State.java delete mode 100644 src/main/java/xyz/wbsite/module/conf/req/NginxStartRequest.java delete mode 100644 src/main/java/xyz/wbsite/module/conf/req/NginxStopRequest.java delete mode 100644 src/main/java/xyz/wbsite/module/conf/rsp/NginxStartResponse.java delete mode 100644 src/main/java/xyz/wbsite/module/system/req/UserLoginRequest.java delete mode 100644 src/main/java/xyz/wbsite/module/system/req/UserLogoutRequest.java delete mode 100644 src/main/java/xyz/wbsite/task/StatusTask.java create mode 100644 src/main/resources/application-dev.properties delete mode 100644 src/main/resources/dbtool/nginx-admin.xml create mode 100644 src/main/resources/logback-spring-dev.xml create mode 100644 src/main/resources/logback-spring-prod.xml delete mode 100644 src/main/resources/nginx-admin.db delete mode 100644 src/main/resources/pt/ADMIN_table/SQLite_ALL_TABLE.sql create mode 100644 src/main/resources/pt/admina_table/SQLite_ALL_TABLE.sql rename src/main/resources/{dbtool/conf_table/SQLite_ALL_TABLE.sql => pt/admina_table/SQLite_CONFIG.sql} (53%) rename src/main/resources/pt/{admin_table => admina_table}/SQLite_CONFIG_DATA.sql (100%) create mode 100644 src/main/resources/pt/admina_table/SQLite_LOCATIONS.sql rename src/main/resources/pt/{admin_table => admina_table}/SQLite_SERVICES.sql (100%) delete mode 100644 src/main/resources/start.bat create mode 100644 src/main/resources/static/dist/echarts/echarts.min.js delete mode 100644 src/main/resources/static/img/start.png delete mode 100644 src/main/resources/static/img/start_.png delete mode 100644 src/main/resources/templates/nginx.conf.ftl create mode 100644 src/main/resources/templates/screen/admin/config.ftl create mode 100644 src/main/resources/templates/screen/admin/locations.ftl create mode 100644 src/main/resources/templates/screen/helpDev.ftl create mode 100644 src/test/java/xyz/wbsite/admin/ConfigDataTest.java create mode 100644 src/test/java/xyz/wbsite/admin/ConfigTest.java create mode 100644 src/test/java/xyz/wbsite/admin/ServicesTest.java create mode 100644 src/test/java/xyz/wbsite/wframe/ExcelTest.java delete mode 100644 wsqlite/src/main/java/xyz/wbsite/wsqlite/Client.java delete mode 100644 wsqlite/src/main/java/xyz/wbsite/wsqlite/ObjectClient.java delete mode 100644 wsqlite/src/main/java/xyz/wbsite/wsqlite/Where.java delete mode 100644 wsqlite/src/main/java/xyz/wbsite/wsqlite/anonation/TableField.java diff --git a/nginx-admin.db b/nginx-admin.db deleted file mode 100644 index b1ebcb0fe92751b4e97a0843588931b720f538fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI$F>ljA6bJCTl%{FGxD2R_r$~`niPm;pl*AJk=SZwNwsEdSVX=Y;YNbMf8i|bs zi7&zjiNwOk0f~`;bBK|fsOf^#<$t#2cfO}*zn`->!>9gfI$^KQ-@hKG%qCleQu3HF zLdd#0*3^-YEWVXb)R`9ItHO1%|KPi(|0X4EO0=o|?W#mvhX4d1009U<00Izz00bZa zfz<+^3EkMP*Xb8G9lto6xMA=l8Sp6bf?hE$xv}6hJI_(0UyF^}Cok9QuKyGt2S7|Uxixa_aakfZ3DyZE8Y zr56UP>!_!{TqkcM4xc5*A|B2v%-ddU)f*;V;R`7;nK1MP50;w!>zZ^%|L_*8%rm5y zxpmb`$fBh>J|D{DD9Y9g#qy^uu3j#rRd<`E^7dh!lG8UYCm%1~ovH8nWc(pLpUsov zyH2d)Z1z2`sh=0szY?`$KmY;|fB*y_009U<00Izz00ba#g96X#-Lig9zu(q2D;2w9 zlRFnbKK+b{(K3y`l+j6=zI6=4YBcvvwOLL}4WnT;%stcIv)asRIR{P0wihn79m}q& szNr3-sJ(Q9E#lS?fB*y_009U<00Izz00bZa0SNqOf!k~4&HO)vKaH@jpa1{> diff --git a/nginx-admin.db3 b/nginx-admin.db3 new file mode 100644 index 0000000000000000000000000000000000000000..0493de4581d4b5ed869c17ee5b3d041bdad75441 GIT binary patch literal 36864 zcmeI%&rj1(00;0^*xEtnhzIL!&B&595wjm624iB`3N&qS_5$@cXy?EjWCkhGfWF+x%{8M}{ z=8V4-60yvX{ZIq}2tWV=5crn@8>a<9nw;df*4mBh&6SGkR5iP%7qx0&RV>&#m6Qx$=1JUX$K5IgJPHmb>i) zGT`I_8?lW-M3B;H{;A^U$uNs5p&%?!-Sud1qPiu=jZ`PDP9TB3;;e1M`Gf3v73uE5 zbkUG@!Q6%{l`IB_zdyrXJBKsYH#P`cC$%(eGtsEDlpYecZamzyb+?4|Mc5b!9)7epzqFasTX*tkb zeqhDH0S?jpbZImynaYsJ1cuiQO<+5+ewi1fWRl<1{aMN@?Iz~L(P24mPTX<(>nZT3 zC+}zjXRi{f@009U<00Izz00bZa0SG_< z0uTtRz!*C*{QV!+;l+7D00Izz00bZa0SG_<0uX=z1Y7|;|3?rY009U<00Izz00bZa z0SG_<0^t|H^Z)RVG0qSI5P$##AOHafKmY;|fB*y_fam|n00bZa0SG_<0uX=z1Rwwb z2tXkG0(kx({xQZGLI45~fB*y_009U<00Izz00h|ce?GCp(H9m7KmY;|fB*y_009U< z00Izz00jOE0gF#Wr;=$tCdNfkEYLok`uXn3LyP;i`|9h?+x_>upI?8-T+AxX){RE< zc5AJD@ch}q_KW@9H($0lt$a40o66>=vNLk-{A{i;Te!fU|MQ9O9DQMd00bZa0SG_< Y0uX=z1Rwwb2tXi20^=jmnE#K1Uys^iEC2ui literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 5f0e9f7..544a634 100644 --- a/pom.xml +++ b/pom.xml @@ -21,22 +21,26 @@ UTF-8 1.8 true - 2.6 - 1.2.5 - 1.3.2 - 1.1.0 - 5.5.1 - Greenwich.RC2 - 3.8 + - spring-milestones - Spring Milestones - https://repo.spring.io/milestone + central + Central Repository + default + https://maven.aliyun.com/repository/public + + + + central + Central Repository + https://maven.aliyun.com/repository/public + default + + @@ -48,99 +52,61 @@ org.mybatis.spring.boot mybatis-spring-boot-starter - - - - org.mybatis.caches - mybatis-ehcache + 1.3.2 com.github.pagehelper pagehelper-spring-boot-starter + 1.2.5 - + org.springframework.boot spring-boot-starter-freemarker - + org.springframework.boot - spring-boot-devtools - provided - true - - - - org.springframework.boot - spring-boot-starter-test - test + spring-boot-starter-security + - org.springframework.boot - spring-boot-starter-security + com.alibaba + easyexcel + 2.2.6 + net.sf.dozer dozer + 5.5.1 - - org.apache.poi - poi-ooxml - - - org.xerial sqlite-jdbc 3.21.0.1 - + + org.springframework.boot + spring-boot-devtools + provided + true + - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - com.github.pagehelper - pagehelper-spring-boot-starter - ${pagehelper-version} - - - org.mybatis.spring.boot - mybatis-spring-boot-starter - ${mybatis-version} - - - org.mybatis.caches - mybatis-ehcache - ${ehcache-version} - - - net.sf.dozer - dozer - ${dozer-version} - - - org.apache.poi - poi-ooxml - ${poi-ooxml-version} - - - + + org.springframework.boot + spring-boot-starter-test + test + + diff --git a/src/main/java/xyz/wbsite/Application.java b/src/main/java/xyz/wbsite/Application.java index f2ecd72..c213c54 100644 --- a/src/main/java/xyz/wbsite/Application.java +++ b/src/main/java/xyz/wbsite/Application.java @@ -4,8 +4,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.event.ApplicationContextInitializedEvent; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -import xyz.wbsite.frame.auth.LocalData; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import xyz.wbsite.frame.base.LocalData; @SpringBootApplication @EnableAutoConfiguration @@ -17,6 +20,25 @@ public class Application extends SpringBootServletInitializer { } public static void main(String[] args) { - LocalData.setApplicationContext(SpringApplication.run(Application.class, args)); + SpringApplication application = new SpringApplication(Application.class); + application.addListeners(getListener()); + application.run(args); + } + + /** + * 用于启动时获取上下文,因为在启动过程中通过工具LocalData.getContext()获取为null + * 所以为了兼容这种需求,通过此监听可以在SpringApplication未启动完成时获得上下文 + * + * @return ApplicationListener + */ + private static ApplicationListener getListener() { + return new ApplicationListener() { + @Override + public void onApplicationEvent(ApplicationEvent applicationEvent) { + if (applicationEvent instanceof ApplicationContextInitializedEvent) { + LocalData.setContext(((ApplicationContextInitializedEvent) applicationEvent).getApplicationContext()); + } + } + }; } } \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/action/GlobalErrorController.java b/src/main/java/xyz/wbsite/action/GlobalErrorController.java new file mode 100644 index 0000000..6f8940c --- /dev/null +++ b/src/main/java/xyz/wbsite/action/GlobalErrorController.java @@ -0,0 +1,81 @@ +package xyz.wbsite.action; + +import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; +import xyz.wbsite.frame.base.LocalData; +import xyz.wbsite.frame.listener.FrameListener; +import xyz.wbsite.frame.utils.LogUtil; +import xyz.wbsite.frame.utils.RequestUtil; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collections; +import java.util.Map; + +/** + * 全局错误处理器,任何未处理异常都会进入 + * + * @author author + * @version 0.0.1 + * @since 2017-01-01 + */ +@Controller +public class GlobalErrorController extends BasicErrorController { + + public GlobalErrorController() { + super(new DefaultErrorAttributes(), new ErrorProperties()); + } + + @Override + public ResponseEntity> error(HttpServletRequest request) { + return super.error(request); + } + + @Override + @RequestMapping(produces = "text/html") + public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { + HttpStatus status = this.getStatus(request); + Map model = Collections.unmodifiableMap(this.getErrorAttributes(request, true)); + response.setStatus(status.value()); + ModelAndView modelAndView = this.resolveErrorView(request, response, status, model); + if (modelAndView == null) { + modelAndView = new ModelAndView("error", model); + } + switch (status) { + case FORBIDDEN://403 + String errorUrl = RequestUtil.getErrorUrl(request); + errorUrl = errorUrl.replaceFirst(LocalData.getContext(), ""); + String indexPage = LocalData.getEnvironment().getProperty("web.url.index", "/index.htm"); + String loginPage = LocalData.getEnvironment().getProperty("web.url.login", "/login.htm"); + if ((errorUrl.equals(indexPage) || errorUrl.equals("/")) && LocalData.getToken() == null) { + RequestUtil.setRedirect(loginPage); + } else { + modelAndView.setViewName("403"); + } + break; + case NOT_FOUND://404 + modelAndView.setViewName("404"); + break; + case INTERNAL_SERVER_ERROR://500 + default: + try { + FrameListener instance = FrameListener.getInstance(); + instance.onError((String) model.get("trace")); + modelAndView.setViewName("500"); + } catch (Exception ex) { + LogUtil.dumpException(ex); + } finally { + modelAndView.setViewName("500"); + } + break; + } + + return modelAndView; + } +} diff --git a/src/main/java/xyz/wbsite/action/ajax/admin/ConfigAjax.java b/src/main/java/xyz/wbsite/action/ajax/admin/ConfigAjax.java new file mode 100644 index 0000000..1b20de7 --- /dev/null +++ b/src/main/java/xyz/wbsite/action/ajax/admin/ConfigAjax.java @@ -0,0 +1,108 @@ +package xyz.wbsite.action.ajax.admin; + +import com.alibaba.excel.support.ExcelTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.multipart.MultipartFile; +import xyz.wbsite.frame.base.Error; +import xyz.wbsite.frame.excel.WExcel; +import xyz.wbsite.frame.utils.LogUtil; +import xyz.wbsite.frame.base.LocalData; +import xyz.wbsite.frame.base.ErrorType; +import xyz.wbsite.frame.utils.MapperUtil; +import xyz.wbsite.frame.base.BaseResponse; +import xyz.wbsite.frame.utils.ResponseUtil; +import xyz.wbsite.frame.utils.ValidationUtil; +import xyz.wbsite.frame.excel.exception.TemplateNotMatchException; +import xyz.wbsite.module.admin.ent.Config; +import xyz.wbsite.module.admin.mgr.ConfigManager; +import xyz.wbsite.module.admin.req.ConfigCreateRequest; +import xyz.wbsite.module.admin.req.ConfigDeleteRequest; +import xyz.wbsite.module.admin.req.ConfigFindRequest; +import xyz.wbsite.module.admin.req.ConfigUpdateRequest; +import xyz.wbsite.module.admin.rsp.ConfigCreateResponse; +import xyz.wbsite.module.admin.rsp.ConfigDeleteResponse; +import xyz.wbsite.module.admin.rsp.ConfigFindResponse; +import xyz.wbsite.module.admin.rsp.ConfigUpdateResponse; + +import java.io.IOException; +import java.util.List; + +public class ConfigAjax{ + + @Autowired + private ConfigManager configManager; + + public ConfigCreateResponse create(ConfigCreateRequest request) { + return configManager.create(request, LocalData.getToken()); + } + + public ConfigDeleteResponse delete(ConfigDeleteRequest request) { + return configManager.delete(request, LocalData.getToken()); + } + + public ConfigUpdateResponse update(ConfigUpdateRequest request) { + return configManager.update(request, LocalData.getToken()); + } + + public ConfigFindResponse find(ConfigFindRequest request) { + return configManager.find(request, LocalData.getToken()); + } + + public Object template(){ + return ResponseUtil.apply(new WExcel<>(Config.class)); + } + + public Object exports(ConfigFindRequest request) { + ConfigFindResponse response = configManager.find(request, LocalData.getToken()); + if (response.hasError()) { + return response; + } else if (response.getTotalCount() == 0) { + response.addError(ErrorType.BUSINESS_ERROR, "导出数据为空"); + return response; + } + return ResponseUtil.apply(new WExcel<>(Config.class).addDatas(response.getResult())); + } + + public Object imports(MultipartFile file) { + BaseResponse baseResponse = new BaseResponse(); + try { + // 检查文件格式 + String originalFilename = file.getOriginalFilename() != null ? file.getOriginalFilename() : ""; + if (!originalFilename.matches(".+(.xlsx?|.XLSX?)$")) { + baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件格式错误!"); + return baseResponse; + } + // 兼容2003以前老版本.xls + ExcelTypeEnum excelTypeEnum = originalFilename.matches(".+(.xlsx|.XLSX)$") ? ExcelTypeEnum.XLSX : ExcelTypeEnum.XLS; + WExcel sheet = new WExcel<>(Config.class).read(file.getBytes(), excelTypeEnum, new WExcel.Processor() { + @Override + public List exec(Config o, int index) { + ConfigCreateRequest request = MapperUtil.map(o, ConfigCreateRequest.class); + List validate = ValidationUtil.validate(request); + if (validate == null || validate.size() == 0) { + ConfigCreateResponse configCreateResponse = configManager.create(request, LocalData.getToken()); + if (configCreateResponse.hasError()) { + for (Error error : configCreateResponse.getErrors()) { + validate.add(error.getMessage()); + } + } + } + return validate; + } + }); + // 当导入出现错误时可以将存在标注错误的Excel返回给用户改正 + if (sheet.hasError()) { + return ResponseUtil.apply(sheet.getBytes(), sheet.getName() + "-检查.xlsx"); + } else { + return baseResponse; + } + } catch (IOException e) { + e.printStackTrace(); + LogUtil.dumpException(e); + baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件出错"); + } catch (TemplateNotMatchException e) { + baseResponse.addError(ErrorType.BUSINESS_ERROR, e.getMessage()); + } + return baseResponse; + } +} diff --git a/src/main/java/xyz/wbsite/action/ajax/admin/ConfigDataAjax.java b/src/main/java/xyz/wbsite/action/ajax/admin/ConfigDataAjax.java new file mode 100644 index 0000000..21de7e0 --- /dev/null +++ b/src/main/java/xyz/wbsite/action/ajax/admin/ConfigDataAjax.java @@ -0,0 +1,108 @@ +package xyz.wbsite.action.ajax.admin; + +import com.alibaba.excel.support.ExcelTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.multipart.MultipartFile; +import xyz.wbsite.frame.base.Error; +import xyz.wbsite.frame.excel.WExcel; +import xyz.wbsite.frame.utils.LogUtil; +import xyz.wbsite.frame.base.LocalData; +import xyz.wbsite.frame.base.ErrorType; +import xyz.wbsite.frame.utils.MapperUtil; +import xyz.wbsite.frame.base.BaseResponse; +import xyz.wbsite.frame.utils.ResponseUtil; +import xyz.wbsite.frame.utils.ValidationUtil; +import xyz.wbsite.frame.excel.exception.TemplateNotMatchException; +import xyz.wbsite.module.admin.ent.ConfigData; +import xyz.wbsite.module.admin.mgr.ConfigDataManager; +import xyz.wbsite.module.admin.req.ConfigDataCreateRequest; +import xyz.wbsite.module.admin.req.ConfigDataDeleteRequest; +import xyz.wbsite.module.admin.req.ConfigDataFindRequest; +import xyz.wbsite.module.admin.req.ConfigDataUpdateRequest; +import xyz.wbsite.module.admin.rsp.ConfigDataCreateResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataDeleteResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataFindResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataUpdateResponse; + +import java.io.IOException; +import java.util.List; + +public class ConfigDataAjax{ + + @Autowired + private ConfigDataManager configDataManager; + + public ConfigDataCreateResponse create(ConfigDataCreateRequest request) { + return configDataManager.create(request, LocalData.getToken()); + } + + public ConfigDataDeleteResponse delete(ConfigDataDeleteRequest request) { + return configDataManager.delete(request, LocalData.getToken()); + } + + public ConfigDataUpdateResponse update(ConfigDataUpdateRequest request) { + return configDataManager.update(request, LocalData.getToken()); + } + + public ConfigDataFindResponse find(ConfigDataFindRequest request) { + return configDataManager.find(request, LocalData.getToken()); + } + + public Object template(){ + return ResponseUtil.apply(new WExcel<>(ConfigData.class)); + } + + public Object exports(ConfigDataFindRequest request) { + ConfigDataFindResponse response = configDataManager.find(request, LocalData.getToken()); + if (response.hasError()) { + return response; + } else if (response.getTotalCount() == 0) { + response.addError(ErrorType.BUSINESS_ERROR, "导出数据为空"); + return response; + } + return ResponseUtil.apply(new WExcel<>(ConfigData.class).addDatas(response.getResult())); + } + + public Object imports(MultipartFile file) { + BaseResponse baseResponse = new BaseResponse(); + try { + // 检查文件格式 + String originalFilename = file.getOriginalFilename() != null ? file.getOriginalFilename() : ""; + if (!originalFilename.matches(".+(.xlsx?|.XLSX?)$")) { + baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件格式错误!"); + return baseResponse; + } + // 兼容2003以前老版本.xls + ExcelTypeEnum excelTypeEnum = originalFilename.matches(".+(.xlsx|.XLSX)$") ? ExcelTypeEnum.XLSX : ExcelTypeEnum.XLS; + WExcel sheet = new WExcel<>(ConfigData.class).read(file.getBytes(), excelTypeEnum, new WExcel.Processor() { + @Override + public List exec(ConfigData o, int index) { + ConfigDataCreateRequest request = MapperUtil.map(o, ConfigDataCreateRequest.class); + List validate = ValidationUtil.validate(request); + if (validate == null || validate.size() == 0) { + ConfigDataCreateResponse configDataCreateResponse = configDataManager.create(request, LocalData.getToken()); + if (configDataCreateResponse.hasError()) { + for (Error error : configDataCreateResponse.getErrors()) { + validate.add(error.getMessage()); + } + } + } + return validate; + } + }); + // 当导入出现错误时可以将存在标注错误的Excel返回给用户改正 + if (sheet.hasError()) { + return ResponseUtil.apply(sheet.getBytes(), sheet.getName() + "-检查.xlsx"); + } else { + return baseResponse; + } + } catch (IOException e) { + e.printStackTrace(); + LogUtil.dumpException(e); + baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件出错"); + } catch (TemplateNotMatchException e) { + baseResponse.addError(ErrorType.BUSINESS_ERROR, e.getMessage()); + } + return baseResponse; + } +} diff --git a/src/main/java/xyz/wbsite/action/ajax/admin/LocationsAjax.java b/src/main/java/xyz/wbsite/action/ajax/admin/LocationsAjax.java new file mode 100644 index 0000000..e6d7721 --- /dev/null +++ b/src/main/java/xyz/wbsite/action/ajax/admin/LocationsAjax.java @@ -0,0 +1,108 @@ +package xyz.wbsite.action.ajax.admin; + +import com.alibaba.excel.support.ExcelTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.multipart.MultipartFile; +import xyz.wbsite.frame.base.Error; +import xyz.wbsite.frame.excel.WExcel; +import xyz.wbsite.frame.utils.LogUtil; +import xyz.wbsite.frame.base.LocalData; +import xyz.wbsite.frame.base.ErrorType; +import xyz.wbsite.frame.utils.MapperUtil; +import xyz.wbsite.frame.base.BaseResponse; +import xyz.wbsite.frame.utils.ResponseUtil; +import xyz.wbsite.frame.utils.ValidationUtil; +import xyz.wbsite.frame.excel.exception.TemplateNotMatchException; +import xyz.wbsite.module.admin.ent.Locations; +import xyz.wbsite.module.admin.mgr.LocationsManager; +import xyz.wbsite.module.admin.req.LocationsCreateRequest; +import xyz.wbsite.module.admin.req.LocationsDeleteRequest; +import xyz.wbsite.module.admin.req.LocationsFindRequest; +import xyz.wbsite.module.admin.req.LocationsUpdateRequest; +import xyz.wbsite.module.admin.rsp.LocationsCreateResponse; +import xyz.wbsite.module.admin.rsp.LocationsDeleteResponse; +import xyz.wbsite.module.admin.rsp.LocationsFindResponse; +import xyz.wbsite.module.admin.rsp.LocationsUpdateResponse; + +import java.io.IOException; +import java.util.List; + +public class LocationsAjax{ + + @Autowired + private LocationsManager locationsManager; + + public LocationsCreateResponse create(LocationsCreateRequest request) { + return locationsManager.create(request, LocalData.getToken()); + } + + public LocationsDeleteResponse delete(LocationsDeleteRequest request) { + return locationsManager.delete(request, LocalData.getToken()); + } + + public LocationsUpdateResponse update(LocationsUpdateRequest request) { + return locationsManager.update(request, LocalData.getToken()); + } + + public LocationsFindResponse find(LocationsFindRequest request) { + return locationsManager.find(request, LocalData.getToken()); + } + + public Object template(){ + return ResponseUtil.apply(new WExcel<>(Locations.class)); + } + + public Object exports(LocationsFindRequest request) { + LocationsFindResponse response = locationsManager.find(request, LocalData.getToken()); + if (response.hasError()) { + return response; + } else if (response.getTotalCount() == 0) { + response.addError(ErrorType.BUSINESS_ERROR, "导出数据为空"); + return response; + } + return ResponseUtil.apply(new WExcel<>(Locations.class).addDatas(response.getResult())); + } + + public Object imports(MultipartFile file) { + BaseResponse baseResponse = new BaseResponse(); + try { + // 检查文件格式 + String originalFilename = file.getOriginalFilename() != null ? file.getOriginalFilename() : ""; + if (!originalFilename.matches(".+(.xlsx?|.XLSX?)$")) { + baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件格式错误!"); + return baseResponse; + } + // 兼容2003以前老版本.xls + ExcelTypeEnum excelTypeEnum = originalFilename.matches(".+(.xlsx|.XLSX)$") ? ExcelTypeEnum.XLSX : ExcelTypeEnum.XLS; + WExcel sheet = new WExcel<>(Locations.class).read(file.getBytes(), excelTypeEnum, new WExcel.Processor() { + @Override + public List exec(Locations o, int index) { + LocationsCreateRequest request = MapperUtil.map(o, LocationsCreateRequest.class); + List validate = ValidationUtil.validate(request); + if (validate == null || validate.size() == 0) { + LocationsCreateResponse locationsCreateResponse = locationsManager.create(request, LocalData.getToken()); + if (locationsCreateResponse.hasError()) { + for (Error error : locationsCreateResponse.getErrors()) { + validate.add(error.getMessage()); + } + } + } + return validate; + } + }); + // 当导入出现错误时可以将存在标注错误的Excel返回给用户改正 + if (sheet.hasError()) { + return ResponseUtil.apply(sheet.getBytes(), sheet.getName() + "-检查.xlsx"); + } else { + return baseResponse; + } + } catch (IOException e) { + e.printStackTrace(); + LogUtil.dumpException(e); + baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件出错"); + } catch (TemplateNotMatchException e) { + baseResponse.addError(ErrorType.BUSINESS_ERROR, e.getMessage()); + } + return baseResponse; + } +} diff --git a/src/main/java/xyz/wbsite/action/ajax/conf/MappingAjax.java b/src/main/java/xyz/wbsite/action/ajax/conf/MappingAjax.java deleted file mode 100644 index c32b4bb..0000000 --- a/src/main/java/xyz/wbsite/action/ajax/conf/MappingAjax.java +++ /dev/null @@ -1,60 +0,0 @@ -package xyz.wbsite.action.ajax.conf; - -import org.springframework.beans.factory.annotation.Autowired; -import xyz.wbsite.frame.auth.LocalData; -import xyz.wbsite.module.conf.mgr.MappingManager; -import xyz.wbsite.module.conf.req.MappingCreateRequest; -import xyz.wbsite.module.conf.req.MappingDeleteRequest; -import xyz.wbsite.module.conf.req.MappingFindRequest; -import xyz.wbsite.module.conf.req.MappingGetRequest; -import xyz.wbsite.module.conf.req.MappingUpdateRequest; -import xyz.wbsite.module.conf.req.NginxReloadRequest; -import xyz.wbsite.module.conf.rsp.MappingCreateResponse; -import xyz.wbsite.module.conf.rsp.MappingDeleteResponse; -import xyz.wbsite.module.conf.rsp.MappingFindResponse; -import xyz.wbsite.module.conf.rsp.MappingGetResponse; -import xyz.wbsite.module.conf.rsp.MappingUpdateResponse; - -public class MappingAjax { - - @Autowired - private MappingManager mappingManager; - - public MappingCreateResponse create(MappingCreateRequest request) { - MappingCreateResponse response = mappingManager.create(request, LocalData.getToken()); - if (!response.hasError()) { - NginxAjax nginxAjax = LocalData.getBean(NginxAjax.class); - nginxAjax.flushConfig(); - nginxAjax.reload(new NginxReloadRequest()); - } - return response; - } - - public MappingDeleteResponse delete(MappingDeleteRequest request) { - MappingDeleteResponse response = mappingManager.delete(request, LocalData.getToken()); - if (!response.hasError()) { - NginxAjax nginxAjax = LocalData.getBean(NginxAjax.class); - nginxAjax.flushConfig(); - nginxAjax.reload(new NginxReloadRequest()); - } - return response; - } - - public MappingUpdateResponse update(MappingUpdateRequest request) { - MappingUpdateResponse response = mappingManager.update(request, LocalData.getToken()); - if (!response.hasError()) { - NginxAjax nginxAjax = LocalData.getBean(NginxAjax.class); - nginxAjax.flushConfig(); - nginxAjax.reload(new NginxReloadRequest()); - } - return response; - } - - public MappingFindResponse find(MappingFindRequest request) { - return mappingManager.find(request, LocalData.getToken()); - } - - public MappingGetResponse get(MappingGetRequest request) { - return mappingManager.get(request, LocalData.getToken()); - } -} diff --git a/src/main/java/xyz/wbsite/action/ajax/conf/NginxAjax.java b/src/main/java/xyz/wbsite/action/ajax/conf/NginxAjax.java deleted file mode 100644 index 68ca734..0000000 --- a/src/main/java/xyz/wbsite/action/ajax/conf/NginxAjax.java +++ /dev/null @@ -1,119 +0,0 @@ -package xyz.wbsite.action.ajax.conf; - -import freemarker.template.Template; -import freemarker.template.TemplateException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; -import xyz.wbsite.frame.auth.LocalData; -import xyz.wbsite.frame.base.ErrorType; -import xyz.wbsite.frame.base.SortType; -import xyz.wbsite.frame.utils.ProcessUtil; -import xyz.wbsite.module.conf.ent.Mapping; -import xyz.wbsite.module.conf.ent.NginxCtrl; -import xyz.wbsite.module.conf.mgr.MappingManager; -import xyz.wbsite.module.conf.req.MappingFindRequest; -import xyz.wbsite.module.conf.req.NginxReloadRequest; -import xyz.wbsite.module.conf.req.NginxStartRequest; -import xyz.wbsite.module.conf.req.NginxStopRequest; -import xyz.wbsite.module.conf.rsp.MappingFindResponse; -import xyz.wbsite.module.conf.rsp.NginxReloadResponse; -import xyz.wbsite.module.conf.rsp.NginxStartResponse; -import xyz.wbsite.module.conf.rsp.NginxStopResponse; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class NginxAjax { - - @Autowired - private NginxCtrl nginxCtrl; - @Autowired - private MappingManager mappingManager; - @Autowired - private FreeMarkerConfigurer freeMarkerConfigurer; - - public NginxStartResponse start(NginxStartRequest request) { - NginxStartResponse response = new NginxStartResponse(); - if (nginxCtrl.isRunning()) { - response.addError(ErrorType.BUSINESS_ERROR, "程序已经运行"); - return response; - } - ProcessUtil.execBat(nginxCtrl.getStartCmd()); - return response; - } - - public NginxStopResponse stop(NginxStopRequest request) { - NginxStopResponse response = new NginxStopResponse(); - if (!nginxCtrl.isRunning()) { - response.addError(ErrorType.BUSINESS_ERROR, "程序尚未运行"); - return response; - } - ProcessUtil.execBat(nginxCtrl.getStopCmd()); - return response; - } - - public NginxReloadResponse reload(NginxReloadRequest request) { - NginxReloadResponse response = new NginxReloadResponse(); - if (!nginxCtrl.isRunning()) { - response.addError(ErrorType.BUSINESS_ERROR, "程序尚未运行"); - return response; - } - // 刷新配置文件 - flushConfig(); - // 重新加载配置文件 - ProcessUtil.execBat(nginxCtrl.getReloadCmd()); - return response; - } - - public synchronized void flushConfig() { - Writer wr = null; - try { - File config = nginxCtrl.getConfig(); - HashMap context = new HashMap<>(); - - MappingFindRequest mappingFindRequest = new MappingFindRequest(); - mappingFindRequest.setPageSize(0); - mappingFindRequest.setSortKey("PORT"); - mappingFindRequest.setSortType(SortType.ASC); - MappingFindResponse mappingFindResponse = mappingManager.find(mappingFindRequest, LocalData.getSysToken()); - - Map> services = new HashMap<>(); - - for (Mapping mapping : mappingFindResponse.getResult()) { - - List mappings = services.get(mapping.getPort()); - - if (mappings == null) { - mappings = new ArrayList<>(); - services.put(mapping.getPort(), mappings); - } - mappings.add(mapping); - } - - context.put("services", services); - Template template = freeMarkerConfigurer.getConfiguration().getTemplate("nginx.conf.ftl"); - wr = new OutputStreamWriter(new FileOutputStream(config), "UTF-8"); - //写入 - template.process(context, wr); - //关闭流 - wr.close(); - } catch (IOException e) { - e.printStackTrace(); - } catch (TemplateException e) { - e.printStackTrace(); - } finally { - try { - wr.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } -} diff --git a/src/main/java/xyz/wbsite/action/ajax/system/UserAjax.java b/src/main/java/xyz/wbsite/action/ajax/system/UserAjax.java deleted file mode 100644 index cf2fefa..0000000 --- a/src/main/java/xyz/wbsite/action/ajax/system/UserAjax.java +++ /dev/null @@ -1,63 +0,0 @@ -package xyz.wbsite.action.ajax.system; - -import org.springframework.beans.factory.annotation.Value; -import xyz.wbsite.frame.auth.LocalData; -import xyz.wbsite.frame.auth.Token; -import xyz.wbsite.frame.base.ErrorType; -import xyz.wbsite.frame.utils.CookieUtil; -import xyz.wbsite.frame.utils.IDgenerator; -import xyz.wbsite.frame.utils.MD5Util; -import xyz.wbsite.frame.utils.ValidationUtil; -import xyz.wbsite.module.system.req.UserLoginRequest; -import xyz.wbsite.module.system.req.UserLogoutRequest; -import xyz.wbsite.module.system.rsp.UserLoginResponse; -import xyz.wbsite.module.system.rsp.UserLogoutResponse; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Calendar; -import java.util.Date; - -public class UserAjax { - - @Value("${web.url.auth.admin}") - private String admin; - @Value("${web.url.auth.pwd}") - private String pwd; - - public UserLoginResponse login(UserLoginRequest request, Token token, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) { - UserLoginResponse response = new UserLoginResponse(); - - ValidationUtil.validate(request, response); - if (response.hasError()) { - return response; - } - - if (request.getUsername().equals(admin)) {//超级管理员登录 - String generatePwd = MD5Util.generatePwd(request.getPassword()); - if (!generatePwd.equals(pwd)) { - response.addError(ErrorType.BUSINESS_ERROR, "用户名或密码错误!"); - } else { - Date current = new Date(); - Calendar instance = Calendar.getInstance(); - instance.setTime(current); - instance.add(Calendar.HOUR_OF_DAY, 1);//默认一个小时内有效 - - Token sysToken = LocalData.getSysToken(); - sysToken.setToken(IDgenerator.nextUUID()); - - Cookie cookie = CookieUtil.newCookie("token", sysToken.getToken()); - httpServletResponse.addCookie(cookie); - response.setToken(sysToken.getToken()); - } - } - return response; - } - - public UserLogoutResponse logout(UserLogoutRequest request, Token token) { - UserLogoutResponse response = new UserLogoutResponse(); - CookieUtil.clearCookie("token"); - return response; - } -} diff --git a/src/main/java/xyz/wbsite/action/ajax/wframe/DictAjax.java b/src/main/java/xyz/wbsite/action/ajax/wframe/DictAjax.java new file mode 100644 index 0000000..7209983 --- /dev/null +++ b/src/main/java/xyz/wbsite/action/ajax/wframe/DictAjax.java @@ -0,0 +1,23 @@ +package xyz.wbsite.action.ajax.wframe; + +import xyz.wbsite.frame.base.DictLoadRequest; +import xyz.wbsite.frame.base.DictLoadResponse; +import xyz.wbsite.frame.provider.DictProvider; +import xyz.wbsite.frame.provider.FrameProvider; +import xyz.wbsite.frame.utils.ValidationUtil; + +public class DictAjax { + + public DictLoadResponse load(DictLoadRequest request) { + DictLoadResponse response = new DictLoadResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + DictProvider dictProvider = FrameProvider.getInstance().getDictProvider(); + response.setResult(dictProvider.getDict(request.getDictName())); + return response; + } +} diff --git a/src/main/java/xyz/wbsite/action/api/conf/MappingApi.java b/src/main/java/xyz/wbsite/action/api/conf/MappingApi.java deleted file mode 100644 index ec6c567..0000000 --- a/src/main/java/xyz/wbsite/action/api/conf/MappingApi.java +++ /dev/null @@ -1,33 +0,0 @@ -package xyz.wbsite.action.api.conf; - -import xyz.wbsite.frame.auth.LocalData; -import xyz.wbsite.module.conf.mgr.MappingManager; -import xyz.wbsite.module.conf.req.*; -import xyz.wbsite.module.conf.rsp.*; -import org.springframework.beans.factory.annotation.Autowired; - -public class MappingApi{ - - @Autowired - private MappingManager mappingManager; - - public MappingCreateResponse create(MappingCreateRequest request) { - return mappingManager.create(request, LocalData.getToken()); - } - - public MappingDeleteResponse delete(MappingDeleteRequest request) { - return mappingManager.delete(request, LocalData.getToken()); - } - - public MappingUpdateResponse update(MappingUpdateRequest request) { - return mappingManager.update(request, LocalData.getToken()); - } - - public MappingFindResponse find(MappingFindRequest request) { - return mappingManager.find(request, LocalData.getToken()); - } - - public MappingGetResponse get(MappingGetRequest request) { - return mappingManager.get(request, LocalData.getToken()); - } -} diff --git a/src/main/java/xyz/wbsite/action/control/Header.java b/src/main/java/xyz/wbsite/action/control/Header.java deleted file mode 100644 index c365fb7..0000000 --- a/src/main/java/xyz/wbsite/action/control/Header.java +++ /dev/null @@ -1,15 +0,0 @@ -package xyz.wbsite.action.control; - -import xyz.wbsite.frame.base.Control; -import org.springframework.ui.Model; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class Header extends Control { - - @Override - public void exec(Model model, HttpServletRequest request, HttpServletResponse response) { - - } -} diff --git a/src/main/java/xyz/wbsite/action/screen/Index.java b/src/main/java/xyz/wbsite/action/page/screen/Index.java similarity index 59% rename from src/main/java/xyz/wbsite/action/screen/Index.java rename to src/main/java/xyz/wbsite/action/page/screen/Index.java index af87898..87dc74b 100644 --- a/src/main/java/xyz/wbsite/action/screen/Index.java +++ b/src/main/java/xyz/wbsite/action/page/screen/Index.java @@ -1,11 +1,19 @@ -package xyz.wbsite.action.screen; +package xyz.wbsite.action.page.screen; import xyz.wbsite.frame.base.Screen; +import xyz.wbsite.frame.base.LocalData; import org.springframework.ui.Model; import java.util.HashMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +/** + * 对应resources/templates/screen/index.ftl,访问对应页面时会执行该Screen。 + * + * @author author + * @version 0.0.1 + * @since 2020-11-01 + */ public class Index extends Screen { @Override @@ -14,9 +22,11 @@ public class Index extends Screen { // 获取配置 HashMap prop = new HashMap<>(); prop.put("open", true);//是否保持一个子菜单展开 - prop.put("coll", true);//左侧菜单是否收缩 + prop.put("coll", false);//左侧菜单是否收缩 prop.put("tran", false);//是否展示动画 prop.put("full", false);//是否全屏 + prop.put("active", LocalData.getActive());//当前激活环境 model.addAttribute("prop", prop); + model.addAttribute("token", LocalData.getToken()); } } diff --git a/src/main/java/xyz/wbsite/action/screen/Home.java b/src/main/java/xyz/wbsite/action/screen/Home.java deleted file mode 100644 index 564eacc..0000000 --- a/src/main/java/xyz/wbsite/action/screen/Home.java +++ /dev/null @@ -1,23 +0,0 @@ -package xyz.wbsite.action.screen; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.ui.Model; -import xyz.wbsite.frame.base.Screen; -import xyz.wbsite.module.conf.ent.NginxCtrl; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class Home extends Screen { - @Autowired - private NginxCtrl nginxCtrl; - @Value("${mapping.default.port}") - private String serverPort; - - @Override - public void exec(Model model, HttpServletRequest request, HttpServletResponse response) { - model.addAttribute("run", nginxCtrl.isRunning() ? "true" : "false"); - model.addAttribute("serverPort", serverPort); - } -} diff --git a/src/main/java/xyz/wbsite/config/NginxConfig.java b/src/main/java/xyz/wbsite/config/NginxConfig.java deleted file mode 100644 index fe6a9ce..0000000 --- a/src/main/java/xyz/wbsite/config/NginxConfig.java +++ /dev/null @@ -1,69 +0,0 @@ -package xyz.wbsite.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.system.ApplicationHome; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.core.io.ClassPathResource; -import org.springframework.util.StringUtils; -import xyz.wbsite.frame.utils.FileUtil; -import xyz.wbsite.frame.utils.ZipUtil; -import xyz.wbsite.module.conf.ent.NginxCtrl; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - - -@Configuration -public class NginxConfig { - - @Autowired - private Environment environment; - - @Bean - public NginxCtrl initNginx() { - String property = environment.getProperty("nginx-path"); - File nginxHome = null; - if (StringUtils.isEmpty(property)) { - ApplicationHome home = new ApplicationHome(getClass()); - // 当前运行jar文件 - File jarFile = home.getSource() != null ? home.getSource() : home.getDir(); - - //jar同目录 - nginxHome = new File(jarFile.getParent(), "nginx"); - - if (!nginxHome.exists()) { - ClassPathResource classPathResource = new ClassPathResource("nginx-1.16.1.zip"); - try { - InputStream inputStream = classPathResource.getInputStream(); - File nginxDir = new File(jarFile.getParent(), "nginx"); - File nginxZip = new File(jarFile.getParent(), "nginx.zip"); - FileUtil.inputStream2File(inputStream, nginxZip); - ZipUtil.unZip(nginxZip, nginxDir); - } catch (IOException e) { - e.printStackTrace(); - } - } - } else { - nginxHome = new File(property); - } - - if (!nginxHome.exists()) { - throw new RuntimeException("nginx home not exists!"); - } - - File start = new File(nginxHome, "start.bat"); - File stop = new File(nginxHome, "stop.bat"); - File reload = new File(nginxHome, "reload.bat"); - - NginxCtrl nginxCtrl = new NginxCtrl(); - nginxCtrl.setStartCmd(start.getAbsolutePath()); - nginxCtrl.setStopCmd(stop.getAbsolutePath()); - nginxCtrl.setReloadCmd(reload.getAbsolutePath()); - nginxCtrl.setVersionCmd(nginxHome.getAbsolutePath() + " -v "); - nginxCtrl.setConfig(new File(new File(nginxHome, "conf"), "nginx.conf")); - return nginxCtrl; - } -} diff --git a/src/main/java/xyz/wbsite/frame/base/DictEntity.java b/src/main/java/xyz/wbsite/frame/base/DictEntity.java new file mode 100644 index 0000000..4ea7d24 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/base/DictEntity.java @@ -0,0 +1,44 @@ +package xyz.wbsite.frame.base; + +import java.util.List; + +public class DictEntity extends BaseEntity { + + /** + * 字典标签:通常为显示所用 + */ + private String label; + /** + * 字典值:通常为实际需要的值 + */ + private String value; + + /** + * 字典子项,无子项时不要 + */ + private List children; + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } +} diff --git a/src/main/java/xyz/wbsite/frame/base/DictLoadResponse.java b/src/main/java/xyz/wbsite/frame/base/DictLoadResponse.java new file mode 100644 index 0000000..d7396aa --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/base/DictLoadResponse.java @@ -0,0 +1,23 @@ +package xyz.wbsite.frame.base; + +import xyz.wbsite.frame.base.DictEntity; + +import java.util.ArrayList; +import java.util.List; + +public class DictLoadResponse extends BaseResponse { + + private List result = new ArrayList<>(); + + public List getResult() { + return result; + } + + public void setResult(List result) { + this.result = result; + } + + public void put(DictEntity entity) { + this.result.add(entity); + } +} diff --git a/src/main/java/xyz/wbsite/frame/auth/LocalData.java b/src/main/java/xyz/wbsite/frame/base/LocalData.java similarity index 51% rename from src/main/java/xyz/wbsite/frame/auth/LocalData.java rename to src/main/java/xyz/wbsite/frame/base/LocalData.java index cd6f41b..491447f 100644 --- a/src/main/java/xyz/wbsite/frame/auth/LocalData.java +++ b/src/main/java/xyz/wbsite/frame/base/LocalData.java @@ -1,14 +1,17 @@ -package xyz.wbsite.frame.auth; +package xyz.wbsite.frame.base; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import xyz.wbsite.frame.auth.Token; +import xyz.wbsite.frame.utils.PropertiesUtil; +import xyz.wbsite.frame.utils.StringUtil; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * LocalData - 本地数据存放类 @@ -19,6 +22,8 @@ import javax.servlet.http.HttpServletResponse; */ public class LocalData { + private static String[] applicationArgs = null; + private static ApplicationContext applicationContext = null; private static Token system = null; @@ -36,19 +41,6 @@ public class LocalData { return system; } - /** - * 当请求目标 target = '/aa/bb' - */ - private static final ThreadLocal actionHolder = new ThreadLocal(); - - public static String getAction() { - return actionHolder.get(); - } - - public static void setAction(String action) { - actionHolder.set(action); - } - /** * 当前用户的通行证 */ @@ -70,12 +62,12 @@ public class LocalData { return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); } - public static ApplicationContext getApplicationContext() { + public static ApplicationContext getApplicationContext() { return LocalData.applicationContext; } - public static void setApplicationContext(ApplicationContext applicationContext) { - LocalData.applicationContext = applicationContext; + public static void setContext(ApplicationContext context) { + LocalData.applicationContext = context; } public static T getBean(Class t) { @@ -89,7 +81,52 @@ public class LocalData { } } + public static Object getBean(String beanName) { + if (getApplicationContext() == null) { + return null; + } + try { + return getApplicationContext().getBean(beanName); + } catch (BeansException ignored) { + return null; + } + } + + public static T getBean(String beanName, Class t) { + if (getApplicationContext() == null) { + return null; + } + try { + return getApplicationContext().getBean(beanName, t); + } catch (BeansException ignored) { + return null; + } + } + public static Environment getEnvironment() { return getBean(Environment.class); } -} + + public static String getProperty(String key, String defaultValue) { + Environment environment = getEnvironment(); + if (environment != null) { + return environment.getProperty(key, defaultValue); + } else { + String active = LocalData.getActive(); + if (StringUtil.isEmpty(active)) { + return PropertiesUtil.getProp("application.properties", key, defaultValue); + } else { + return PropertiesUtil.getProp("application-" + active + ".properties", key, defaultValue); + } + } + } + + public static String getActive() { + Environment environment = getEnvironment(); + return environment.getActiveProfiles()[0]; + } + + public static String getContext() { + return getRequest().getContextPath(); + } +} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/frame/base/LogTaskEntity.java b/src/main/java/xyz/wbsite/frame/base/LogTaskEntity.java new file mode 100644 index 0000000..2f344a2 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/base/LogTaskEntity.java @@ -0,0 +1,92 @@ +package xyz.wbsite.frame.base; + +import java.io.Serializable; +import java.util.Date; + +public class LogTaskEntity implements Serializable { + + /** + * TASK_ID - 任务主键 + */ + private String taskId; + /** + * TASK_NAME - 任务名称 + */ + private String taskName; + /** + * START_TIME - 开始时间 + */ + private Date startTime; + /** + * END_TIME - 结束时间 + */ + private Date endTime; + /** + * EXEC_TIME - 执行耗时 + */ + private Integer execTime; + /** + * EXEC_STATE - 执行状态 + */ + private String execState; + /** + * EXEC_RESULT - 执行结果 + */ + private String execResult; + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } + + public String getTaskName() { + return taskName; + } + + public void setTaskName(String taskName) { + this.taskName = taskName; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public Integer getExecTime() { + return execTime; + } + + public void setExecTime(Integer execTime) { + this.execTime = execTime; + } + + public String getExecState() { + return execState; + } + + public void setExecState(String execState) { + this.execState = execState; + } + + public String getExecResult() { + return execResult; + } + + public void setExecResult(String execResult) { + this.execResult = execResult; + } +} diff --git a/src/main/java/xyz/wbsite/frame/base/LoginRequest.java b/src/main/java/xyz/wbsite/frame/base/LoginRequest.java new file mode 100644 index 0000000..05a6ad3 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/base/LoginRequest.java @@ -0,0 +1,60 @@ +package xyz.wbsite.frame.base; + +import xyz.wbsite.frame.base.BaseRequest; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * LoginRequest - 登录 + * + * @author wangbing + * @version 0.0.1 + * @since 2017-01-01 + */ +public class LoginRequest extends BaseRequest { + + @NotBlank(message = "[username]用户名不能为空") + private String username; + + @NotBlank(message = "[password]用户密码不能为空") + private String password; + + @NotNull(message = "[verifyCodeId]验证码ID不能为空") + private Long verifyCodeId; + + @NotBlank(message = "[verifyCodeCode]验证码不能为空") + private String verifyCodeCode; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Long getVerifyCodeId() { + return verifyCodeId; + } + + public void setVerifyCodeId(Long verifyCodeId) { + this.verifyCodeId = verifyCodeId; + } + + public String getVerifyCodeCode() { + return verifyCodeCode; + } + + public void setVerifyCodeCode(String verifyCodeCode) { + this.verifyCodeCode = verifyCodeCode; + } +} diff --git a/src/main/java/xyz/wbsite/module/system/rsp/UserLoginResponse.java b/src/main/java/xyz/wbsite/frame/base/LoginResponse.java similarity index 70% rename from src/main/java/xyz/wbsite/module/system/rsp/UserLoginResponse.java rename to src/main/java/xyz/wbsite/frame/base/LoginResponse.java index 4445950..b58ff6e 100644 --- a/src/main/java/xyz/wbsite/module/system/rsp/UserLoginResponse.java +++ b/src/main/java/xyz/wbsite/frame/base/LoginResponse.java @@ -1,15 +1,15 @@ -package xyz.wbsite.module.system.rsp; +package xyz.wbsite.frame.base; import xyz.wbsite.frame.base.BaseResponse; /** - * UserLoginResponse - 登录响应 + * LoginResponse - 登录响应 * * @author wangbing * @version 0.0.1 * @since 2017-01-01 */ -public class UserLoginResponse extends BaseResponse { +public class LoginResponse extends BaseResponse { /** * token diff --git a/src/main/java/xyz/wbsite/frame/base/LogoutResponse.java b/src/main/java/xyz/wbsite/frame/base/LogoutResponse.java new file mode 100644 index 0000000..6270804 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/base/LogoutResponse.java @@ -0,0 +1,14 @@ +package xyz.wbsite.frame.base; + +import xyz.wbsite.frame.base.BaseResponse; + +/** + * LogoutResponse - 用户登出 + * + * @author wangbing + * @version 0.0.1 + * @since 2017-01-01 + */ +public class LogoutResponse extends BaseResponse { + +} diff --git a/src/main/java/xyz/wbsite/frame/base/SqlTaskEntity.java b/src/main/java/xyz/wbsite/frame/base/SqlTaskEntity.java new file mode 100644 index 0000000..06dcfe2 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/base/SqlTaskEntity.java @@ -0,0 +1,71 @@ +package xyz.wbsite.frame.base; + + +import java.io.Serializable; + +public class SqlTaskEntity implements Serializable { + + /** + * TASK_NAME - 任务名称 + */ + private String taskName; + /** + * TASK_NOTE - 详细注释 + */ + private String taskNote; + /** + * 任务类型. + * Cron:Cron表达式 + * DelayRepeat:间隔重复(秒) + * FixRepeat:绝对重复(秒) + */ + private String taskType; + /** + * TYPE_VALUE - 任务类型值 + */ + private String typeValue; + /** + * TASK_SQL - 任务SQL + */ + private String taskSql; + + public String getTaskName() { + return taskName; + } + + public void setTaskName(String taskName) { + this.taskName = taskName; + } + + public String getTaskNote() { + return taskNote; + } + + public void setTaskNote(String taskNote) { + this.taskNote = taskNote; + } + + public String getTaskType() { + return taskType; + } + + public void setTaskType(String taskType) { + this.taskType = taskType; + } + + public String getTypeValue() { + return typeValue; + } + + public void setTypeValue(String typeValue) { + this.typeValue = typeValue; + } + + public String getTaskSql() { + return taskSql; + } + + public void setTaskSql(String taskSql) { + this.taskSql = taskSql; + } +} diff --git a/src/main/java/xyz/wbsite/frame/auth/Token.java b/src/main/java/xyz/wbsite/frame/base/Token.java similarity index 69% rename from src/main/java/xyz/wbsite/frame/auth/Token.java rename to src/main/java/xyz/wbsite/frame/base/Token.java index ac4274f..668e487 100644 --- a/src/main/java/xyz/wbsite/frame/auth/Token.java +++ b/src/main/java/xyz/wbsite/frame/base/Token.java @@ -1,6 +1,7 @@ -package xyz.wbsite.frame.auth; +package xyz.wbsite.frame.base; + +import xyz.wbsite.frame.listener.FrameListener; -import xyz.wbsite.frame.utils.IDgenerator; import java.io.Serializable; import java.util.HashSet; import java.util.Set; @@ -12,7 +13,7 @@ import java.util.Set; * @version 0.0.1 * @since 2017-01-01 */ -public class Token implements Serializable { +public class Token implements Serializable { private static final Long serialVersionUID = 1L; /** * ID @@ -30,10 +31,22 @@ public class Token implements Serializable { * 用户名称 */ private String userName; + /** + * 用户别名 + */ + private String userAlias; private Set resSet = new HashSet<>(); public boolean hasRes(String res) { + {// todo 开发初期收集资源,后期删除 + String active = LocalData.getActive(); + if (active.contains("dev")) {//测试环境捕获资源 + FrameListener instance = FrameListener.getInstance(); + instance.onRes(res); + } + } + for (String s : resSet) { if (res.matches(s)) { return true; @@ -51,12 +64,10 @@ public class Token implements Serializable { this.resSet.addAll(resourceSet); } - public Set getResSet() { return resSet; } - public long getId() { return id; } @@ -81,6 +92,14 @@ public class Token implements Serializable { this.userName = userName; } + public String getUserAlias() { + return userAlias; + } + + public void setUserAlias(String userAlias) { + this.userAlias = userAlias; + } + public String getToken() { return token; } diff --git a/src/main/java/xyz/wbsite/frame/base/VerifyCodeRequest.java b/src/main/java/xyz/wbsite/frame/base/VerifyCodeRequest.java new file mode 100644 index 0000000..fb7490f --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/base/VerifyCodeRequest.java @@ -0,0 +1,14 @@ +package xyz.wbsite.frame.base; + +import xyz.wbsite.frame.base.BaseRequest; + +/** + * VerifyCodeRequest - 请求验证码 + * + * @author wangbing + * @version 0.0.1 + * @since 2020-12-24 + */ +public class VerifyCodeRequest extends BaseRequest { + +} diff --git a/src/main/java/xyz/wbsite/frame/excel/WCell.java b/src/main/java/xyz/wbsite/frame/excel/WCell.java deleted file mode 100644 index a1cc37b..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/WCell.java +++ /dev/null @@ -1,47 +0,0 @@ -package xyz.wbsite.frame.excel; - -import java.io.Serializable; - -/** - * WCell - Excel单元格对象 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class WCell implements Serializable { - - /** - * 单元格的值,任意格式都将转化为字符类型 - */ - private String value; - - /** - * 单元格存在的错误,只在excel导入时会产生错误 - */ - private String error; - - public WCell() { - this.value = ""; - } - - public WCell(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/WColumn.java b/src/main/java/xyz/wbsite/frame/excel/WColumn.java deleted file mode 100644 index 0fbcb2f..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/WColumn.java +++ /dev/null @@ -1,146 +0,0 @@ -package xyz.wbsite.frame.excel; - - -import xyz.wbsite.frame.excel.converter.Converter; - -import java.io.Serializable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -/** - * WColumn - Excel列对象(包含列名,长度,必须项,列描述,指定转换器) - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class WColumn implements Serializable { - /** - * 列名 - */ - private String name = ""; - /** - * 列宽度 - */ - private int cellWidth = 8; - /** - * 是否是必输列 - */ - private boolean isRequired = false; - /** - * 该列的描述字段 - */ - private String description = ""; - /** - * 列转换器 - */ - private Converter converter; - /** - * Field对象 - */ - private Field field; - /** - * set方法 - */ - private Method setMethod; - /** - * get方法 - */ - private Method getMethod; - /** - * ExcelType - */ - private int cellType = 1; - /** - * 下拉列表 - */ - private String[] cellList; - - public WColumn() { - this.name = ""; - } - - public WColumn(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Field getField() { - return field; - } - - public void setField(Field field) { - this.field = field; - } - - public int getCellWidth() { - return cellWidth; - } - - public void setCellWidth(int cellWidth) { - this.cellWidth = cellWidth; - } - - public boolean isRequired() { - return isRequired; - } - - public void setRequired(boolean isRequired) { - this.isRequired = isRequired; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Converter getConverter() { - return converter; - } - - public void setConverter(Converter converter) { - this.converter = converter; - } - - public int getCellType() { - return cellType; - } - - public void setCellType(int cellType) { - this.cellType = cellType; - } - - public Method getSetMethod() { - return setMethod; - } - - public void setSetMethod(Method setMethod) { - this.setMethod = setMethod; - } - - public Method getGetMethod() { - return getMethod; - } - - public void setGetMethod(Method getMethod) { - this.getMethod = getMethod; - } - - public String[] getCellList() { - return cellList; - } - - public void setCellList(String[] cellList) { - this.cellList = cellList; - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/WRow.java b/src/main/java/xyz/wbsite/frame/excel/WRow.java deleted file mode 100644 index 2e998dd..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/WRow.java +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.wbsite.frame.excel; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * WRow - Excel行对象,即数据WCell容器
继承至HashMap,key为列名,value为单元对象 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class WRow extends HashMap implements Serializable { - - private List errorList = new ArrayList<>(); - - public final boolean hasError() { - return errorList.size() > 0; - } - - public final void addError(String errorMsg) { - errorList.add(errorMsg); - } - - public final void addErrors(List errorMsgs) { - errorList.addAll(errorMsgs); - } - - public List getErrorList() { - return errorList; - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/annotation/ColumnName.java b/src/main/java/xyz/wbsite/frame/excel/annotation/ColumnName.java deleted file mode 100644 index 0df4b63..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/annotation/ColumnName.java +++ /dev/null @@ -1,40 +0,0 @@ -package xyz.wbsite.frame.excel.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * ColumnName - Excel列名称注解,当Excel模板没有该注解则使用字段名作为列名称 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -@Target({ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface ColumnName { - - /** - * 列名 - */ - String value(); - - /** - * 默认宽度 - */ - int width() default 8; - - /** - * *标志 - */ - boolean required() default false; - - /** - * 日期格式化 - */ - String dateFormat() default "yyyy-MM-dd"; -} diff --git a/src/main/java/xyz/wbsite/frame/excel/annotation/ColumnList.java b/src/main/java/xyz/wbsite/frame/excel/annotation/ExcelSelect.java similarity index 86% rename from src/main/java/xyz/wbsite/frame/excel/annotation/ColumnList.java rename to src/main/java/xyz/wbsite/frame/excel/annotation/ExcelSelect.java index c8a9abb..0cdbe47 100644 --- a/src/main/java/xyz/wbsite/frame/excel/annotation/ColumnList.java +++ b/src/main/java/xyz/wbsite/frame/excel/annotation/ExcelSelect.java @@ -7,7 +7,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * ColumnList - 单元格下拉选项 + * ExcelSelect - 单元格下拉选项 * * @author wangbing * @version 0.0.1 @@ -16,7 +16,7 @@ import java.lang.annotation.Target; @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented -public @interface ColumnList { +public @interface ExcelSelect { /** * 下拉列表 diff --git a/src/main/java/xyz/wbsite/frame/excel/annotation/Ignore.java b/src/main/java/xyz/wbsite/frame/excel/annotation/ExcelSheet.java similarity index 64% rename from src/main/java/xyz/wbsite/frame/excel/annotation/Ignore.java rename to src/main/java/xyz/wbsite/frame/excel/annotation/ExcelSheet.java index 9540028..0456618 100644 --- a/src/main/java/xyz/wbsite/frame/excel/annotation/Ignore.java +++ b/src/main/java/xyz/wbsite/frame/excel/annotation/ExcelSheet.java @@ -7,15 +7,13 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Ignore - Excel列忽略注解,在导入导出过程中不会对存在该注解的字典进行解析 - * * @author wangbing * @version 0.0.1 * @since 2017-01-01 */ -@Target(ElementType.FIELD) +@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented -public @interface Ignore { - boolean value() default true; +public @interface ExcelSheet { + String value(); } diff --git a/src/main/java/xyz/wbsite/frame/excel/converter/BooleanConverter.java b/src/main/java/xyz/wbsite/frame/excel/converter/BooleanConverter.java index a233558..056b995 100644 --- a/src/main/java/xyz/wbsite/frame/excel/converter/BooleanConverter.java +++ b/src/main/java/xyz/wbsite/frame/excel/converter/BooleanConverter.java @@ -1,24 +1,23 @@ package xyz.wbsite.frame.excel.converter; -import xyz.wbsite.frame.excel.exception.ValueConverterException; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.property.ExcelContentProperty; -/** - * BooleanConverter - Boolean转化器,重写了对象到String,String到对象的转化方式 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ public class BooleanConverter implements Converter { - @Override - public Boolean convert(String var) throws ValueConverterException { - if (null == var || "".equals(var)) { - return false; - } + public Class supportJavaTypeKey() { + return Boolean.class; + } - String lowerCase = var.toLowerCase(); + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String lowerCase = cellData.getStringValue().toLowerCase(); if (lowerCase.matches("y|n")) { return "y".equals(lowerCase); } else if (lowerCase.matches("yes|no")) { @@ -32,15 +31,14 @@ public class BooleanConverter implements Converter { } else if (lowerCase.matches("是|不是")) { return "是".equals(lowerCase); } else { - throw new ValueConverterException("[" + var + "] can not convert to Boolean"); + throw new RuntimeException("[" + cellData.getStringValue() + "] 值有错误!"); } } - @Override - public String string(Boolean var) { - if (var == null) { - return ""; + public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + if (value == null) { + return new CellData(""); } - return var ? "是" : "否"; + return new CellData(value ? "是" : "否"); } -} \ No newline at end of file +} diff --git a/src/main/java/xyz/wbsite/frame/excel/converter/CharacterConverter.java b/src/main/java/xyz/wbsite/frame/excel/converter/CharacterConverter.java deleted file mode 100644 index 795dacb..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/converter/CharacterConverter.java +++ /dev/null @@ -1,28 +0,0 @@ -package xyz.wbsite.frame.excel.converter; - -/** - * CharacterConverter - Character转化器,重写了对象到String,String到对象的转化方式 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class CharacterConverter implements Converter { - - @Override - public Character convert(String var) { - if (var == null || var.equals("")) { - return '0'; - } else { - return var.charAt(0); - } - } - - @Override - public String string(Character var) { - if (var == null) { - return ""; - } - return String.valueOf(var).trim(); - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/converter/DateConverter.java b/src/main/java/xyz/wbsite/frame/excel/converter/DateConverter.java deleted file mode 100644 index ab3e13f..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/converter/DateConverter.java +++ /dev/null @@ -1,51 +0,0 @@ -package xyz.wbsite.frame.excel.converter; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * DateConverter - Date转化器,重写了对象到String,String到对象的转化方式 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class DateConverter implements Converter { - - @Override - public Date convert(String var) { - if (var == null) { - return null; - } - Date date = null; - try { - var = var.trim(); - if (var.matches("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}")) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - return sdf.parse(var); - } else if (var.matches("[0-9]{4}/[0-9]{1,2}/[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}")) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - return sdf.parse(var); - } else if (var.matches("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}")) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - date = sdf.parse(var); - } else if (var.matches("[0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日 [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}")) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); - date = sdf.parse(var); - } - - } catch (ParseException e) { - e.printStackTrace(); - } - return date; - } - - @Override - public String string(Date var) { - if (var == null) { - return ""; - } - return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(var); - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/converter/DoubleConverter.java b/src/main/java/xyz/wbsite/frame/excel/converter/DoubleConverter.java deleted file mode 100644 index 06f55ea..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/converter/DoubleConverter.java +++ /dev/null @@ -1,28 +0,0 @@ -package xyz.wbsite.frame.excel.converter; - -/** - * DoubleConverter - Double转化器,重写了对象到String,String到对象的转化方式 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class DoubleConverter implements Converter { - - @Override - public Double convert(String var) { - try { - return Double.parseDouble(var); - } catch (Exception e) { - return 0d; - } - } - - @Override - public String string(Double var) { - if (var == null) { - return ""; - } - return String.valueOf(var); - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/converter/FloatConverter.java b/src/main/java/xyz/wbsite/frame/excel/converter/FloatConverter.java deleted file mode 100644 index 647a289..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/converter/FloatConverter.java +++ /dev/null @@ -1,33 +0,0 @@ -package xyz.wbsite.frame.excel.converter; - -/** - * FloatConverter - Float转化器,重写了对象到String,String到对象的转化方式 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class FloatConverter implements Converter { - - @Override - public Float convert(String var) { - try { - //增加对1.0一类的的优化显示 - if (var.matches("(\\d+)\\.0")) { - var = var.replaceAll("\\.0$", ""); - } - - return Float.parseFloat(var); - } catch (Exception e) { - return 0f; - } - } - - @Override - public String string(Float var) { - if (var == null) { - return ""; - } - return String.valueOf(var); - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/converter/ShortConverter.java b/src/main/java/xyz/wbsite/frame/excel/converter/ShortConverter.java deleted file mode 100644 index 5ddebb1..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/converter/ShortConverter.java +++ /dev/null @@ -1,28 +0,0 @@ -package xyz.wbsite.frame.excel.converter; - -/** - * ShortConverter - Short转化器,重写了对象到String,String到对象的转化方式 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class ShortConverter implements Converter { - - @Override - public Short convert(String var) { - try { - return Short.parseShort(var); - } catch (Exception e) { - return 0; - } - } - - @Override - public String string(Short var) { - if (var == null) { - return ""; - } - return String.valueOf(var); - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/exception/ReadErrorException.java b/src/main/java/xyz/wbsite/frame/excel/exception/ReadErrorException.java deleted file mode 100644 index 9dac0cf..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/exception/ReadErrorException.java +++ /dev/null @@ -1,17 +0,0 @@ -package xyz.wbsite.frame.excel.exception; - -/** - * Excel文件读取失败异常 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class ReadErrorException extends Exception { - public ReadErrorException() { - } - - public ReadErrorException(String s) { - super(s); - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/exception/ValueConverterException.java b/src/main/java/xyz/wbsite/frame/excel/exception/ValueConverterException.java deleted file mode 100644 index b848c46..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/exception/ValueConverterException.java +++ /dev/null @@ -1,15 +0,0 @@ -package xyz.wbsite.frame.excel.exception; - -/** - * 值转换异常 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class ValueConverterException extends Exception { - - public ValueConverterException(String s) { - super(s); - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/handler/HeadWriteHandler.java b/src/main/java/xyz/wbsite/frame/excel/handler/HeadWriteHandler.java new file mode 100644 index 0000000..bc854d8 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/excel/handler/HeadWriteHandler.java @@ -0,0 +1,24 @@ +package xyz.wbsite.frame.excel.handler; + +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.AbstractCellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Cell; + +import java.util.List; + + +public abstract class HeadWriteHandler extends AbstractCellWriteHandler { + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + super.afterCellDispose(writeSheetHolder, writeTableHolder, cellDataList, cell, head, relativeRowIndex, isHead); + if (isHead) { + handlerHead(head); + } + } + + protected abstract void handlerHead(Head head); +} diff --git a/src/main/java/xyz/wbsite/frame/excel/handler/WCellWriteHandler.java b/src/main/java/xyz/wbsite/frame/excel/handler/WCellWriteHandler.java new file mode 100644 index 0000000..32d878a --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/excel/handler/WCellWriteHandler.java @@ -0,0 +1,50 @@ +package xyz.wbsite.frame.excel.handler; + +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Row; +import xyz.wbsite.frame.excel.WHead; + +import java.util.List; +import java.util.Map; + +public class WCellWriteHandler implements CellWriteHandler { + private CellStyle[] styles; + + private Map> errMap; + + public WCellWriteHandler(List wHeads, CellStyle[] styles, Map> errMap) { + this.styles = styles; + this.errMap = errMap; + } + + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean isHead) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean isHead) { + + } + + @Override + public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean isHead) { + + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List list, Cell cell, Head head, Integer rowIndex, Boolean isHead) { + if (isHead) { + cell.setCellStyle(styles[0]); + } else if (errMap.get(rowIndex) != null) { + cell.setCellStyle(styles[1]); + } + } +} diff --git a/src/main/java/xyz/wbsite/frame/excel/style/BaseCellStyle.java b/src/main/java/xyz/wbsite/frame/excel/style/BaseCellStyle.java deleted file mode 100644 index d336a29..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/style/BaseCellStyle.java +++ /dev/null @@ -1,57 +0,0 @@ -package xyz.wbsite.frame.excel.style; - -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * Created on 2015/1/29. - * - * @author - * @since 2.0.0 - */ -public class BaseCellStyle { - /** - * 样式 - */ - protected CellStyle style; - - public BaseCellStyle(Workbook workbook) { - style = workbook.createCellStyle(); - style.setFillPattern(CellStyle.NO_FILL); - //下边框 - style.setBorderBottom(CellStyle.SOLID_FOREGROUND); - //下边框颜色 - style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); - //左边框 - style.setBorderLeft(CellStyle.SOLID_FOREGROUND); - //左边框颜色 - style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); - //右边框 - style.setBorderRight(CellStyle.SOLID_FOREGROUND); - //右边框颜色 - style.setRightBorderColor(IndexedColors.BLACK.getIndex()); - //上边框 - style.setBorderTop(CellStyle.SOLID_FOREGROUND); - //上边框颜色 - style.setTopBorderColor(IndexedColors.BLACK.getIndex()); - - style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //上下居中 - style.setBorderBottom(CellStyle.SOLID_FOREGROUND); //下边框 - style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); //下边框颜色 - style.setBorderLeft(CellStyle.SOLID_FOREGROUND); //左边框 - style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); //左边框颜色 - style.setBorderRight(CellStyle.SOLID_FOREGROUND); //右边框 - style.setRightBorderColor(IndexedColors.BLACK.getIndex()); //右边框颜色 - style.setBorderTop(CellStyle.SOLID_FOREGROUND); //上边框 - style.setTopBorderColor(IndexedColors.BLACK.getIndex()); //上边框颜色 - } - - public CellStyle getStyle() { - return style; - } - - public void setStyle(CellStyle style) { - this.style = style; - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/style/BaseFont.java b/src/main/java/xyz/wbsite/frame/excel/style/BaseFont.java deleted file mode 100644 index e03c689..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/style/BaseFont.java +++ /dev/null @@ -1,29 +0,0 @@ -package xyz.wbsite.frame.excel.style; - -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * Created on 2015/1/29. - * - * @author - * @since 2.0.0 - */ -public class BaseFont { - /** - * 字体 - */ - protected Font font; - - public BaseFont(Workbook workbook) { - font = workbook.createFont(); - } - - public Font getFont() { - return font; - } - - public void setFont(Font font) { - this.font = font; - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/style/NormalFont.java b/src/main/java/xyz/wbsite/frame/excel/style/NormalFont.java deleted file mode 100644 index f4cf5bb..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/style/NormalFont.java +++ /dev/null @@ -1,18 +0,0 @@ -package xyz.wbsite.frame.excel.style; - -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.Workbook; - -/** - * 普通字体.颜色黑 - * Created on 2015/1/29. - * - * @author - * @since 2.0.0 - */ -public class NormalFont extends BaseFont { - public NormalFont(Workbook workbook) { - super(workbook); - font.setColor(HSSFColor.BLACK.index); //字体颜色-黑色 - } -} diff --git a/src/main/java/xyz/wbsite/frame/excel/style/SuccessCellStyle.java b/src/main/java/xyz/wbsite/frame/excel/style/SuccessCellStyle.java deleted file mode 100644 index 136c474..0000000 --- a/src/main/java/xyz/wbsite/frame/excel/style/SuccessCellStyle.java +++ /dev/null @@ -1,22 +0,0 @@ -package xyz.wbsite.frame.excel.style; - -import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Workbook; - -public class SuccessCellStyle extends BaseCellStyle { - - public SuccessCellStyle(Workbook workbook) { - super(workbook); - style.setFillForegroundColor(HSSFColor.GREEN.index); //背景颜色红色 - style.setFillPattern(CellStyle.SOLID_FOREGROUND); //设置单元格填充样式 - } - - public CellStyle getStyle() { - return style; - } - - public void setStyle(CellStyle style) { - this.style = style; - } -} diff --git a/src/main/java/xyz/wbsite/frame/listener/FrameListener.java b/src/main/java/xyz/wbsite/frame/listener/FrameListener.java new file mode 100644 index 0000000..80ebc8a --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/listener/FrameListener.java @@ -0,0 +1,46 @@ +package xyz.wbsite.frame.listener; + +import xyz.wbsite.frame.base.LocalData; + +import java.util.Map; + +public class FrameListener { + + private static FrameListener ourInstance = new FrameListener(); + + public static FrameListener getInstance() { + return ourInstance; + } + + private FrameListener() { + } + + public void onRes(String res) { + Map beansOfType = LocalData.getApplicationContext().getBeansOfType(IResListener.class); + for (IResListener resListener : beansOfType.values()) { + resListener.onRes(res); + } + } + + public void onError(Throwable throwable) { + Map beansOfType = LocalData.getApplicationContext().getBeansOfType(IErrorListener.class); + for (IErrorListener errorListener : beansOfType.values()) { + errorListener.error(throwable); + } + } + + public void onError(String message) { + onError(new RuntimeException(message)); + } + + public void onTaskError(Throwable error) { + Map beansOfType = LocalData.getApplicationContext().getBeansOfType(IErrorListener.class); + for (IErrorListener errorListener : beansOfType.values()) { + errorListener.error(error); + } + } + + public void onTaskError(String message) { + onTaskError(new RuntimeException(message)); + } +} diff --git a/src/main/java/xyz/wbsite/frame/listener/IErrorListener.java b/src/main/java/xyz/wbsite/frame/listener/IErrorListener.java new file mode 100644 index 0000000..148bb9c --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/listener/IErrorListener.java @@ -0,0 +1,9 @@ +package xyz.wbsite.frame.listener; + +/** + * 系统错误监听器 + */ +public interface IErrorListener { + + void error(Throwable error); +} diff --git a/src/main/java/xyz/wbsite/frame/provider/DictProvider.java b/src/main/java/xyz/wbsite/frame/provider/DictProvider.java new file mode 100644 index 0000000..c56e58c --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/DictProvider.java @@ -0,0 +1,15 @@ +package xyz.wbsite.frame.provider; + +import xyz.wbsite.frame.base.DictEntity; + +import javax.validation.constraints.NotNull; +import java.util.List; + +public interface DictProvider { + + List getDict(@NotNull String dictName); + + boolean isExist(@NotNull String dictName); + + boolean isExistValue(@NotNull String dictName, @NotNull String dictKey); +} diff --git a/src/main/java/xyz/wbsite/frame/provider/FrameProvider.java b/src/main/java/xyz/wbsite/frame/provider/FrameProvider.java new file mode 100644 index 0000000..08fdd6d --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/FrameProvider.java @@ -0,0 +1,74 @@ +package xyz.wbsite.frame.provider; + +import xyz.wbsite.frame.base.LocalData; + +import java.util.Iterator; +import java.util.Map; + +public class FrameProvider { + + private static FrameProvider ourInstance = new FrameProvider(); + + public static FrameProvider getInstance() { + return ourInstance; + } + + private FrameProvider() { + } + + public UserProvider getUserProvider() { + Map beansOfType = LocalData.getApplicationContext().getBeansOfType(UserProvider.class); + if (beansOfType.size() == 0) { + return null; + } + Iterator iterator = beansOfType.keySet().iterator(); + String name = iterator.next(); + while (iterator.hasNext()) { + String next = iterator.next(); + name = !"simpleUserProvider".equals(next) ? next : name; + } + return beansOfType.get(name); + } + + public TokenProvider getTokenProvider() { + Map beansOfType = LocalData.getApplicationContext().getBeansOfType(TokenProvider.class); + if (beansOfType.size() == 0) { + return null; + } + Iterator iterator = beansOfType.keySet().iterator(); + String name = iterator.next(); + while (iterator.hasNext()) { + String next = iterator.next(); + name = !"simpleTokenProvider".equals(next) ? next : name; + } + return beansOfType.get(name); + } + + public ProfileProvider getProfileProvider() { + Map beansOfType = LocalData.getApplicationContext().getBeansOfType(ProfileProvider.class); + if (beansOfType.size() == 0) { + return null; + } + Iterator iterator = beansOfType.keySet().iterator(); + String name = iterator.next(); + while (iterator.hasNext()) { + String next = iterator.next(); + name = !"simpleProfileProvider".equals(next) ? next : name; + } + return beansOfType.get(name); + } + + public DictProvider getDictProvider() { + Map beansOfType = LocalData.getApplicationContext().getBeansOfType(DictProvider.class); + if (beansOfType.size() == 0) { + return null; + } + Iterator iterator = beansOfType.keySet().iterator(); + String name = iterator.next(); + while (iterator.hasNext()) { + String next = iterator.next(); + name = !"simpleDictProvider".equals(next) ? next : name; + } + return beansOfType.get(name); + } +} diff --git a/src/main/java/xyz/wbsite/frame/provider/LogTaskCollector.java b/src/main/java/xyz/wbsite/frame/provider/LogTaskCollector.java new file mode 100644 index 0000000..c8d4e92 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/LogTaskCollector.java @@ -0,0 +1,7 @@ +package xyz.wbsite.frame.provider; + +import xyz.wbsite.frame.base.LogTaskEntity; + +public interface LogTaskCollector { + void collector(LogTaskEntity entity); +} diff --git a/src/main/java/xyz/wbsite/frame/provider/SimpleProfileProvider.java b/src/main/java/xyz/wbsite/frame/provider/SimpleProfileProvider.java new file mode 100644 index 0000000..fca68b6 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/SimpleProfileProvider.java @@ -0,0 +1,51 @@ +package xyz.wbsite.frame.provider; + +import xyz.wbsite.frame.base.LocalData; +import xyz.wbsite.frame.utils.StringUtil; + +public class SimpleProfileProvider implements ProfileProvider { + + @Override + public String getString(String key, String defaultValue) { + return LocalData.getProperty(key, defaultValue); + } + + @Override + public int getInt(String key, int defaultValue) { + String string = getString(key, String.valueOf(defaultValue)); + if (!StringUtil.isEmpty(string)) { + try { + return Integer.parseInt(string); + } catch (Exception ignored) { + + } + } + return defaultValue; + } + + @Override + public long getLong(String key, long defaultValue) { + String string = this.getString(key, String.valueOf(defaultValue)); + if (!StringUtil.isEmpty(string)) { + try { + return Long.parseLong(string); + } catch (Exception ignored) { + + } + } + return defaultValue; + } + + @Override + public boolean getBoolean(String key, boolean defaultValue) { + String string = this.getString(key, String.valueOf(defaultValue)); + if (!StringUtil.isEmpty(string)) { + try { + return Boolean.parseBoolean(string); + } catch (Exception ignored) { + + } + } + return defaultValue; + } +} diff --git a/src/main/java/xyz/wbsite/frame/provider/SimpleTokenProvider.java b/src/main/java/xyz/wbsite/frame/provider/SimpleTokenProvider.java new file mode 100644 index 0000000..b686f94 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/SimpleTokenProvider.java @@ -0,0 +1,38 @@ +package xyz.wbsite.frame.provider; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import xyz.wbsite.config.CacheConfig; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.frame.base.UserEntity; +import xyz.wbsite.frame.utils.IDgenerator; + +import javax.validation.constraints.NotNull; + +@Component +public class SimpleTokenProvider implements TokenProvider { + + @Autowired + private CacheConfig cacheConfig; + + public Token build(@NotNull UserEntity userEntity) { + Token token = new Token(); + token.setId(IDgenerator.nextId()); + token.setUserId(userEntity.getId()); + token.setToken(IDgenerator.nextUUID()); + token.setUserName(userEntity.getUserName()); + token.setUserAlias(userEntity.getUserAlias()); + token.putRes(userEntity.getResSet()); + cacheConfig.put(token.getToken(), token, 3 * 60 * 60 * 1000); + return token; + } + + public Token build(@NotNull String token) { + // 检索缓存Token + Object o = cacheConfig.get(token); + if (o != null && o instanceof Token) { + return (Token) o; + } + return null; + } +} diff --git a/src/main/java/xyz/wbsite/frame/provider/SimpleUserProvider.java b/src/main/java/xyz/wbsite/frame/provider/SimpleUserProvider.java new file mode 100644 index 0000000..12bb6a9 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/SimpleUserProvider.java @@ -0,0 +1,23 @@ +package xyz.wbsite.frame.provider; + +import org.springframework.stereotype.Component; +import xyz.wbsite.frame.base.LocalData; +import xyz.wbsite.frame.base.UserEntity; + +@Component +public class SimpleUserProvider implements UserProvider { + + public UserEntity getUser(String username) { + String admin = LocalData.getProperty("web.url.auth.admin", ""); + if (!username.equals(admin)) { + return null; + } + UserEntity userEntity = new UserEntity(); + userEntity.setId(0L); + userEntity.setUserName(username); + userEntity.setUserAlias("超级管理员"); + userEntity.setPassword(LocalData.getProperty("web.url.auth.pwd", "")); + userEntity.putRes(".*"); + return userEntity; + } +} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/frame/provider/SqlTaskProvider.java b/src/main/java/xyz/wbsite/frame/provider/SqlTaskProvider.java new file mode 100644 index 0000000..04e795f --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/SqlTaskProvider.java @@ -0,0 +1,9 @@ +package xyz.wbsite.frame.provider; + +import xyz.wbsite.frame.base.SqlTaskEntity; + +import java.util.List; + +public interface SqlTaskProvider { + List getSqlTask(); +} diff --git a/src/main/java/xyz/wbsite/frame/provider/TokenProvider.java b/src/main/java/xyz/wbsite/frame/provider/TokenProvider.java new file mode 100644 index 0000000..b4b4c99 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/TokenProvider.java @@ -0,0 +1,13 @@ +package xyz.wbsite.frame.provider; + +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.frame.base.UserEntity; + +import javax.validation.constraints.NotNull; + +public interface TokenProvider { + + Token build(@NotNull UserEntity userEntity); + + Token build(@NotNull String token); +} diff --git a/src/main/java/xyz/wbsite/frame/provider/UserProvider.java b/src/main/java/xyz/wbsite/frame/provider/UserProvider.java new file mode 100644 index 0000000..f44f3da --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/UserProvider.java @@ -0,0 +1,8 @@ +package xyz.wbsite.frame.provider; + +import xyz.wbsite.frame.base.UserEntity; + +public interface UserProvider { + + UserEntity getUser(String username); +} diff --git a/src/main/java/xyz/wbsite/frame/provider/VisitorProvider.java b/src/main/java/xyz/wbsite/frame/provider/VisitorProvider.java new file mode 100644 index 0000000..6661bd1 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/provider/VisitorProvider.java @@ -0,0 +1,8 @@ +package xyz.wbsite.frame.provider; + +import xyz.wbsite.frame.base.VisitorEntity; + +public interface VisitorProvider { + + VisitorEntity getVisitor(String appKey); +} diff --git a/src/main/java/xyz/wbsite/frame/schedule/RunDelayRepeatTask.java b/src/main/java/xyz/wbsite/frame/schedule/RunDelayRepeatTask.java index f52c639..66b3c36 100644 --- a/src/main/java/xyz/wbsite/frame/schedule/RunDelayRepeatTask.java +++ b/src/main/java/xyz/wbsite/frame/schedule/RunDelayRepeatTask.java @@ -6,6 +6,14 @@ import org.springframework.util.Assert; import java.time.Duration; import java.util.concurrent.ScheduledFuture; +/** + * 间隔重复任务,任务A执行结束后,间隔指定时间后开始执行B + * 倘若A未执行完,B一直处于等待状态 + * + * @author wangbing + * @version 0.0.1 + * @since 2020-01-01 + */ public abstract class RunDelayRepeatTask extends RunTask { public abstract Duration interval(); diff --git a/src/main/java/xyz/wbsite/frame/schedule/RunFixRepeatTask.java b/src/main/java/xyz/wbsite/frame/schedule/RunFixRepeatTask.java index 1abf7e6..46b1fd6 100644 --- a/src/main/java/xyz/wbsite/frame/schedule/RunFixRepeatTask.java +++ b/src/main/java/xyz/wbsite/frame/schedule/RunFixRepeatTask.java @@ -6,6 +6,13 @@ import org.springframework.util.Assert; import java.time.Duration; import java.util.concurrent.ScheduledFuture; +/** + * 重复任务,任务A开始后经过指定时间后执行B,无论A是否结束 + * + * @author wangbing + * @version 0.0.1 + * @since 2020-01-01 + */ public abstract class RunFixRepeatTask extends RunTask { public abstract Duration interval(); diff --git a/src/main/java/xyz/wbsite/frame/schedule/RunSqlTask.java b/src/main/java/xyz/wbsite/frame/schedule/RunSqlTask.java deleted file mode 100644 index 5858ed7..0000000 --- a/src/main/java/xyz/wbsite/frame/schedule/RunSqlTask.java +++ /dev/null @@ -1,40 +0,0 @@ -package xyz.wbsite.frame.schedule; - -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; -import xyz.wbsite.frame.auth.LocalData; -import xyz.wbsite.frame.utils.LogUtil; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -public abstract class RunSqlTask extends RunFixRepeatTask { - - private Connection connection; - - @Override - public void run() { - try { - if (connection == null || connection.isClosed()) { - SqlSessionFactory factory = LocalData.getBean(SqlSessionFactory.class); - SqlSession sqlSession = factory.openSession(true); - connection = sqlSession.getConnection(); - } - } catch (Exception e) { - e.printStackTrace(); - LogUtil.e("schedule: get connection failed!"); - return; - } - try { - PreparedStatement preparedStatement = connection.prepareStatement(getSql()); - preparedStatement.execute(); - preparedStatement.close(); - } catch (SQLException e) { - e.printStackTrace(); - LogUtil.e("RunSqlTask exec failed! SQL:[" + getSql() + "]"); - } - } - - public abstract String getSql(); -} diff --git a/src/main/java/xyz/wbsite/frame/schedule/RunTask.java b/src/main/java/xyz/wbsite/frame/schedule/RunTask.java index 897dea6..748e292 100644 --- a/src/main/java/xyz/wbsite/frame/schedule/RunTask.java +++ b/src/main/java/xyz/wbsite/frame/schedule/RunTask.java @@ -1,21 +1,93 @@ package xyz.wbsite.frame.schedule; - import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import xyz.wbsite.frame.base.LocalData; +import xyz.wbsite.frame.base.LogTaskEntity; +import xyz.wbsite.frame.provider.LogTaskCollector; +import xyz.wbsite.frame.utils.LogUtil; import java.util.Date; import java.util.concurrent.ScheduledFuture; +/** + * 抽象任务 + * + * @author wangbing + * @version 0.0.1 + * @since 2020-01-01 + */ public abstract class RunTask implements Runnable { public abstract String taskId(); - public abstract ScheduledFuture schedule(ThreadPoolTaskScheduler poolTaskScheduler); + protected abstract void task(); + + public String taskName() { + return ""; + } - public void configChange(ThreadPoolTaskScheduler scheduler) { - ScheduledFuture schedule = scheduler.schedule(this, new Date()); - if (!schedule.cancel(true)) { + public String taskNote() { + return ""; + } + + @Override + public void run() { + LogTaskEntity logTaskEntity = new LogTaskEntity(); + logTaskEntity.setTaskId(taskId()); + logTaskEntity.setTaskName(taskName()); + logTaskEntity.setStartTime(new Date()); + try { + boolean before = before(); + if (before) { + task(); + } + after(); + logTaskEntity.setExecState("1"); + logTaskEntity.setExecResult("成功"); + logTaskEntity.setEndTime(new Date()); + } catch (Exception e) { + exception(e); + // 保证异常信息不会超过字段长度 + String trace = LogUtil.getTrace(e); + if (trace.length() > 496) { + trace = trace.substring(0, 496); + } + logTaskEntity.setExecState("0"); + logTaskEntity.setExecResult(String.format("失败[%s]", trace)); + logTaskEntity.setEndTime(new Date()); + } + try { + // 任务执行结果 + logTaskEntity.setExecTime((int) (logTaskEntity.getEndTime().getTime() - logTaskEntity.getStartTime().getTime())); + LogTaskCollector logtaskManager = LocalData.getBean(LogTaskCollector.class); + if (logtaskManager != null) logtaskManager.collector(logTaskEntity); + // todo 考虑是否将任务的异常归为故障 + } catch (Exception ignored) { } } -} + + /** + * 任务执行前执行 + * + * @return 是否继续执行任务 + */ + protected boolean before() { + return true; + } + + /** + * 任务执行后执行 + */ + protected void after() { + } + + /** + * 执行任务异常处理 + */ + protected void exception(Exception e) { + e.printStackTrace(); + } + + public abstract ScheduledFuture schedule(ThreadPoolTaskScheduler poolTaskScheduler); +} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/frame/sse/Sser.java b/src/main/java/xyz/wbsite/frame/sse/Sser.java new file mode 100644 index 0000000..a047244 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/sse/Sser.java @@ -0,0 +1,58 @@ +package xyz.wbsite.frame.sse; + +import org.springframework.http.MediaType; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; +import xyz.wbsite.frame.utils.MapperUtil; + +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; + +public class Sser { + + private static ConcurrentHashMap sseMap = new ConcurrentHashMap(); + + /** + * 注册推送服务 + */ + public static SseEmitter register(String key, SseEmitter sseEmitter) { + if (sseMap.get(key) != null) { + sseMap.remove(key); + } + sseMap.put(key, sseEmitter); + return sseEmitter; + } + + /** + * 消息推送 + * + * @param key key + * @param data 推送数据 + */ + public static void push(String key, Object data) { + SseEmitter sseEmitter = sseMap.get(key); + if (sseEmitter == null) { + return; + } + try { + sseEmitter.send(MapperUtil.toJson(data), MediaType.APPLICATION_JSON); + } catch (IOException e) { + sseMap.remove(key); + } + } + + /** + * 消息批量推送 + * + * @param data 推送数据 + */ + public static void pushAll(Object data) { + for (String s : sseMap.keySet()) { + try { + sseMap.get(s).send(MapperUtil.toJson(data), MediaType.APPLICATION_JSON); + } catch (IOException e) { + sseMap.remove(s); + } + } + } + +} diff --git a/src/main/java/xyz/wbsite/frame/utils/Base64Util.java b/src/main/java/xyz/wbsite/frame/utils/Base64Util.java index 614c782..746c3be 100644 --- a/src/main/java/xyz/wbsite/frame/utils/Base64Util.java +++ b/src/main/java/xyz/wbsite/frame/utils/Base64Util.java @@ -10,6 +10,7 @@ import java.util.Arrays; * @since 2017-01-01 */ public class Base64Util { + private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); private static final int[] IA = new int[256]; diff --git a/src/main/java/xyz/wbsite/frame/utils/ClassUtil.java b/src/main/java/xyz/wbsite/frame/utils/ClassUtil.java index 30c915a..e651f39 100644 --- a/src/main/java/xyz/wbsite/frame/utils/ClassUtil.java +++ b/src/main/java/xyz/wbsite/frame/utils/ClassUtil.java @@ -1,11 +1,26 @@ package xyz.wbsite.frame.utils; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.*; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Stack; /** - * ClassUtil + * ClassUtil类工具 * * @author wangbing * @version 0.0.1 @@ -14,28 +29,53 @@ import java.util.*; public class ClassUtil { /** - * 获取模板类所有字段 + * 获取类的所有字段(不包含父类) * - * @param clazz 模板对象 + * @param clazz 类对象 + * @return 字段集合 + */ + public static Field[] getFields(Class clazz) { + return getFields(clazz, false); + } + + /** + * 获取类所有字段 + * + * @param clazz 类对象 * @param parentFirst 是否关注父类的字段 - * @return + * @return 字段对象 */ public static Field[] getFields(Class clazz, boolean parentFirst) { Field[] fields = clazz.getDeclaredFields(); if (parentFirst) { Field[] parentFields = getParentFields(clazz.getSuperclass()); - return concat(fields, parentFields); + return ArrayUtil.merge(fields, parentFields); } return fields; } /** - * 判断是不是集合的实现类 + * 获取父类字段集合 * - * @param clazz + * @param clazz 类对象 * @return */ + private static Field[] getParentFields(Class clazz) { + if (clazz != null && clazz.getSuperclass() != null) { + Field[] pfs = clazz.getSuperclass().getDeclaredFields(); + Field[] ppfs = getParentFields(clazz.getSuperclass()); + return ArrayUtil.merge(pfs, ppfs); + } + return new Field[0]; + } + + /** + * 判断是不是集合的实现类 + * + * @param clazz 类对象 + * @return 是否 + */ public static boolean isCollection(Class clazz) { return Collection.class.isAssignableFrom(clazz); } @@ -44,10 +84,10 @@ public class ClassUtil { * 获取GET方法 * * @param name 成员变量名 - * @param pojoClass POJO对象 - * @return 方法 + * @param pojoClass 类对象 + * @return 方法对象 */ - public static Method getMethod(String name, Class pojoClass) throws RuntimeException { + public static Method getMethod(String name, Class pojoClass) { String getMethodName = "get" + StringUtil.upperFirstWord(name); try { return pojoClass.getMethod(getMethodName); @@ -66,17 +106,23 @@ public class ClassUtil { * * @param name 成员变量名 * @param pojoClass POJO对象 - * @return 方法 + * @return 方法对象 */ public static Method setMethod(String name, Class pojoClass, Class type) { String setMethodName = "set" + StringUtil.upperFirstWord(name); try { return pojoClass.getMethod(setMethodName, type); } catch (Exception e) { - return null; + throw new RuntimeException("can not find[" + name + "]method"); } } + /** + * 判断字段是否为自定义类 + * + * @param field 字段 + * @return 是否 + */ public static boolean isJavaClass(Field field) { Class fieldType = field.getType(); boolean isBaseClass = false; @@ -92,23 +138,139 @@ public class ClassUtil { return isBaseClass; } - public static Field[] getFields(Class clazz) { - return getFields(clazz, false); + /** + * @param sourcePath 源文件路径 + * @param classPath 编译文件路径 + * @return 是否成功 + */ + public static boolean compile(String sourcePath, String classPath) { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + Iterable options = Arrays.asList("-d", classPath); + List fileList = listJavaFile(sourcePath); + File[] files = new File[fileList.size()]; + fileList.toArray(files); + Iterable javaFileObjects = fileManager.getJavaFileObjects(files); + JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, javaFileObjects); + return task.call(); } - private static Field[] getParentFields(Class parentClazz) { - if (parentClazz != null) { - Field[] fields = parentClazz.getDeclaredFields(); - Field[] parentFields = getParentFields(parentClazz.getSuperclass()); - return concat(fields, parentFields); + /** + * @param className 类名 + * @param classContent 类内容 + * @param classPath 编译路径 + * @return 是否编译成功 + */ + public static boolean compileStringJava(String className, String classContent, String classPath) { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + Iterable options = Arrays.asList("-d", classPath); + SimpleJavaFileObject simpleJavaFileObject = new SimpleJavaFileObject( + URI.create("string:///" + className.replace('.', '/') + JavaFileObject.Kind.SOURCE.extension), + JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return classContent; + } + }; + Iterable simpleJavaFileObjects = Arrays.asList(simpleJavaFileObject); + JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, simpleJavaFileObjects); + return task.call(); + } + + private static List listJavaFile(String sourcePath) { + ArrayList result = new ArrayList<>(); + File file = new File(sourcePath); + if (!file.exists()) file.mkdirs(); + + for (File item : file.listFiles()) { + if (item.isFile() && item.getName().endsWith(".java")) { + result.add(item); + } else if (item.isDirectory()) { + result.addAll(listJavaFile(item.getAbsolutePath())); + } } - return new Field[0]; + return result; } - private static Field[] concat(Field[] f1, Field[] f2) { - Field[] fields = new Field[f1.length + f2.length]; - System.arraycopy(f1, 0, fields, 0, f1.length); - System.arraycopy(f2, 0, fields, f1.length, f2.length); - return fields; + public static void loadClass(String classPath) throws Exception { + loadClass(new File(classPath)); + } + + /** + * 加载指定clazzPath + *

+ * 例如clazzPath = /classes class文件的实际位置是/classes/text/test.class + * + * @param classPath + * @throws Exception + */ + public static void loadClass(File classPath) throws Exception { + // 记录加载.class文件的数量 + int clazzCount = 0; + //only handle the folder + if (classPath.isFile()) { + classPath = classPath.getParentFile(); + } + + if (classPath.exists() && classPath.isDirectory()) { + // 获取路径长度 + int classPathLen = classPath.getAbsolutePath().length() + 1; + + Stack stack = new Stack<>(); + stack.push(classPath); + + // 遍历类路径 + while (stack.isEmpty() == false) { + File path = stack.pop(); + File[] classFiles = path.listFiles(new FileFilter() { + public boolean accept(File pathname) { + return pathname.isDirectory() || pathname.getName().endsWith(".class"); + } + }); + for (File subFile : classFiles) { + if (subFile.isDirectory()) { + stack.push(subFile); + } else { + if (clazzCount++ == 0) { + Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + boolean accessible = method.isAccessible(); + try { + if (accessible == false) { + method.setAccessible(true); + } + // 设置类加载器 + URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); + // 将当前类路径加入到类加载器中 + method.invoke(classLoader, classPath.toURI().toURL()); + } finally { + method.setAccessible(accessible); + } + } + // 文件名称 + String className = subFile.getAbsolutePath(); + className = className.substring(classPathLen, className.length() - 6); + className = className.replace(File.separatorChar, '.'); + // 加载Class类 + Class.forName(className); + System.out.println(String.format("读取应用程序类文件[class=%s]", className)); + } + } + } + } + } + + /** + * 获取指定类 + * 获取之前请确认是否加载 {@link #loadClass(File)} + * 与Class.forName()相比,两者都可以装载类,但如果程序依赖于Class是否被初始化,就必须用Class.forName(name)了。 + * + * @param className 类名(包含package,不含后缀) + * @return 类 + * @throws Exception 获取类异常 + */ + public static Class getClass(String className) throws Exception { + ClassLoader loader = ClassUtil.class.getClassLoader(); + return loader.loadClass(className); } } diff --git a/src/main/java/xyz/wbsite/frame/utils/CookieUtil.java b/src/main/java/xyz/wbsite/frame/utils/CookieUtil.java index c407f25..c619f3e 100644 --- a/src/main/java/xyz/wbsite/frame/utils/CookieUtil.java +++ b/src/main/java/xyz/wbsite/frame/utils/CookieUtil.java @@ -1,8 +1,7 @@ package xyz.wbsite.frame.utils; -import xyz.wbsite.frame.auth.LocalData; +import xyz.wbsite.frame.base.LocalData; import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** @@ -42,9 +41,7 @@ public class CookieUtil { * @param value 值 */ public static Cookie newCookie(String name, String value) { - HttpServletRequest request = LocalData.getRequest(); Cookie cookie = new Cookie(name, value); - cookie.setDomain(request.getServerName()); cookie.setMaxAge(-1); cookie.setPath("/"); return cookie; @@ -56,10 +53,8 @@ public class CookieUtil { * @param name 键 */ public static void clearCookie(String name) { - HttpServletRequest request = LocalData.getRequest(); HttpServletResponse response = LocalData.getResponse(); Cookie cookie = new Cookie(name, null); - cookie.setDomain(request.getServerName()); cookie.setMaxAge(0); cookie.setPath("/"); response.addCookie(cookie); diff --git a/src/main/java/xyz/wbsite/frame/utils/MD5Util.java b/src/main/java/xyz/wbsite/frame/utils/MD5Util.java index db3831f..e66fb6c 100644 --- a/src/main/java/xyz/wbsite/frame/utils/MD5Util.java +++ b/src/main/java/xyz/wbsite/frame/utils/MD5Util.java @@ -47,7 +47,7 @@ public class MD5Util { try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] e = md.digest(value.getBytes()); - return toHexString(e); + return BytesUtil.bytes2Hex(e); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return value; @@ -64,28 +64,10 @@ public class MD5Util { try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] e = md.digest(bytes); - return toHexString(e); + return BytesUtil.bytes2Hex(e); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return ""; } } - - /** - * @param bytes 信息摘要字节数组 - * @return Hex字符串 - */ - private static String toHexString(byte bytes[]) { - StringBuilder hs = new StringBuilder(); - String stmp = ""; - for (int n = 0; n < bytes.length; n++) { - stmp = Integer.toHexString(bytes[n] & 0xff); - if (stmp.length() == 1) - hs.append("0").append(stmp); - else - hs.append(stmp); - } - - return hs.toString(); - } } diff --git a/src/main/java/xyz/wbsite/frame/utils/RandomUtil.java b/src/main/java/xyz/wbsite/frame/utils/RandomUtil.java new file mode 100644 index 0000000..1acb9a3 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/utils/RandomUtil.java @@ -0,0 +1,33 @@ +package xyz.wbsite.frame.utils; + +import java.util.Random; + +public class RandomUtil { + + /** + * 获取一个最小为[min,max)范围的随机数 + * @param min 最小(包含) + * @param max 最大(不包含) + * @return + */ + public static int getInt(int min, int max) { + Random random = new Random(); + int nextInt = random.nextInt(max - min); + return nextInt + min; + } + + /** + * 获取一串指定长度、并指定随机源的字符串 + * @param dict 随机源字典 + * @param len 长度 + * @return + */ + public static String getString(String dict, int len) { + Random r = new Random(); + StringBuilder rs = new StringBuilder(); + for (int j = 0; j < len; j++) { + rs.append(dict.charAt(r.nextInt(dict.length()))); + } + return rs.toString(); + } +} diff --git a/src/main/java/xyz/wbsite/frame/utils/RequestUtil.java b/src/main/java/xyz/wbsite/frame/utils/RequestUtil.java index a9fe557..a6d0861 100644 --- a/src/main/java/xyz/wbsite/frame/utils/RequestUtil.java +++ b/src/main/java/xyz/wbsite/frame/utils/RequestUtil.java @@ -1,6 +1,13 @@ package xyz.wbsite.frame.utils; +import xyz.wbsite.frame.base.LocalData; + +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * RequestUtil @@ -76,4 +83,81 @@ public class RequestUtil { return ""; } } + + public static String getScheme(HttpServletRequest request) { + String url = request.getRequestURL().toString(); + Pattern compile = Pattern.compile("(http|https)://(.*)/"); + Matcher matcher = compile.matcher(url); + if (matcher.find()) { + String group = matcher.group(1); + return group; + } + return ""; + } + + public static String getDomain(HttpServletRequest request) { + String url = request.getRequestURL().toString(); + Pattern compile = Pattern.compile("(http|https)://(.*)(:.*)?/"); + Matcher matcher = compile.matcher(url); + if (matcher.find()) { + String group = matcher.group(2); + return group; + } + return ""; + } + + public static int getPort(HttpServletRequest request) { + String url = request.getRequestURL().toString(); + Pattern compile = Pattern.compile("(http|https)://(.*)(:.*)?/"); + Matcher matcher = compile.matcher(url); + if (matcher.find()) { + String group = matcher.group(3); + if (group == null) { + return Integer.parseInt(group); + } + } + return 80; + } + + public static void setRedirect(String url) { + HttpServletResponse response = LocalData.getResponse(); + try { + response.sendRedirect(url); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void setForward(String url) { + HttpServletRequest request = LocalData.getRequest(); + HttpServletResponse response = LocalData.getResponse(); + try { + request.getRequestDispatcher(url).forward(request, response); + } catch (ServletException | IOException e) { + e.printStackTrace(); + } + } + + public static String getHeader(HttpServletRequest request, String head, String defaultValue) { + try { + return request.getHeader(head); + } catch (Exception e) { + return defaultValue; + } + } + + public static String getHeader(HttpServletRequest request, String head) { + return getHeader(request, head, null); + } + + public static Pattern actionPattern = Pattern.compile("^/(.+)\\.htm"); + + public static String getPage() { + HttpServletRequest request = LocalData.getRequest(); + Matcher matcher = actionPattern.matcher(request.getServletPath()); + if (!matcher.find()) { + return ""; + } + return matcher.group(1); + } } diff --git a/src/main/java/xyz/wbsite/frame/utils/ResourceUtil.java b/src/main/java/xyz/wbsite/frame/utils/ResourceUtil.java index eab3c72..9ddb00a 100644 --- a/src/main/java/xyz/wbsite/frame/utils/ResourceUtil.java +++ b/src/main/java/xyz/wbsite/frame/utils/ResourceUtil.java @@ -5,15 +5,16 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.util.ResourceUtils; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -25,27 +26,78 @@ import java.util.regex.Pattern; */ public class ResourceUtil extends ResourceUtils { + /** + * 获取当前运行主目录 + * 当开发时获取:E:\...\classes + * 当JAR包时: E:\...\***.jar + * + * @return jar路径 + */ + public static File getApplicationHome() { + ApplicationHome home = new ApplicationHome(ResourceUtil.class); + return home.getSource(); + } + + /** + * 列出指定目录下文件名 + * + * @param resourcePath 目录 + * @return 文件名集合 + */ + public static List listFileName(String resourcePath) { + if (!resourcePath.endsWith("/")) { + resourcePath = resourcePath + "/"; + } + List result = new ArrayList<>(); + List urls = ResourceUtil.listURL(resourcePath); + for (URL url : urls) { + File file1 = new File(url.getFile()); + if (file1.isFile()) { + result.add(file1.getName()); + } else if (!file1.isDirectory() && !url.getFile().endsWith("/")) { + result.add(file1.getName()); + } + } + return result; + } + + /** + * @param resourceLocation 资源路径 + * @return URL + * @throws FileNotFoundException 文件未找到异常 + */ + public static URL getURL(String resourceLocation) throws FileNotFoundException { + if (!resourceLocation.startsWith("classpath:")) { + resourceLocation = "classpath:" + resourceLocation; + } + return ResourceUtils.getURL(resourceLocation); + } + /** * 获取资源目录下所有文件名 如: /modules/dir/ * * @param resourcePath 路径 * @return */ - public static List getResourceFiles(String resourcePath) { - List result = new ArrayList<>(); + public static List listURL(String resourcePath) { + if (!resourcePath.startsWith("/")) { + resourcePath = "/" + resourcePath; + } + if (!resourcePath.endsWith("/")) { + resourcePath = resourcePath + "/"; + } + List result = new ArrayList<>(); File applicationHome = getApplicationHome(); - if (applicationHome.getAbsolutePath().endsWith(".jar")) { + if (applicationHome.getName().endsWith(".jar")) { try { - Pattern pattern = Pattern.compile(".*" + resourcePath + "(.+\\..+)"); + Pattern pattern = Pattern.compile("BOOT-INF/classes" + resourcePath + "[^/]+/?$"); JarFile jarFile = new JarFile(applicationHome); Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = entries.nextElement(); String name = jarEntry.getName(); - - if (name.matches(".*" + resourcePath + "(.+\\..+)")) { - Matcher matcher = pattern.matcher(name); - if (matcher.find()) result.add(matcher.group(1)); + if (pattern.matcher(name).find()) { + result.add(getURL(name)); } } } catch (IOException e) { @@ -56,35 +108,24 @@ public class ResourceUtil extends ResourceUtils { ClassPathResource cpr = new ClassPathResource(resourcePath); File in = cpr.getFile(); for (File file : in.listFiles()) { - result.add(file.getName()); + result.add(FileUtil.getURL(file.getAbsolutePath())); } return result; } catch (IOException e) { e.printStackTrace(); } } - return result; } /** - * 获取当前运行jar文件 - * - * @return jar路径 - */ - public static File getApplicationHome() { - ApplicationHome home = new ApplicationHome(ResourceUtil.class); - return home.getSource(); - } - - /** - * 获取resource下文件 + * 获取资源输入流 * - * @return 文件路径 + * @return 资源路径 */ - public static InputStream getResourceInput(String resource) { + public static InputStream getInput(String resourceLocation) { try { - ClassPathResource classPathResource = new ClassPathResource(resource); + ClassPathResource classPathResource = new ClassPathResource(resourceLocation); return classPathResource.getInputStream(); } catch (IOException e) { return null; @@ -92,53 +133,55 @@ public class ResourceUtil extends ResourceUtils { } /** - * 复制jar下的资源文件到指定文件 + * 获取资源的的字节数组 * - * @return 成功或失败情况 + * @return 字节数组 */ - public static boolean copyResource2File(String resource, File file) { - InputStream resourceInput = getResourceInput(resource); - FileOutputStream fileOutputStream = null; + public static byte[] getBytes(String resourceLocation) { + InputStream is = null; + byte[] result = null; try { - if (!file.exists()) { - file.createNewFile(); - } - fileOutputStream = new FileOutputStream(file); - FileUtil.copy(resourceInput, fileOutputStream); + is = getInput(resourceLocation); + result = new byte[is.available()]; + is.read(result); } catch (IOException e) { e.printStackTrace(); - return false; } finally { try { - if (fileOutputStream != null) fileOutputStream.close(); + if (is != null) is.close(); } catch (IOException e) { e.printStackTrace(); } } - return true; + return result; } /** - * 获取资源的的字节数组 + * 复制类文件下的资源文件 * - * @return 字节数组 + * @param resourceLocation 资源路径 + * @param file 输出文件 + * @return 成功或失败情况 */ - public static byte[] getResourceBytes(String resource) { - InputStream is = null; - byte[] result = null; + public static boolean copyToFile(String resourceLocation, File file) { + InputStream resourceInput = getInput(resourceLocation); + FileOutputStream fileOutputStream = null; try { - is = getResourceInput(resource); - result = new byte[is.available()]; - is.read(result); + if (!file.exists()) { + throw new RuntimeException(file.getAbsolutePath() + " not exists!"); + } + fileOutputStream = FileUtil.openOutputStream(file); + FileUtil.copy(resourceInput, fileOutputStream); } catch (IOException e) { e.printStackTrace(); + return false; } finally { try { - if (is != null) is.close(); + if (fileOutputStream != null) fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } - return result; + return true; } -} +} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/frame/utils/SqlUtil.java b/src/main/java/xyz/wbsite/frame/utils/SqlUtil.java new file mode 100644 index 0000000..75795f1 --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/utils/SqlUtil.java @@ -0,0 +1,129 @@ +package xyz.wbsite.frame.utils; + +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import xyz.wbsite.frame.base.LocalData; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class SqlUtil { + + public static void exec(String sql) { + SqlSession sqlSession = null; + try { + SqlSessionFactory factory = LocalData.getBean(SqlSessionFactory.class); + sqlSession = factory.openSession(true); + Connection connection = sqlSession.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql); + statement.execute(); + } catch (SQLException e) { + throw new RuntimeException(String.format("[ %s ]执行错误!", sql)); + } finally { + if (sqlSession != null) sqlSession.close(); + } + } + + public static int insert(String sql) { + return update(sql); + } + + public static int delete(String sql) { + return update(sql); + } + + public static int update(String sql) { + SqlSession sqlSession = null; + int result = 0; + try { + SqlSessionFactory factory = LocalData.getBean(SqlSessionFactory.class); + sqlSession = factory.openSession(true); + Connection connection = sqlSession.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql); + result = statement.executeUpdate(); + statement.close(); + connection.close(); + } catch (SQLException e) { + throw new RuntimeException(String.format("[ %s ]执行错误!", sql)); + } finally { + if (sqlSession != null) sqlSession.close(); + } + return result; + } + + public static List select(String sql, Class t) { + List result = new ArrayList<>(); + try { + SqlSessionFactory factory = LocalData.getBean(SqlSessionFactory.class); + SqlSession sqlSession = factory.openSession(true); + Connection connection = sqlSession.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql); + ResultSet resultSet = statement.executeQuery(); + while (resultSet.next()) { + T instance = t.newInstance(); + Field[] fields = t.getDeclaredFields(); + for (Field field : fields) { + Method method = ClassUtil.setMethod(field.getName(), t, field.getType()); + if (field.getType() == String.class) { + String v = resultSet.getString(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Boolean.class || field.getType() == boolean.class) { + boolean v = resultSet.getBoolean(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Byte.class || field.getType() == byte.class) { + byte v = resultSet.getByte(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Short.class || field.getType() == short.class) { + short v = resultSet.getShort(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Character.class || field.getType() == char.class) { + short v = resultSet.getShort(field.getName()); + method.invoke(instance, (char) v); + } else if (field.getType() == Integer.class || field.getType() == int.class) { + int v = resultSet.getInt(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Long.class || field.getType() == long.class) { + long v = resultSet.getLong(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Float.class || field.getType() == float.class) { + float v = resultSet.getFloat(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Double.class || field.getType() == double.class) { + double v = resultSet.getDouble(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Byte[].class || field.getType() == byte[].class) { + byte[] v = resultSet.getBytes(field.getName()); + method.invoke(instance, v); + } else if (field.getType() == Date.class) { + Date v = resultSet.getDate(field.getName()); + method.invoke(instance, v); + } else { + String v = resultSet.getString(field.getName()); + method.invoke(instance, v); + } + } + result.add(instance); + } + statement.close(); + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + return result; + } + +} diff --git a/src/main/java/xyz/wbsite/frame/utils/StringUtil.java b/src/main/java/xyz/wbsite/frame/utils/StringUtil.java index 767dbe8..b93c4b1 100644 --- a/src/main/java/xyz/wbsite/frame/utils/StringUtil.java +++ b/src/main/java/xyz/wbsite/frame/utils/StringUtil.java @@ -1,17 +1,86 @@ package xyz.wbsite.frame.utils; +import java.util.Arrays; + +/** + * 字符串相关工具 + */ public class StringUtil { - public static int getByteLength(String str) { - int length = str.replaceAll("[^\\x00-\\xff]", "**").length(); + /** + * 字符串右填充 + * ("A", 10, "0")==> A000000000 + * + * @param text 待填充字符串 + * @param length 总长度 + * @param c 填充字符 + * @return 补充完成的字符串 + */ + public static String padRight(String text, int length, char c) { + if (text == null) { + throw new IllegalArgumentException("text can not be null!"); + } + if (text.length() > length) { + throw new IllegalArgumentException("text's length " + text.length() + " is too long!"); + } + char[] array = new char[length]; + Arrays.fill(array, text.length(), length, c); + System.arraycopy(text.toCharArray(), 0, array, 0, text.length()); + return new String(array); + } + + /** + * 字符串左填充 + * ("A", 10, "0")==> 000000000A + * + * @param text 待填充字符串 + * @param length 总长度 + * @param c 填充字符 + * @return 补充完成的字符串 + */ + public static String padLeft(String text, int length, char c) { + if (text == null) { + throw new IllegalArgumentException("text can not be null!"); + } + if (text.length() > length) { + throw new IllegalArgumentException("text's length " + text.length() + " is too long!"); + } + char[] array = new char[length]; + Arrays.fill(array, 0, length - text.length(), c); + System.arraycopy(text.toCharArray(), 0, array, length - text.length(), text.length()); + return new String(array); + } + + /** + * 获取字符(包含汉字)长度 + * 我 ==> 2 + * + * @param value + * @return + */ + public static int getByteLength(String value) { + int length = value.replaceAll("[^\\x00-\\xff]", "**").length(); return length; } - public static String upperFirstWord(String str) { - String temp = str.substring(0, 1); - return temp.toUpperCase() + str.substring(1); + /** + * 首字母转大写 + * myCar ==> MyCar + * + * @param value + * @return + */ + public static String upperFirstWord(String value) { + String temp = value.substring(0, 1); + return temp.toUpperCase() + value.substring(1); } + /** + * 判断字符是否为空 + * + * @param value 字符对象 + * @return + */ public static boolean isEmpty(String value) { int strLen; if (value == null || (strLen = value.length()) == 0) { @@ -25,20 +94,27 @@ public class StringUtil { return true; } - + /** + * 判断字符是否不为空 + * + * @param value 字符对象 + * @return + */ public static boolean isNotEmpty(String value) { return !isEmpty(value); } - /** * 检查对象是否为数字型字符串,包含负数开头的。 + * + * @param value 对象 + * @return */ - public static boolean isNumeric(Object obj) { - if (obj == null) { + public static boolean isNumeric(Object value) { + if (value == null) { return false; } - char[] chars = obj.toString().toCharArray(); + char[] chars = value.toString().toCharArray(); int length = chars.length; if (length < 1) return false; @@ -56,7 +132,11 @@ public class StringUtil { } /** - * 把通用字符编码的字符串转化为汉字编码。 + * 把通用字符编码的字符串转化为汉字编码 + * 例: \u6211 ==> 我 + * + * @param unicode 字符编码 + * @return */ public static String unicodeToChinese(String unicode) { StringBuilder out = new StringBuilder(); @@ -68,7 +148,13 @@ public class StringUtil { return out.toString(); } - + /** + * 字符串驼峰式转下划线式 + * 例:myCar ==> my_car + * + * @param name + * @return + */ public static String toUnderlineStyle(String name) { StringBuilder newName = new StringBuilder(); for (int i = 0; i < name.length(); i++) { diff --git a/src/main/java/xyz/wbsite/frame/utils/VerifyCodeUtil.java b/src/main/java/xyz/wbsite/frame/utils/VerifyCodeUtil.java new file mode 100644 index 0000000..27617ab --- /dev/null +++ b/src/main/java/xyz/wbsite/frame/utils/VerifyCodeUtil.java @@ -0,0 +1,182 @@ +package xyz.wbsite.frame.utils; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; + +/** + * 验证码生成工具 + * 通过Builder对象构建参数 + * + * @author wangbing + * @version 0.0.1 + * @since 2020-05-01 + */ +public class VerifyCodeUtil { + + public static class Builder { + private String code; + private int size = 35; + private String dict = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"; + private BufferedImage bufferedImage; + private boolean freeColor = true; + private Color color = Color.BLACK; + private Color bgColor = Color.WHITE; + + public Builder code(String code) { + this.code = code; + return this; + } + + public Builder size(int size) { + this.size = size; + return this; + } + + public Builder dict(String dict) { + this.dict = dict; + return this; + } + + public Builder freeColor(boolean freeColor) { + this.freeColor = freeColor; + return this; + } + + public Builder color(Color color) { + this.color = color; + return this; + } + + public Builder bgColor(Color bgColor) { + this.bgColor = bgColor; + return this; + } + + public boolean toFile(File file) { + if (bufferedImage == null) build(); + try { + ImageIO.write(bufferedImage, "png", file); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + public String toCode() { + return code; + } + + public byte[] toBytes() { + if (bufferedImage == null) build(); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + try { + ImageIO.write(bufferedImage, "png", stream); + return stream.toByteArray(); + } catch (IOException e) { + + } + return null; + } + + public String toBase64() { + if (bufferedImage == null) build(); + return Base64Util.encodeToString(toBytes()); + } + + public Builder build() { + if (StringUtil.isEmpty(code)) { + this.code = RandomUtil.getString(dict, 4); + } + + if (bufferedImage == null) { + bufferedImage = new BufferedImage(size * code.length(), size, BufferedImage.TYPE_INT_RGB); + } + + draw(this, bufferedImage); + return this; + } + } + + /** + * 根据Builder参数取绘制验证码 + * + * @param builder 构建参数 + * @param verifyImg 抽象图片 + */ + public static void draw(Builder builder, BufferedImage verifyImg) { + //验证码 + String code = builder.code; + //方块大小 + int size = builder.size; + //宽度 + int width = builder.size * builder.code.length(); + //高度 + int height = builder.size; + //背景色 + Color bgColor = builder.bgColor; + //是否随机颜色 + boolean freeColor = builder.freeColor; + //字符颜色,仅当freeColor为false时生效 + Color color = builder.color; + + Graphics2D graphics = (Graphics2D) verifyImg.getGraphics(); + graphics.setColor(bgColor);//设置画笔颜色-验证码背景色 + graphics.fillRect(0, 0, width, height);//填充背景 + graphics.setFont(new Font("微软雅黑", Font.BOLD, (int) (height * 0.9))); + + for (int i = 0; i < code.length(); i++) { + char c = code.charAt(i); + int descent = graphics.getFontMetrics().getDescent();// 字符基线以下高度 + int charWidth = graphics.getFontMetrics().charWidth(c);// 字符高度 + int charHeight = graphics.getFontMetrics().getHeight();// 字符高度 + + int centerX = size * i + size / 2;// 字符水平中心坐标 + int centerY = size / 2;// 字符垂直中心坐标 + int offsetX = -charWidth / 2; + int offsetY = charHeight / 2 - descent; + + // 设置颜色 + graphics.setColor(freeColor ? getRandomColor() : color); + // 设置字体旋转角度 + int degree = RandomUtil.getInt(-30, 30); + // 旋转 + graphics.rotate(degree * Math.PI / 180, centerX, centerY); + // 绘制字符 + graphics.drawString(String.valueOf(c), centerX + offsetX, centerY + offsetY); + // 恢复旋转 + graphics.rotate(-degree * Math.PI / 180, centerX, centerY); + } + + //画干扰线 + for (int i = 0; i < size / 5; i++) { + // 设置颜色 + graphics.setColor(freeColor ? getRandomColor() : color); + // 随机画线 + graphics.drawLine(RandomUtil.getInt(1, width), RandomUtil.getInt(1, height), RandomUtil.getInt(1, width), RandomUtil.getInt(1, height)); + } + + //添加噪点 + for (int i = 0; i < size; i++) { + int x1 = RandomUtil.getInt(1, width); + int y1 = RandomUtil.getInt(1, height); + graphics.setColor(freeColor ? getRandomColor() : color); + graphics.fillRect(x1, y1, 2, 2); + } + } + + /** + * 获得一个随机颜色 + */ + private static Color getRandomColor() { + int r = RandomUtil.getInt(0, 256); + int g = RandomUtil.getInt(0, 256); + int b = RandomUtil.getInt(0, 256); + Color color = new Color(r, g, b); + return color; + } +} diff --git a/src/main/java/xyz/wbsite/frame/utils/ZipUtil.java b/src/main/java/xyz/wbsite/frame/utils/ZipUtil.java index 4707c1b..e8a3442 100644 --- a/src/main/java/xyz/wbsite/frame/utils/ZipUtil.java +++ b/src/main/java/xyz/wbsite/frame/utils/ZipUtil.java @@ -6,6 +6,13 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; +/** + * ZipUtil - Zip解压打包工具 + * + * @author wangbing + * @version 0.0.1 + * @since 2017-01-01 + */ public class ZipUtil { /** @@ -128,11 +135,4 @@ public class ZipUtil { in.close(); } } - - public static void main(String[] args) { - //解压 - unZip(new File("E:\\AAA.zip"), new File("E:\\AAA")); - //压缩 - toZip(new File("E:\\AAA"), new File("E:\\AAA.zip")); - } } diff --git a/src/main/java/xyz/wbsite/module/admin/ent/Services.java b/src/main/java/xyz/wbsite/module/admin/ent/Services.java new file mode 100644 index 0000000..1a61873 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/ent/Services.java @@ -0,0 +1,119 @@ +package xyz.wbsite.module.admin.ent; + +import xyz.wbsite.frame.excel.annotation.ExcelNote; +import xyz.wbsite.frame.excel.annotation.ExcelSelect; +import com.alibaba.excel.annotation.ExcelProperty; +import xyz.wbsite.frame.excel.annotation.ExcelSheet; +import xyz.wbsite.frame.base.BaseEntity; + +/** + * SERVICES - 虚拟主机 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +@ExcelSheet("虚拟主机") +public class Services extends BaseEntity { + + /** + * TITLE - 主机标题 + */ + @ExcelProperty("主机标题") + @ExcelNote("") + private String title; + /** + * DOMAIN - 主机域名 + */ + @ExcelProperty("主机域名") + @ExcelNote("") + private String domain; + /** + * TYPE - 服务类型 + */ + @ExcelProperty("服务类型") + @ExcelNote("") + private String type; + /** + * PORT - 服务端口 + */ + @ExcelProperty("服务端口") + @ExcelNote("") + private Integer port; + /** + * VALID - 是否启用 + */ + @ExcelProperty("是否启用") + @ExcelNote("") + @ExcelSelect({"是","否"}) + private Boolean valid; + /** + * FILTER - 启用过滤 + */ + @ExcelProperty("启用过滤") + @ExcelNote("") + @ExcelSelect({"是","否"}) + private Boolean filter; + /** + * FILTER_CONF - 过滤配置 + */ + @ExcelProperty("过滤配置") + @ExcelNote("") + private String filterConf; + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDomain() { + return this.domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public Integer getPort() { + return this.port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public Boolean getValid() { + return this.valid; + } + + public void setValid(Boolean valid) { + this.valid = valid; + } + + public Boolean getFilter() { + return this.filter; + } + + public void setFilter(Boolean filter) { + this.filter = filter; + } + + public String getFilterConf() { + return this.filterConf; + } + + public void setFilterConf(String filterConf) { + this.filterConf = filterConf; + } +} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/module/admin/mgr/ConfigDataManagerImpl.java b/src/main/java/xyz/wbsite/module/admin/mgr/ConfigDataManagerImpl.java new file mode 100644 index 0000000..0464c28 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mgr/ConfigDataManagerImpl.java @@ -0,0 +1,168 @@ +package xyz.wbsite.module.admin.mgr; + +import xyz.wbsite.frame.utils.IDgenerator; +import xyz.wbsite.frame.utils.Message; +import xyz.wbsite.frame.base.ErrorType; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.frame.utils.MapperUtil; +import xyz.wbsite.frame.utils.ValidationUtil; +import xyz.wbsite.module.admin.ent.ConfigData; +import xyz.wbsite.module.admin.mpr.ConfigDataMapper; +import xyz.wbsite.module.admin.req.ConfigDataCreateRequest; +import xyz.wbsite.module.admin.req.ConfigDataDeleteRequest; +import xyz.wbsite.module.admin.req.ConfigDataFindRequest; +import xyz.wbsite.module.admin.req.ConfigDataUpdateRequest; +import xyz.wbsite.module.admin.rsp.ConfigDataCreateResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataDeleteResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataFindResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataUpdateResponse; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.github.pagehelper.util.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * CONFIG_DATA - 配置数据 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +@Transactional +@Service +public class ConfigDataManagerImpl implements ConfigDataManager { + + @Autowired + private ConfigDataMapper configDataMapper; + + /** + * 插入 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public ConfigDataCreateResponse create(ConfigDataCreateRequest request, Token token) { + ConfigDataCreateResponse response = new ConfigDataCreateResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + {// 配置名称唯一检查 + ConfigDataFindRequest configDataFindRequest = new ConfigDataFindRequest(); + configDataFindRequest.setConfName(request.getConfName()); + ConfigDataFindResponse configDataFindResponse = this.find(configDataFindRequest, token); + if (configDataFindResponse.hasError()) { + response.addErrors(configDataFindResponse.getErrors()); + return response; + } else if (configDataFindResponse.getTotalCount() > 0) { + response.addError(ErrorType.UNIQUENESS_ERROR, "[confName]配置名称已存在,请检查!"); + return response; + } + } + + long id = IDgenerator.nextId(); + ConfigData entity = MapperUtil.map(request, ConfigData.class); + entity.setId(id); + + long result = configDataMapper.insert(entity, token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.CREATE_FAILURE); + return response; + } + response.setId(id); + + return response; + } + + /** + * 逻辑删除 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public ConfigDataDeleteResponse delete(ConfigDataDeleteRequest request, Token token) { + ConfigDataDeleteResponse response = new ConfigDataDeleteResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + long result = configDataMapper.delete(request.getId(), token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.DELETE_FAILURE); + return response; + } + response.setResult(result); + + return response; + } + + /** + * 更新 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public ConfigDataUpdateResponse update(ConfigDataUpdateRequest request, Token token) { + ConfigDataUpdateResponse response = new ConfigDataUpdateResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + ConfigData entity = configDataMapper.getById(request.getId(), token); + if (entity == null) { + response.addError(ErrorType.BUSINESS_ERROR, Message.GET_FAILURE); + return response; + } + + MapperUtil.map(request, entity); + long result = configDataMapper.update(entity, token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.UPDATE_FAILURE); + return response; + } + response.setResult(result); + + return response; + } + + /** + * 查询 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + @Transactional(readOnly = true) + public ConfigDataFindResponse find(ConfigDataFindRequest request, Token token) { + ConfigDataFindResponse response = new ConfigDataFindResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + if (request.getPageSize() != 0) { + PageHelper.startPage(request.getPageNumber(), request.getPageSize()); + } + if (StringUtil.isNotEmpty(request.getSortKey())) { + PageHelper.orderBy(request.getSortKey() + " " + request.getSortType()); + } + PageInfo pageInfo = new PageInfo<>(configDataMapper.find(request, token)); + + response.setResult(pageInfo.getList()); + response.setTotalCount(pageInfo.getTotal()); + + return response; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/mgr/ConfigManager.java b/src/main/java/xyz/wbsite/module/admin/mgr/ConfigManager.java new file mode 100644 index 0000000..70533d0 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mgr/ConfigManager.java @@ -0,0 +1,57 @@ +package xyz.wbsite.module.admin.mgr; + +import xyz.wbsite.module.admin.req.ConfigCreateRequest; +import xyz.wbsite.module.admin.req.ConfigDeleteRequest; +import xyz.wbsite.module.admin.req.ConfigFindRequest; +import xyz.wbsite.module.admin.req.ConfigUpdateRequest; +import xyz.wbsite.module.admin.rsp.ConfigCreateResponse; +import xyz.wbsite.module.admin.rsp.ConfigDeleteResponse; +import xyz.wbsite.module.admin.rsp.ConfigFindResponse; +import xyz.wbsite.module.admin.rsp.ConfigUpdateResponse; +import xyz.wbsite.frame.base.Token; + +/** + * 配置预设 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public interface ConfigManager { + + /** + * 插入 + * + * @param request 请求对象 + * @param token 令牌 + * @return + */ + ConfigCreateResponse create(ConfigCreateRequest request, Token token); + + /** + * 逻辑删除 + * + * @param request 请求对象 + * @param token 令牌 + * @return + */ + ConfigDeleteResponse delete(ConfigDeleteRequest request, Token token); + + /** + * 更新 + * + * @param request 请求对象 + * @param token 令牌 + * @return + */ + ConfigUpdateResponse update(ConfigUpdateRequest request, Token token); + + /** + * 查询 + * + * @param request 请求对象 + * @param token 令牌 + * @return + */ + ConfigFindResponse find(ConfigFindRequest request, Token token); +} diff --git a/src/main/java/xyz/wbsite/module/conf/mgr/MappingManagerImpl.java b/src/main/java/xyz/wbsite/module/admin/mgr/ConfigManagerImpl.java similarity index 52% rename from src/main/java/xyz/wbsite/module/conf/mgr/MappingManagerImpl.java rename to src/main/java/xyz/wbsite/module/admin/mgr/ConfigManagerImpl.java index bcab1ba..dc58efd 100644 --- a/src/main/java/xyz/wbsite/module/conf/mgr/MappingManagerImpl.java +++ b/src/main/java/xyz/wbsite/module/admin/mgr/ConfigManagerImpl.java @@ -1,44 +1,41 @@ -package xyz.wbsite.module.conf.mgr; +package xyz.wbsite.module.admin.mgr; +import xyz.wbsite.frame.utils.IDgenerator; +import xyz.wbsite.frame.utils.Message; +import xyz.wbsite.frame.base.ErrorType; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.frame.utils.MapperUtil; +import xyz.wbsite.frame.utils.ValidationUtil; +import xyz.wbsite.module.admin.ent.Config; +import xyz.wbsite.module.admin.mpr.ConfigMapper; +import xyz.wbsite.module.admin.req.ConfigCreateRequest; +import xyz.wbsite.module.admin.req.ConfigDeleteRequest; +import xyz.wbsite.module.admin.req.ConfigFindRequest; +import xyz.wbsite.module.admin.req.ConfigUpdateRequest; +import xyz.wbsite.module.admin.rsp.ConfigCreateResponse; +import xyz.wbsite.module.admin.rsp.ConfigDeleteResponse; +import xyz.wbsite.module.admin.rsp.ConfigFindResponse; +import xyz.wbsite.module.admin.rsp.ConfigUpdateResponse; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.github.pagehelper.util.StringUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import xyz.wbsite.frame.auth.Token; -import xyz.wbsite.frame.base.ErrorType; -import xyz.wbsite.frame.base.SortType; -import xyz.wbsite.frame.utils.IDgenerator; -import xyz.wbsite.frame.utils.MapperUtil; -import xyz.wbsite.frame.utils.Message; -import xyz.wbsite.frame.utils.ValidationUtil; -import xyz.wbsite.module.conf.ent.Mapping; -import xyz.wbsite.module.conf.mpr.MappingMapper; -import xyz.wbsite.module.conf.req.MappingCreateRequest; -import xyz.wbsite.module.conf.req.MappingDeleteRequest; -import xyz.wbsite.module.conf.req.MappingFindRequest; -import xyz.wbsite.module.conf.req.MappingGetRequest; -import xyz.wbsite.module.conf.req.MappingUpdateRequest; -import xyz.wbsite.module.conf.rsp.MappingCreateResponse; -import xyz.wbsite.module.conf.rsp.MappingDeleteResponse; -import xyz.wbsite.module.conf.rsp.MappingFindResponse; -import xyz.wbsite.module.conf.rsp.MappingGetResponse; -import xyz.wbsite.module.conf.rsp.MappingUpdateResponse; /** - * MAPPING - 映射 + * CONFIG - 配置预设 * * @author wangbing * @version 0.0.1 - * @since 2020-03-18 + * @since 2021-02-07 */ @Transactional @Service -public class MappingManagerImpl implements MappingManager { +public class ConfigManagerImpl implements ConfigManager { @Autowired - private MappingMapper mappingMapper; + private ConfigMapper configMapper; /** * 插入 @@ -47,19 +44,32 @@ public class MappingManagerImpl implements MappingManager { * @param token 令牌 * @return 响应 */ - public MappingCreateResponse create(MappingCreateRequest request, Token token) { - MappingCreateResponse response = new MappingCreateResponse(); + public ConfigCreateResponse create(ConfigCreateRequest request, Token token) { + ConfigCreateResponse response = new ConfigCreateResponse(); ValidationUtil.validate(request, response); if (response.hasError()) { return response; } + {// 配置名称唯一检查 + ConfigFindRequest configFindRequest = new ConfigFindRequest(); + configFindRequest.setConfName(request.getConfName()); + ConfigFindResponse configFindResponse = this.find(configFindRequest, token); + if (configFindResponse.hasError()) { + response.addErrors(configFindResponse.getErrors()); + return response; + } else if (configFindResponse.getTotalCount() > 0) { + response.addError(ErrorType.UNIQUENESS_ERROR, "[confName]配置名称已存在,请检查!"); + return response; + } + } + long id = IDgenerator.nextId(); - Mapping entity = MapperUtil.map(request, Mapping.class); + Config entity = MapperUtil.map(request, Config.class); entity.setId(id); - long result = mappingMapper.insert(entity, token); + long result = configMapper.insert(entity, token); if (1L != result) { response.addError(ErrorType.BUSINESS_ERROR, Message.CREATE_FAILURE); return response; @@ -76,15 +86,15 @@ public class MappingManagerImpl implements MappingManager { * @param token 令牌 * @return 响应 */ - public MappingDeleteResponse delete(MappingDeleteRequest request, Token token) { - MappingDeleteResponse response = new MappingDeleteResponse(); + public ConfigDeleteResponse delete(ConfigDeleteRequest request, Token token) { + ConfigDeleteResponse response = new ConfigDeleteResponse(); ValidationUtil.validate(request, response); if (response.hasError()) { return response; } - long result = mappingMapper.delete(request, token); + long result = configMapper.delete(request.getId(), token); if (1L != result) { response.addError(ErrorType.BUSINESS_ERROR, Message.DELETE_FAILURE); return response; @@ -101,15 +111,22 @@ public class MappingManagerImpl implements MappingManager { * @param token 令牌 * @return 响应 */ - public MappingUpdateResponse update(MappingUpdateRequest request, Token token) { - MappingUpdateResponse response = new MappingUpdateResponse(); + public ConfigUpdateResponse update(ConfigUpdateRequest request, Token token) { + ConfigUpdateResponse response = new ConfigUpdateResponse(); ValidationUtil.validate(request, response); if (response.hasError()) { return response; } - long result = mappingMapper.update(request, token); + Config entity = configMapper.getById(request.getId(), token); + if (entity == null) { + response.addError(ErrorType.BUSINESS_ERROR, Message.GET_FAILURE); + return response; + } + + MapperUtil.map(request, entity); + long result = configMapper.update(entity, token); if (1L != result) { response.addError(ErrorType.BUSINESS_ERROR, Message.UPDATE_FAILURE); return response; @@ -127,8 +144,8 @@ public class MappingManagerImpl implements MappingManager { * @return 响应 */ @Transactional(readOnly = true) - public MappingFindResponse find(MappingFindRequest request, Token token) { - MappingFindResponse response = new MappingFindResponse(); + public ConfigFindResponse find(ConfigFindRequest request, Token token) { + ConfigFindResponse response = new ConfigFindResponse(); ValidationUtil.validate(request, response); if (response.hasError()) { @@ -139,40 +156,13 @@ public class MappingManagerImpl implements MappingManager { PageHelper.startPage(request.getPageNumber(), request.getPageSize()); } if (StringUtil.isNotEmpty(request.getSortKey())) { - PageHelper.orderBy(request.getSortKey() + " " + (request.getSortType() != null ? request.getSortType() : SortType.ASC)); + PageHelper.orderBy(request.getSortKey() + " " + request.getSortType()); } - PageInfo pageInfo = new PageInfo<>(mappingMapper.find(request, token)); + PageInfo pageInfo = new PageInfo<>(configMapper.find(request, token)); response.setResult(pageInfo.getList()); response.setTotalCount(pageInfo.getTotal()); return response; } - - /** - * 获得对象 - * - * @param request 请求对象 - * @param token 令牌 - * @return 响应 - */ - @Transactional(readOnly = true) - public MappingGetResponse get(MappingGetRequest request, Token token) { - MappingGetResponse response = new MappingGetResponse(); - - ValidationUtil.validate(request, response); - if (response.hasError()) { - return response; - } - - Mapping po = mappingMapper.get(request, token); - - if (po != null) { - response.setMapping(po); - } else { - response.addError(ErrorType.BUSINESS_ERROR, Message.GET_FAILURE); - } - - return response; - } } diff --git a/src/main/java/xyz/wbsite/module/admin/mgr/LocationsManager.java b/src/main/java/xyz/wbsite/module/admin/mgr/LocationsManager.java new file mode 100644 index 0000000..05b31c2 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mgr/LocationsManager.java @@ -0,0 +1,57 @@ +package xyz.wbsite.module.admin.mgr; + +import xyz.wbsite.module.admin.req.LocationsCreateRequest; +import xyz.wbsite.module.admin.req.LocationsDeleteRequest; +import xyz.wbsite.module.admin.req.LocationsFindRequest; +import xyz.wbsite.module.admin.req.LocationsUpdateRequest; +import xyz.wbsite.module.admin.rsp.LocationsCreateResponse; +import xyz.wbsite.module.admin.rsp.LocationsDeleteResponse; +import xyz.wbsite.module.admin.rsp.LocationsFindResponse; +import xyz.wbsite.module.admin.rsp.LocationsUpdateResponse; +import xyz.wbsite.frame.base.Token; + +/** + * 路径配置 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public interface LocationsManager { + + /** + * 插入 + * + * @param request 请求对象 + * @param token 令牌 + * @return + */ + LocationsCreateResponse create(LocationsCreateRequest request, Token token); + + /** + * 逻辑删除 + * + * @param request 请求对象 + * @param token 令牌 + * @return + */ + LocationsDeleteResponse delete(LocationsDeleteRequest request, Token token); + + /** + * 更新 + * + * @param request 请求对象 + * @param token 令牌 + * @return + */ + LocationsUpdateResponse update(LocationsUpdateRequest request, Token token); + + /** + * 查询 + * + * @param request 请求对象 + * @param token 令牌 + * @return + */ + LocationsFindResponse find(LocationsFindRequest request, Token token); +} diff --git a/src/main/java/xyz/wbsite/module/admin/mgr/LocationsManagerImpl.java b/src/main/java/xyz/wbsite/module/admin/mgr/LocationsManagerImpl.java new file mode 100644 index 0000000..18c3712 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mgr/LocationsManagerImpl.java @@ -0,0 +1,168 @@ +package xyz.wbsite.module.admin.mgr; + +import xyz.wbsite.frame.utils.IDgenerator; +import xyz.wbsite.frame.utils.Message; +import xyz.wbsite.frame.base.ErrorType; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.frame.utils.MapperUtil; +import xyz.wbsite.frame.utils.ValidationUtil; +import xyz.wbsite.module.admin.ent.Locations; +import xyz.wbsite.module.admin.mpr.LocationsMapper; +import xyz.wbsite.module.admin.req.LocationsCreateRequest; +import xyz.wbsite.module.admin.req.LocationsDeleteRequest; +import xyz.wbsite.module.admin.req.LocationsFindRequest; +import xyz.wbsite.module.admin.req.LocationsUpdateRequest; +import xyz.wbsite.module.admin.rsp.LocationsCreateResponse; +import xyz.wbsite.module.admin.rsp.LocationsDeleteResponse; +import xyz.wbsite.module.admin.rsp.LocationsFindResponse; +import xyz.wbsite.module.admin.rsp.LocationsUpdateResponse; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.github.pagehelper.util.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * LOCATIONS - 路径配置 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +@Transactional +@Service +public class LocationsManagerImpl implements LocationsManager { + + @Autowired + private LocationsMapper locationsMapper; + + /** + * 插入 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public LocationsCreateResponse create(LocationsCreateRequest request, Token token) { + LocationsCreateResponse response = new LocationsCreateResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + {// 配置标题唯一检查 + LocationsFindRequest locationsFindRequest = new LocationsFindRequest(); + locationsFindRequest.setLocalTitle(request.getLocalTitle()); + LocationsFindResponse locationsFindResponse = this.find(locationsFindRequest, token); + if (locationsFindResponse.hasError()) { + response.addErrors(locationsFindResponse.getErrors()); + return response; + } else if (locationsFindResponse.getTotalCount() > 0) { + response.addError(ErrorType.UNIQUENESS_ERROR, "[localTitle]配置标题已存在,请检查!"); + return response; + } + } + + long id = IDgenerator.nextId(); + Locations entity = MapperUtil.map(request, Locations.class); + entity.setId(id); + + long result = locationsMapper.insert(entity, token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.CREATE_FAILURE); + return response; + } + response.setId(id); + + return response; + } + + /** + * 逻辑删除 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public LocationsDeleteResponse delete(LocationsDeleteRequest request, Token token) { + LocationsDeleteResponse response = new LocationsDeleteResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + long result = locationsMapper.delete(request.getId(), token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.DELETE_FAILURE); + return response; + } + response.setResult(result); + + return response; + } + + /** + * 更新 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public LocationsUpdateResponse update(LocationsUpdateRequest request, Token token) { + LocationsUpdateResponse response = new LocationsUpdateResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + Locations entity = locationsMapper.getById(request.getId(), token); + if (entity == null) { + response.addError(ErrorType.BUSINESS_ERROR, Message.GET_FAILURE); + return response; + } + + MapperUtil.map(request, entity); + long result = locationsMapper.update(entity, token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.UPDATE_FAILURE); + return response; + } + response.setResult(result); + + return response; + } + + /** + * 查询 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + @Transactional(readOnly = true) + public LocationsFindResponse find(LocationsFindRequest request, Token token) { + LocationsFindResponse response = new LocationsFindResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + if (request.getPageSize() != 0) { + PageHelper.startPage(request.getPageNumber(), request.getPageSize()); + } + if (StringUtil.isNotEmpty(request.getSortKey())) { + PageHelper.orderBy(request.getSortKey() + " " + request.getSortType()); + } + PageInfo pageInfo = new PageInfo<>(locationsMapper.find(request, token)); + + response.setResult(pageInfo.getList()); + response.setTotalCount(pageInfo.getTotal()); + + return response; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/mgr/ServicesManagerImpl.java b/src/main/java/xyz/wbsite/module/admin/mgr/ServicesManagerImpl.java new file mode 100644 index 0000000..5f7a085 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mgr/ServicesManagerImpl.java @@ -0,0 +1,194 @@ +package xyz.wbsite.module.admin.mgr; + +import xyz.wbsite.frame.utils.IDgenerator; +import xyz.wbsite.frame.utils.Message; +import xyz.wbsite.frame.base.ErrorType; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.frame.utils.MapperUtil; +import xyz.wbsite.frame.utils.ValidationUtil; +import xyz.wbsite.module.admin.ent.Services; +import xyz.wbsite.module.admin.mpr.ServicesMapper; +import xyz.wbsite.module.admin.req.ServicesCreateRequest; +import xyz.wbsite.module.admin.req.ServicesDeleteRequest; +import xyz.wbsite.module.admin.req.ServicesFindRequest; +import xyz.wbsite.module.admin.req.ServicesUpdateRequest; +import xyz.wbsite.module.admin.rsp.ServicesCreateResponse; +import xyz.wbsite.module.admin.rsp.ServicesDeleteResponse; +import xyz.wbsite.module.admin.rsp.ServicesFindResponse; +import xyz.wbsite.module.admin.rsp.ServicesUpdateResponse; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.github.pagehelper.util.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * SERVICES - 虚拟主机 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +@Transactional +@Service +public class ServicesManagerImpl implements ServicesManager { + + @Autowired + private ServicesMapper servicesMapper; + + /** + * 插入 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public ServicesCreateResponse create(ServicesCreateRequest request, Token token) { + ServicesCreateResponse response = new ServicesCreateResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + {// 主机标题唯一检查 + ServicesFindRequest servicesFindRequest = new ServicesFindRequest(); + servicesFindRequest.setTitle(request.getTitle()); + ServicesFindResponse servicesFindResponse = this.find(servicesFindRequest, token); + if (servicesFindResponse.hasError()) { + response.addErrors(servicesFindResponse.getErrors()); + return response; + } else if (servicesFindResponse.getTotalCount() > 0) { + response.addError(ErrorType.UNIQUENESS_ERROR, "[title]主机标题已存在,请检查!"); + return response; + } + } + + {// 主机域名唯一检查 + ServicesFindRequest servicesFindRequest = new ServicesFindRequest(); + servicesFindRequest.setDomain(request.getDomain()); + ServicesFindResponse servicesFindResponse = this.find(servicesFindRequest, token); + if (servicesFindResponse.hasError()) { + response.addErrors(servicesFindResponse.getErrors()); + return response; + } else if (servicesFindResponse.getTotalCount() > 0) { + response.addError(ErrorType.UNIQUENESS_ERROR, "[domain]主机域名已存在,请检查!"); + return response; + } + } + + {// 服务端口唯一检查 + ServicesFindRequest servicesFindRequest = new ServicesFindRequest(); + servicesFindRequest.setPort(request.getPort()); + ServicesFindResponse servicesFindResponse = this.find(servicesFindRequest, token); + if (servicesFindResponse.hasError()) { + response.addErrors(servicesFindResponse.getErrors()); + return response; + } else if (servicesFindResponse.getTotalCount() > 0) { + response.addError(ErrorType.UNIQUENESS_ERROR, "[port]服务端口已存在,请检查!"); + return response; + } + } + + long id = IDgenerator.nextId(); + Services entity = MapperUtil.map(request, Services.class); + entity.setId(id); + + long result = servicesMapper.insert(entity, token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.CREATE_FAILURE); + return response; + } + response.setId(id); + + return response; + } + + /** + * 逻辑删除 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public ServicesDeleteResponse delete(ServicesDeleteRequest request, Token token) { + ServicesDeleteResponse response = new ServicesDeleteResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + long result = servicesMapper.delete(request.getId(), token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.DELETE_FAILURE); + return response; + } + response.setResult(result); + + return response; + } + + /** + * 更新 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + public ServicesUpdateResponse update(ServicesUpdateRequest request, Token token) { + ServicesUpdateResponse response = new ServicesUpdateResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + Services entity = servicesMapper.getById(request.getId(), token); + if (entity == null) { + response.addError(ErrorType.BUSINESS_ERROR, Message.GET_FAILURE); + return response; + } + + MapperUtil.map(request, entity); + long result = servicesMapper.update(entity, token); + if (1L != result) { + response.addError(ErrorType.BUSINESS_ERROR, Message.UPDATE_FAILURE); + return response; + } + response.setResult(result); + + return response; + } + + /** + * 查询 + * + * @param request 请求对象 + * @param token 令牌 + * @return 响应 + */ + @Transactional(readOnly = true) + public ServicesFindResponse find(ServicesFindRequest request, Token token) { + ServicesFindResponse response = new ServicesFindResponse(); + + ValidationUtil.validate(request, response); + if (response.hasError()) { + return response; + } + + if (request.getPageSize() != 0) { + PageHelper.startPage(request.getPageNumber(), request.getPageSize()); + } + if (StringUtil.isNotEmpty(request.getSortKey())) { + PageHelper.orderBy(request.getSortKey() + " " + request.getSortType()); + } + PageInfo pageInfo = new PageInfo<>(servicesMapper.find(request, token)); + + response.setResult(pageInfo.getList()); + response.setTotalCount(pageInfo.getTotal()); + + return response; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/mpr/ConfigDataMapper.xml b/src/main/java/xyz/wbsite/module/admin/mpr/ConfigDataMapper.xml new file mode 100644 index 0000000..9883532 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mpr/ConfigDataMapper.xml @@ -0,0 +1,187 @@ + + + + + "NA_CONFIG_DATA" + + + "ID","TARGET_ID","CONF_NAME","CONF_TYPE","CONF_VALUE","CONF_NOTE","ROW_VERSION","IS_DELETED","CREATE_BY","CREATE_TIME","LAST_UPDATE_BY","LAST_UPDATE_TIME" + + + + + + + + + + + + + + + + + + + INSERT INTO + + ( + + ) + VALUES + ( + #{request.id}, + #{request.targetId,jdbcType=BIGINT}, + #{request.confName,jdbcType=VARCHAR}, + #{request.confType,jdbcType=VARCHAR}, + #{request.confValue,jdbcType=VARCHAR}, + #{request.confNote,jdbcType=VARCHAR}, + 0, + 0, + #{token.userId,jdbcType=NUMERIC}, + datetime('now','localtime'), + NULL, + NULL + ) + + + + INSERT INTO + + ( + + ) + VALUES + + #{item.id}, + #{item.targetId,jdbcType=BIGINT}, + #{item.confName,jdbcType=VARCHAR}, + #{item.confType,jdbcType=VARCHAR}, + #{item.confValue,jdbcType=VARCHAR}, + #{item.confNote,jdbcType=VARCHAR}, + 0, + 0, + #{token.userId,jdbcType=NUMERIC}, + datetime('now','localtime'), + NULL, + NULL + + + + + UPDATE + + SET "IS_DELETED" = 1 + WHERE "IS_DELETED" = 0 + AND "ID" = #{id} + + + + UPDATE + + SET "IS_DELETED" = 1 + WHERE "IS_DELETED" = 0 + AND "ID" IN + + #{item} + + + + + UPDATE + + SET + TARGET_ID = #{request.targetId,jdbcType=BIGINT}, + CONF_NAME = #{request.confName,jdbcType=VARCHAR}, + CONF_TYPE = #{request.confType,jdbcType=VARCHAR}, + CONF_VALUE = #{request.confValue,jdbcType=VARCHAR}, + CONF_NOTE = #{request.confNote,jdbcType=VARCHAR}, + "ROW_VERSION" = "ROW_VERSION" + 1, + "LAST_UPDATE_BY" = #{token.userId}, + "LAST_UPDATE_TIME" = datetime('now','localtime') + WHERE "IS_DELETED" = 0 + AND "ID" = #{request.id} + AND "ROW_VERSION" = #{request.rowVersion} + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/module/admin/mpr/ConfigMapper.xml b/src/main/java/xyz/wbsite/module/admin/mpr/ConfigMapper.xml new file mode 100644 index 0000000..fadf5f0 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mpr/ConfigMapper.xml @@ -0,0 +1,177 @@ + + + + + "NA_CONFIG" + + + "ID","CONF_NAME","CONF_TYPE","CONF_VALUE","CONF_NOTE","ROW_VERSION","IS_DELETED","CREATE_BY","CREATE_TIME","LAST_UPDATE_BY","LAST_UPDATE_TIME" + + + + + + + + + + + + + + + + + + INSERT INTO + + ( + + ) + VALUES + ( + #{request.id}, + #{request.confName,jdbcType=VARCHAR}, + #{request.confType,jdbcType=VARCHAR}, + #{request.confValue,jdbcType=VARCHAR}, + #{request.confNote,jdbcType=VARCHAR}, + 0, + 0, + #{token.userId,jdbcType=NUMERIC}, + datetime('now','localtime'), + NULL, + NULL + ) + + + + INSERT INTO + + ( + + ) + VALUES + + #{item.id}, + #{item.confName,jdbcType=VARCHAR}, + #{item.confType,jdbcType=VARCHAR}, + #{item.confValue,jdbcType=VARCHAR}, + #{item.confNote,jdbcType=VARCHAR}, + 0, + 0, + #{token.userId,jdbcType=NUMERIC}, + datetime('now','localtime'), + NULL, + NULL + + + + + UPDATE + + SET "IS_DELETED" = 1 + WHERE "IS_DELETED" = 0 + AND "ID" = #{id} + + + + UPDATE + + SET "IS_DELETED" = 1 + WHERE "IS_DELETED" = 0 + AND "ID" IN + + #{item} + + + + + UPDATE + + SET + CONF_NAME = #{request.confName,jdbcType=VARCHAR}, + CONF_TYPE = #{request.confType,jdbcType=VARCHAR}, + CONF_VALUE = #{request.confValue,jdbcType=VARCHAR}, + CONF_NOTE = #{request.confNote,jdbcType=VARCHAR}, + "ROW_VERSION" = "ROW_VERSION" + 1, + "LAST_UPDATE_BY" = #{token.userId}, + "LAST_UPDATE_TIME" = datetime('now','localtime') + WHERE "IS_DELETED" = 0 + AND "ID" = #{request.id} + AND "ROW_VERSION" = #{request.rowVersion} + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/module/admin/mpr/LocationsMapper.java b/src/main/java/xyz/wbsite/module/admin/mpr/LocationsMapper.java new file mode 100644 index 0000000..9a9a6e6 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mpr/LocationsMapper.java @@ -0,0 +1,100 @@ +package xyz.wbsite.module.admin.mpr; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.module.admin.ent.Locations; +import xyz.wbsite.module.admin.req.LocationsFindRequest; + +import java.util.List; + +/** + * LOCATIONS - 路径配置 + * + * @author wangbing + * @since 2021-02-07 + */ +@Mapper +public interface LocationsMapper { + + /** + * 插入 + * + * @param request 请求对象 + * @param token 令牌 + * @return 返回数量 + */ + long insert(@Param("request") Locations request, @Param("token") Token token); + + /** + * 批量插入 + * + * @param list 对象集合 + * @param token 令牌 + * @return 返回数量 + */ + long insertBatch(@Param("list") List list, @Param("token") Token token); + + /** + * 逻辑删除 + * + * @param id 主键 + * @param token 令牌 + * @return 返回数量 + */ + long delete(@Param("id") Long id, @Param("token") Token token); + + /** + * 批量逻辑删除 + * + * @param list 主键集合 + * @param token 令牌 + * @return 返回数量 + */ + long deleteBatch(@Param("list") List list, @Param("token") Token token); + + /** + * 更新 + * + * @param request 请求对象 + * @param token 令牌 + * @return 返回数量 + */ + long update(@Param("request") Locations request, @Param("token") Token token); + + /** + * 普通查询 + * + * @param request 请求对象 + * @param token 令牌 + * @return 返回对象 + */ + List select(@Param("request") Locations request, @Param("token") Token token); + + /** + * 高级查询 + * + * @param request 请求对象 + * @param token 令牌 + * @return 返回对象 + */ + List find(@Param("request") LocationsFindRequest request, @Param("token") Token token); + + /** + * 获得对象 + * + * @param id 主键 + * @param token 令牌 + * @return 返回对象 + */ + Locations getById(@Param("id") Long id, @Param("token") Token token); + + /** + * 获得对象 + * + * @param ids 主键集合 + * @param token 令牌 + * @return 返回对象 + */ + List getByIds(@Param("ids") Long[] ids, @Param("token") Token token); +} diff --git a/src/main/java/xyz/wbsite/module/admin/mpr/ServicesMapper.xml b/src/main/java/xyz/wbsite/module/admin/mpr/ServicesMapper.xml new file mode 100644 index 0000000..db4b419 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/mpr/ServicesMapper.xml @@ -0,0 +1,207 @@ + + + + + "NA_SERVICES" + + + "ID","TITLE","DOMAIN","TYPE","PORT","VALID","FILTER","FILTER_CONF","ROW_VERSION","IS_DELETED","CREATE_BY","CREATE_TIME","LAST_UPDATE_BY","LAST_UPDATE_TIME" + + + + + + + + + + + + + + + + + + + + + INSERT INTO + + ( + + ) + VALUES + ( + #{request.id}, + #{request.title,jdbcType=VARCHAR}, + #{request.domain,jdbcType=VARCHAR}, + #{request.type,jdbcType=VARCHAR}, + #{request.port,jdbcType=INTEGER}, + #{request.valid,jdbcType=BIT}, + #{request.filter,jdbcType=BIT}, + #{request.filterConf,jdbcType=VARCHAR}, + 0, + 0, + #{token.userId,jdbcType=NUMERIC}, + datetime('now','localtime'), + NULL, + NULL + ) + + + + INSERT INTO + + ( + + ) + VALUES + + #{item.id}, + #{item.title,jdbcType=VARCHAR}, + #{item.domain,jdbcType=VARCHAR}, + #{item.type,jdbcType=VARCHAR}, + #{item.port,jdbcType=INTEGER}, + #{item.valid,jdbcType=BIT}, + #{item.filter,jdbcType=BIT}, + #{item.filterConf,jdbcType=VARCHAR}, + 0, + 0, + #{token.userId,jdbcType=NUMERIC}, + datetime('now','localtime'), + NULL, + NULL + + + + + UPDATE + + SET "IS_DELETED" = 1 + WHERE "IS_DELETED" = 0 + AND "ID" = #{id} + + + + UPDATE + + SET "IS_DELETED" = 1 + WHERE "IS_DELETED" = 0 + AND "ID" IN + + #{item} + + + + + UPDATE + + SET + TITLE = #{request.title,jdbcType=VARCHAR}, + DOMAIN = #{request.domain,jdbcType=VARCHAR}, + TYPE = #{request.type,jdbcType=VARCHAR}, + PORT = #{request.port,jdbcType=INTEGER}, + VALID = #{request.valid,jdbcType=BIT}, + FILTER = #{request.filter,jdbcType=BIT}, + FILTER_CONF = #{request.filterConf,jdbcType=VARCHAR}, + "ROW_VERSION" = "ROW_VERSION" + 1, + "LAST_UPDATE_BY" = #{token.userId}, + "LAST_UPDATE_TIME" = datetime('now','localtime') + WHERE "IS_DELETED" = 0 + AND "ID" = #{request.id} + AND "ROW_VERSION" = #{request.rowVersion} + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/module/admin/req/ConfigDataCreateRequest.java b/src/main/java/xyz/wbsite/module/admin/req/ConfigDataCreateRequest.java new file mode 100644 index 0000000..195e349 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/req/ConfigDataCreateRequest.java @@ -0,0 +1,93 @@ +package xyz.wbsite.module.admin.req; + +import xyz.wbsite.frame.base.BaseRequest; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.NotBlank; +import org.hibernate.validator.constraints.Length; +import xyz.wbsite.frame.validation.Select; + +/** + * ConfigDataCreateRequest - 配置数据新增 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class ConfigDataCreateRequest extends BaseRequest { + + /** + * 目标主键. + */ + @NotNull(message = "[targetId]目标主键不能为NULL") + private Long targetId; + + /** + * 配置名称. + */ + @NotBlank(message = "[confName]配置名称不能为空") + @Length(min = 0, max = 50, message = "[confName]配置名称长度不合法(0-50)") + private String confName; + + /** + * 配置类型. + * HTTP:全局配置 + * SERVER:主机配置 + * LOCATION:路径配置 + */ + @NotNull(message = "[confType]配置类型不能为NULL") + @Select({"HTTP", "SERVER", "LOCATION"}) + private String confType; + + /** + * 配置属值. + */ + @NotBlank(message = "[confValue]配置属值不能为空") + @Length(min = 0, max = 255, message = "[confValue]配置属值长度不合法(0-255)") + private String confValue; + + /** + * 配置备注. + */ + @Length(min = 0, max = 255, message = "[confNote]配置备注长度不合法(0-255)") + private String confNote; + + public Long getTargetId() { + return this.targetId; + } + + public void setTargetId(Long targetId) { + this.targetId = targetId; + } + + public String getConfName() { + return this.confName; + } + + public void setConfName(String confName) { + this.confName = confName; + } + + public String getConfType() { + return this.confType; + } + + public void setConfType(String confType) { + this.confType = confType; + } + + public String getConfValue() { + return this.confValue; + } + + public void setConfValue(String confValue) { + this.confValue = confValue; + } + + public String getConfNote() { + return this.confNote; + } + + public void setConfNote(String confNote) { + this.confNote = confNote; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/req/ConfigDataFindRequest.java b/src/main/java/xyz/wbsite/module/admin/req/ConfigDataFindRequest.java new file mode 100644 index 0000000..a0ee4db --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/req/ConfigDataFindRequest.java @@ -0,0 +1,123 @@ +package xyz.wbsite.module.admin.req; + +import xyz.wbsite.frame.base.BaseFindRequest; +import java.util.Date; +import xyz.wbsite.frame.validation.Select; + +/** + * ConfigDataFindRequest - 配置数据查询 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class ConfigDataFindRequest extends BaseFindRequest { + + /** + * 目标主键. + */ + private Long targetId; + + /** + * 配置名称. + */ + private String confName; + + /** + * 配置名称模糊查询. + */ + private String confNameLike; + + /** + * 配置类型. + * HTTP:全局配置 + * SERVER:主机配置 + * LOCATION:路径配置 + */ + @Select({"HTTP", "SERVER", "LOCATION"}) + private String confType; + + /** + * 配置属值模糊查询. + */ + private String confValueLike; + + /** + * 配置备注模糊查询. + */ + private String confNoteLike; + + /** + * 开始日期. + */ + private Date startDate; + + /** + * 结束日期. + */ + private Date endDate; + + public Long getTargetId() { + return this.targetId; + } + + public void setTargetId(Long targetId) { + this.targetId = targetId; + } + + public String getConfName() { + return this.confName; + } + + public void setConfName(String confName) { + this.confName = confName; + } + + public String getConfNameLike() { + return this.confNameLike; + } + + public void setConfNameLike(String confNameLike) { + this.confNameLike = confNameLike; + } + + public String getConfType() { + return this.confType; + } + + public void setConfType(String confType) { + this.confType = confType; + } + + public String getConfValueLike() { + return this.confValueLike; + } + + public void setConfValueLike(String confValueLike) { + this.confValueLike = confValueLike; + } + + public String getConfNoteLike() { + return this.confNoteLike; + } + + public void setConfNoteLike(String confNoteLike) { + this.confNoteLike = confNoteLike; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/req/ConfigFindRequest.java b/src/main/java/xyz/wbsite/module/admin/req/ConfigFindRequest.java new file mode 100644 index 0000000..b6abc3e --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/req/ConfigFindRequest.java @@ -0,0 +1,110 @@ +package xyz.wbsite.module.admin.req; + +import xyz.wbsite.frame.base.BaseFindRequest; +import java.util.Date; +import xyz.wbsite.frame.validation.Select; + +/** + * ConfigFindRequest - 配置预设查询 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class ConfigFindRequest extends BaseFindRequest { + + /** + * 配置名称. + */ + private String confName; + + /** + * 配置名称模糊查询. + */ + private String confNameLike; + + /** + * 配置类型. + * HTTP:全局配置 + * SERVER:主机配置 + * LOCATION:路径配置 + */ + @Select({"HTTP", "SERVER", "LOCATION"}) + private String confType; + + /** + * 配置属值模糊查询. + */ + private String confValueLike; + + /** + * 配置备注模糊查询. + */ + private String confNoteLike; + + /** + * 开始日期. + */ + private Date startDate; + + /** + * 结束日期. + */ + private Date endDate; + + public String getConfName() { + return this.confName; + } + + public void setConfName(String confName) { + this.confName = confName; + } + + public String getConfNameLike() { + return this.confNameLike; + } + + public void setConfNameLike(String confNameLike) { + this.confNameLike = confNameLike; + } + + public String getConfType() { + return this.confType; + } + + public void setConfType(String confType) { + this.confType = confType; + } + + public String getConfValueLike() { + return this.confValueLike; + } + + public void setConfValueLike(String confValueLike) { + this.confValueLike = confValueLike; + } + + public String getConfNoteLike() { + return this.confNoteLike; + } + + public void setConfNoteLike(String confNoteLike) { + this.confNoteLike = confNoteLike; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/req/ConfigUpdateRequest.java b/src/main/java/xyz/wbsite/module/admin/req/ConfigUpdateRequest.java new file mode 100644 index 0000000..c0c9d42 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/req/ConfigUpdateRequest.java @@ -0,0 +1,93 @@ +package xyz.wbsite.module.admin.req; + +import xyz.wbsite.frame.base.BaseUpdateRequest; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import org.hibernate.validator.constraints.Length; +import javax.validation.constraints.NotEmpty; +import xyz.wbsite.frame.validation.Select; + +/** + * ConfigUpdateRequest - 配置预设更新 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class ConfigUpdateRequest extends BaseUpdateRequest { + + /** + * 主键. + */ + @NotNull(message = "[id]主键不能为NULL") + private Long id; + + /** + * 配置名称. + */ + @NotBlank(message = "[confName]配置名称不能为空") + @Length(min = 0, max = 50, message = "[confName]配置名称长度不合法(0-50)") + private String confName; + + /** + * 配置类型. + * HTTP:全局配置 + * SERVER:主机配置 + * LOCATION:路径配置 + */ + @NotNull(message = "[confType]配置类型不能为NULL") + @Select({"HTTP", "SERVER", "LOCATION"}) + private String confType; + + /** + * 配置属值. + */ + @Length(min = 0, max = 255, message = "[confValue]配置属值长度不合法(0-255)") + private String confValue; + + /** + * 配置备注. + */ + @Length(min = 0, max = 255, message = "[confNote]配置备注长度不合法(0-255)") + private String confNote; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getConfName() { + return this.confName; + } + + public void setConfName(String confName) { + this.confName = confName; + } + + public String getConfType() { + return this.confType; + } + + public void setConfType(String confType) { + this.confType = confType; + } + + public String getConfValue() { + return this.confValue; + } + + public void setConfValue(String confValue) { + this.confValue = confValue; + } + + public String getConfNote() { + return this.confNote; + } + + public void setConfNote(String confNote) { + this.confNote = confNote; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/req/LocationsDeleteRequest.java b/src/main/java/xyz/wbsite/module/admin/req/LocationsDeleteRequest.java new file mode 100644 index 0000000..3acd873 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/req/LocationsDeleteRequest.java @@ -0,0 +1,30 @@ +package xyz.wbsite.module.admin.req; + +import xyz.wbsite.frame.base.BaseRequest; + +import javax.validation.constraints.NotNull; + + +/** + * LocationsDeleteRequest - 路径配置删除 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class LocationsDeleteRequest extends BaseRequest { + + /** + * 主键. + */ + @NotNull(message = "[id]主键不能为空") + private Long id; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/req/LocationsFindRequest.java b/src/main/java/xyz/wbsite/module/admin/req/LocationsFindRequest.java new file mode 100644 index 0000000..a57f247 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/req/LocationsFindRequest.java @@ -0,0 +1,144 @@ +package xyz.wbsite.module.admin.req; + +import xyz.wbsite.frame.base.BaseFindRequest; +import java.util.Date; + +/** + * LocationsFindRequest - 路径配置查询 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class LocationsFindRequest extends BaseFindRequest { + + /** + * 服务主键. + */ + private Long serviceId; + + /** + * 配置标题. + */ + private String localTitle; + + /** + * 配置标题模糊查询. + */ + private String localTitleLike; + + /** + * 配置备注模糊查询. + */ + private String localNoteLike; + + /** + * 配置路径. + */ + private String localPath; + + /** + * 配置路径模糊查询. + */ + private String localPathLike; + + /** + * 是否启用. + */ + private Boolean localValid; + + /** + * 启用过滤. + */ + private Boolean filter; + + /** + * 开始日期. + */ + private Date startDate; + + /** + * 结束日期. + */ + private Date endDate; + + public Long getServiceId() { + return this.serviceId; + } + + public void setServiceId(Long serviceId) { + this.serviceId = serviceId; + } + + public String getLocalTitle() { + return this.localTitle; + } + + public void setLocalTitle(String localTitle) { + this.localTitle = localTitle; + } + + public String getLocalTitleLike() { + return this.localTitleLike; + } + + public void setLocalTitleLike(String localTitleLike) { + this.localTitleLike = localTitleLike; + } + + public String getLocalNoteLike() { + return this.localNoteLike; + } + + public void setLocalNoteLike(String localNoteLike) { + this.localNoteLike = localNoteLike; + } + + public String getLocalPath() { + return this.localPath; + } + + public void setLocalPath(String localPath) { + this.localPath = localPath; + } + + public String getLocalPathLike() { + return this.localPathLike; + } + + public void setLocalPathLike(String localPathLike) { + this.localPathLike = localPathLike; + } + + public Boolean getLocalValid() { + return this.localValid; + } + + public void setLocalValid(Boolean localValid) { + this.localValid = localValid; + } + + public Boolean getFilter() { + return this.filter; + } + + public void setFilter(Boolean filter) { + this.filter = filter; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/req/ServicesCreateRequest.java b/src/main/java/xyz/wbsite/module/admin/req/ServicesCreateRequest.java new file mode 100644 index 0000000..3b2afd0 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/req/ServicesCreateRequest.java @@ -0,0 +1,122 @@ +package xyz.wbsite.module.admin.req; + +import xyz.wbsite.frame.base.BaseRequest; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.NotBlank; +import org.hibernate.validator.constraints.Length; +import xyz.wbsite.frame.validation.Select; + +/** + * ServicesCreateRequest - 虚拟主机新增 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class ServicesCreateRequest extends BaseRequest { + + /** + * 主机标题. + */ + @NotBlank(message = "[title]主机标题不能为空") + @Length(min = 0, max = 50, message = "[title]主机标题长度不合法(0-50)") + private String title; + + /** + * 主机域名. + */ + @NotBlank(message = "[domain]主机域名不能为空") + @Length(min = 0, max = 50, message = "[domain]主机域名长度不合法(0-50)") + private String domain; + + /** + * 服务类型. + * 反向代理:反向代理 + * 负载均衡:负载均衡 + * 正向代理:正向代理 + * 文件代理:文件代理 + * 端口转发:端口转发 + */ + @NotNull(message = "[type]服务类型不能为NULL") + @Select({"反向代理", "负载均衡", "正向代理", "文件代理", "端口转发"}) + private String type; + + /** + * 服务端口. + */ + @NotNull(message = "[port]服务端口不能为NULL") + private Integer port; + + /** + * 是否启用. + */ + private Boolean valid; + + /** + * 启用过滤. + */ + @NotNull(message = "[filter]启用过滤不能为NULL") + private Boolean filter; + + /** + * 过滤配置. + */ + @Length(min = 0, max = 500, message = "[filterConf]过滤配置长度不合法(0-500)") + private String filterConf; + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDomain() { + return this.domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public Integer getPort() { + return this.port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public Boolean getValid() { + return this.valid; + } + + public void setValid(Boolean valid) { + this.valid = valid; + } + + public Boolean getFilter() { + return this.filter; + } + + public void setFilter(Boolean filter) { + this.filter = filter; + } + + public String getFilterConf() { + return this.filterConf; + } + + public void setFilterConf(String filterConf) { + this.filterConf = filterConf; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/req/ServicesUpdateRequest.java b/src/main/java/xyz/wbsite/module/admin/req/ServicesUpdateRequest.java new file mode 100644 index 0000000..1808818 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/req/ServicesUpdateRequest.java @@ -0,0 +1,137 @@ +package xyz.wbsite.module.admin.req; + +import xyz.wbsite.frame.base.BaseUpdateRequest; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import org.hibernate.validator.constraints.Length; +import javax.validation.constraints.NotEmpty; +import xyz.wbsite.frame.validation.Select; + +/** + * ServicesUpdateRequest - 虚拟主机更新 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class ServicesUpdateRequest extends BaseUpdateRequest { + + /** + * 主键. + */ + @NotNull(message = "[id]主键不能为NULL") + private Long id; + + /** + * 主机标题. + */ + @NotBlank(message = "[title]主机标题不能为空") + @Length(min = 0, max = 50, message = "[title]主机标题长度不合法(0-50)") + private String title; + + /** + * 主机域名. + */ + @NotBlank(message = "[domain]主机域名不能为空") + @Length(min = 0, max = 50, message = "[domain]主机域名长度不合法(0-50)") + private String domain; + + /** + * 服务类型. + * 反向代理:反向代理 + * 负载均衡:负载均衡 + * 正向代理:正向代理 + * 文件代理:文件代理 + * 端口转发:端口转发 + */ + @NotNull(message = "[type]服务类型不能为NULL") + @Select({"反向代理", "负载均衡", "正向代理", "文件代理", "端口转发"}) + private String type; + + /** + * 服务端口. + */ + @NotNull(message = "[port]服务端口不能为NULL") + private Integer port; + + /** + * 是否启用. + */ + private Boolean valid; + + /** + * 启用过滤. + */ + @NotNull(message = "[filter]启用过滤不能为NULL") + private Boolean filter; + + /** + * 过滤配置. + */ + @Length(min = 0, max = 500, message = "[filterConf]过滤配置长度不合法(0-500)") + private String filterConf; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDomain() { + return this.domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + this.type = type; + } + + public Integer getPort() { + return this.port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public Boolean getValid() { + return this.valid; + } + + public void setValid(Boolean valid) { + this.valid = valid; + } + + public Boolean getFilter() { + return this.filter; + } + + public void setFilter(Boolean filter) { + this.filter = filter; + } + + public String getFilterConf() { + return this.filterConf; + } + + public void setFilterConf(String filterConf) { + this.filterConf = filterConf; + } +} diff --git a/src/main/java/xyz/wbsite/module/conf/rsp/MappingUpdateResponse.java b/src/main/java/xyz/wbsite/module/admin/rsp/ConfigDataDeleteResponse.java similarity index 60% rename from src/main/java/xyz/wbsite/module/conf/rsp/MappingUpdateResponse.java rename to src/main/java/xyz/wbsite/module/admin/rsp/ConfigDataDeleteResponse.java index 00ecbcf..ebf7cf3 100644 --- a/src/main/java/xyz/wbsite/module/conf/rsp/MappingUpdateResponse.java +++ b/src/main/java/xyz/wbsite/module/admin/rsp/ConfigDataDeleteResponse.java @@ -1,18 +1,18 @@ -package xyz.wbsite.module.conf.rsp; +package xyz.wbsite.module.admin.rsp; import xyz.wbsite.frame.base.BaseResponse; /** - * MappingUpdateResponse - 映射 + * ConfigDataDeleteResponse - 配置数据 * * @author wangbing * @version 0.0.1 - * @since 2020-03-18 + * @since 2021-02-07 */ -public class MappingUpdateResponse extends BaseResponse { +public class ConfigDataDeleteResponse extends BaseResponse { /** - * 更新数目 + * 删除数目 */ private Long result; diff --git a/src/main/java/xyz/wbsite/module/admin/rsp/LocationsCreateResponse.java b/src/main/java/xyz/wbsite/module/admin/rsp/LocationsCreateResponse.java new file mode 100644 index 0000000..f7f3917 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/rsp/LocationsCreateResponse.java @@ -0,0 +1,26 @@ +package xyz.wbsite.module.admin.rsp; + +import xyz.wbsite.frame.base.BaseResponse; + +/** + * LocationsCreateResponse - 路径配置 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class LocationsCreateResponse extends BaseResponse { + + /** + * 主键 + */ + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/src/main/java/xyz/wbsite/module/admin/rsp/ServicesCreateResponse.java b/src/main/java/xyz/wbsite/module/admin/rsp/ServicesCreateResponse.java new file mode 100644 index 0000000..e693303 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/rsp/ServicesCreateResponse.java @@ -0,0 +1,26 @@ +package xyz.wbsite.module.admin.rsp; + +import xyz.wbsite.frame.base.BaseResponse; + +/** + * ServicesCreateResponse - 虚拟主机 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class ServicesCreateResponse extends BaseResponse { + + /** + * 主键 + */ + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/src/main/java/xyz/wbsite/module/conf/rsp/MappingDeleteResponse.java b/src/main/java/xyz/wbsite/module/admin/rsp/ServicesDeleteResponse.java similarity index 65% rename from src/main/java/xyz/wbsite/module/conf/rsp/MappingDeleteResponse.java rename to src/main/java/xyz/wbsite/module/admin/rsp/ServicesDeleteResponse.java index c05b13b..ca5651a 100644 --- a/src/main/java/xyz/wbsite/module/conf/rsp/MappingDeleteResponse.java +++ b/src/main/java/xyz/wbsite/module/admin/rsp/ServicesDeleteResponse.java @@ -1,15 +1,15 @@ -package xyz.wbsite.module.conf.rsp; +package xyz.wbsite.module.admin.rsp; import xyz.wbsite.frame.base.BaseResponse; /** - * MappingDeleteResponse - 映射 + * ServicesDeleteResponse - 虚拟主机 * * @author wangbing * @version 0.0.1 - * @since 2020-03-18 + * @since 2021-02-07 */ -public class MappingDeleteResponse extends BaseResponse { +public class ServicesDeleteResponse extends BaseResponse { /** * 删除数目 diff --git a/src/main/java/xyz/wbsite/module/admin/rsp/ServicesFindResponse.java b/src/main/java/xyz/wbsite/module/admin/rsp/ServicesFindResponse.java new file mode 100644 index 0000000..2b108f5 --- /dev/null +++ b/src/main/java/xyz/wbsite/module/admin/rsp/ServicesFindResponse.java @@ -0,0 +1,14 @@ +package xyz.wbsite.module.admin.rsp; + +import xyz.wbsite.frame.base.BaseFindResponse; +import xyz.wbsite.module.admin.ent.Services; + +/** + * ServicesFindResponse - 虚拟主机 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +public class ServicesFindResponse extends BaseFindResponse { +} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/module/conf/ent/Mapping.java b/src/main/java/xyz/wbsite/module/conf/ent/Mapping.java deleted file mode 100644 index 6621b38..0000000 --- a/src/main/java/xyz/wbsite/module/conf/ent/Mapping.java +++ /dev/null @@ -1,86 +0,0 @@ -package xyz.wbsite.module.conf.ent; - -import xyz.wbsite.frame.base.BaseEntity; - -/** - * MAPPING - 映射 - * - * @author wangbing - * @version 0.0.1 - * @since 2020-03-18 - */ -public class Mapping extends BaseEntity { - - /** - * NAME - 名称 - */ - private String name; - /** - * PORT - 端口 - */ - private String port; - /** - * PATH - 路径 - */ - private String path; - /** - * TYPE - 类型 - */ - private String type; - /** - * LOCATION - 代理地址 - */ - private String location; - /** - * NOTE - 备注 - */ - private String note; - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getPort() { - return this.port; - } - - public void setPort(String port) { - this.port = port; - } - - public String getPath() { - return this.path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getType() { - return this.type; - } - - public void setType(String type) { - this.type = type; - } - - public String getLocation() { - return this.location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getNote() { - return this.note; - } - - public void setNote(String note) { - this.note = note; - } -} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/module/conf/ent/Message.java b/src/main/java/xyz/wbsite/module/conf/ent/Message.java deleted file mode 100644 index c44f62b..0000000 --- a/src/main/java/xyz/wbsite/module/conf/ent/Message.java +++ /dev/null @@ -1,24 +0,0 @@ -package xyz.wbsite.module.conf.ent; - -public class Message { - - private MessageType type; - - private Object object; - - public MessageType getType() { - return type; - } - - public void setType(MessageType type) { - this.type = type; - } - - public Object getObject() { - return object; - } - - public void setObject(Object object) { - this.object = object; - } -} diff --git a/src/main/java/xyz/wbsite/module/conf/ent/MessageType.java b/src/main/java/xyz/wbsite/module/conf/ent/MessageType.java deleted file mode 100644 index 1ba0a62..0000000 --- a/src/main/java/xyz/wbsite/module/conf/ent/MessageType.java +++ /dev/null @@ -1,6 +0,0 @@ -package xyz.wbsite.module.conf.ent; - -public enum MessageType { - - NGINX_STATE, -} \ No newline at end of file diff --git a/src/main/java/xyz/wbsite/module/conf/ent/State.java b/src/main/java/xyz/wbsite/module/conf/ent/State.java deleted file mode 100644 index a9b9832..0000000 --- a/src/main/java/xyz/wbsite/module/conf/ent/State.java +++ /dev/null @@ -1,18 +0,0 @@ -package xyz.wbsite.module.conf.ent; - -/** - * 运行状态 - */ -public class State { - - // 0 为关闭,1为运行 - private boolean run; - - public boolean isRun() { - return run; - } - - public void setRun(boolean run) { - this.run = run; - } -} diff --git a/src/main/java/xyz/wbsite/module/conf/req/NginxStartRequest.java b/src/main/java/xyz/wbsite/module/conf/req/NginxStartRequest.java deleted file mode 100644 index 8cb572b..0000000 --- a/src/main/java/xyz/wbsite/module/conf/req/NginxStartRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package xyz.wbsite.module.conf.req; - -import xyz.wbsite.frame.base.BaseRequest; - -public class NginxStartRequest extends BaseRequest { - -} diff --git a/src/main/java/xyz/wbsite/module/conf/req/NginxStopRequest.java b/src/main/java/xyz/wbsite/module/conf/req/NginxStopRequest.java deleted file mode 100644 index 68342fb..0000000 --- a/src/main/java/xyz/wbsite/module/conf/req/NginxStopRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package xyz.wbsite.module.conf.req; - -import xyz.wbsite.frame.base.BaseRequest; - -public class NginxStopRequest extends BaseRequest { - -} diff --git a/src/main/java/xyz/wbsite/module/conf/rsp/NginxStartResponse.java b/src/main/java/xyz/wbsite/module/conf/rsp/NginxStartResponse.java deleted file mode 100644 index 6aee6fd..0000000 --- a/src/main/java/xyz/wbsite/module/conf/rsp/NginxStartResponse.java +++ /dev/null @@ -1,7 +0,0 @@ -package xyz.wbsite.module.conf.rsp; - -import xyz.wbsite.frame.base.BaseResponse; - -public class NginxStartResponse extends BaseResponse { - -} diff --git a/src/main/java/xyz/wbsite/module/system/req/UserLoginRequest.java b/src/main/java/xyz/wbsite/module/system/req/UserLoginRequest.java deleted file mode 100644 index 728f851..0000000 --- a/src/main/java/xyz/wbsite/module/system/req/UserLoginRequest.java +++ /dev/null @@ -1,37 +0,0 @@ -package xyz.wbsite.module.system.req; - -import xyz.wbsite.frame.base.BaseRequest; - -import javax.validation.constraints.NotBlank; - -/** - * UserLoginRequest - 登录 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class UserLoginRequest extends BaseRequest { - - @NotBlank(message = "[username]用户名不能为空") - private String username; - - @NotBlank(message = "[password]用户密码不能为空") - private String password; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } -} diff --git a/src/main/java/xyz/wbsite/module/system/req/UserLogoutRequest.java b/src/main/java/xyz/wbsite/module/system/req/UserLogoutRequest.java deleted file mode 100644 index a3e9853..0000000 --- a/src/main/java/xyz/wbsite/module/system/req/UserLogoutRequest.java +++ /dev/null @@ -1,14 +0,0 @@ -package xyz.wbsite.module.system.req; - -import xyz.wbsite.frame.base.BaseRequest; - -/** - * UserLogoutRequest - 用户登出 - * - * @author wangbing - * @version 0.0.1 - * @since 2017-01-01 - */ -public class UserLogoutRequest extends BaseRequest { - -} diff --git a/src/main/java/xyz/wbsite/task/StatusTask.java b/src/main/java/xyz/wbsite/task/StatusTask.java deleted file mode 100644 index 64dd1b7..0000000 --- a/src/main/java/xyz/wbsite/task/StatusTask.java +++ /dev/null @@ -1,40 +0,0 @@ -package xyz.wbsite.task; - -import xyz.wbsite.action.GlobalController; -import xyz.wbsite.frame.auth.LocalData; -import xyz.wbsite.frame.schedule.RunDelayRepeatTask; -import xyz.wbsite.module.conf.ent.Message; -import xyz.wbsite.module.conf.ent.MessageType; -import xyz.wbsite.module.conf.ent.NginxCtrl; -import xyz.wbsite.module.conf.ent.State; - -import java.time.Duration; - -public class StatusTask extends RunDelayRepeatTask { - - @Override - public String taskId() { - return "task1"; - } - - @Override - public Duration interval() { - return Duration.ofSeconds(3); - } - - @Override - public void run() { - NginxCtrl nginxCtrl = LocalData.getBean(NginxCtrl.class); - GlobalController globalController = LocalData.getBean(GlobalController.class); - if (nginxCtrl == null || globalController == null) { - return; - } - - Message message = new Message(); - message.setType(MessageType.NGINX_STATE); - State state = new State(); - state.setRun(nginxCtrl.isRunning()); - message.setObject(state); - globalController.pushAll(message); - } -} diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties new file mode 100644 index 0000000..17d030a --- /dev/null +++ b/src/main/resources/application-dev.properties @@ -0,0 +1,72 @@ +# 开发环境 +server.port=8080 +server.servlet.context-path= +spring.mvc.static-path-pattern=/static/** +spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:/file-upload +spring.application.name=nginx-admin +spring.main.banner-mode=CONSOLE +spring.devtools.restart.enabled=true +# 编码配置 +spring.http.encoding.force=true +spring.http.encoding.charset=UTF-8 +spring.http.encoding.enabled=true +server.tomcat.uri-encoding=UTF-8 +# jackson 相关配置 +spring.jackson.date-format=yyyy-MM-dd HH:mm:ss +spring.jackson.time-zone=GMT+8 +spring.jackson.default-property-inclusion=non_null +spring.jackson.mapper.sort-properties-alphabetically=true +spring.jackson.deserialization.fail-on-unknown-properties=false +# 文件上传配置 +spring.servlet.multipart.resolveLazily=false +spring.servlet.multipart.max-file-size=100MB +spring.servlet.multipart.max-request-size=100MB +server.tomcat.max-http-post-size=-1 +# 日志 +logging.config=classpath:logback-spring-dev.xml +# SQLite spring.datasource.url=jdbc:sqlite::resource:example.db3 +spring.datasource.driver-class-name=org.sqlite.JDBC +spring.datasource.url=jdbc:sqlite:nginx-admin.db3?date_string_format=yyyy-MM-dd HH:mm:ss +spring.datasource.username=test +spring.datasource.password=123456 +# mybatis +mybatis.mapper-locations=classpath:**/mpr/*.xml +mybatis.configuration.map-underscore-to-camel-case=true +# pagehelper +pagehelper.autoRuntimeDialect=true +pagehelper.reasonable=false +pagehelper.supportMethodsArguments=true +pagehelper.params=count=countSql +# freemarker +spring.freemarker.enabled=true +spring.freemarker.allow-request-override=false +spring.freemarker.cache=true +spring.freemarker.check-template-location=true +spring.freemarker.charset=UTF-8 +spring.freemarker.content-type=text/html +spring.freemarker.expose-request-attributes=false +spring.freemarker.expose-session-attributes=false +spring.freemarker.expose-spring-macro-helpers=false +spring.freemarker.settings.template_update_delay=1 +spring.freemarker.settings.locale=zh_CN +spring.freemarker.settings.datetime_format=yyyy-MM-dd HH:mm:ss +spring.freemarker.settings.date_format=yyyy-MM-dd +spring.freemarker.settings.number_format=#.## +spring.freemarker.settings.classic_compatible=true +spring.freemarker.settings.whitespace_stripping=true +spring.freemarker.settings.url_escaping_charset=utf-8 +# 开启Gzip压缩 +server.compression.enabled=true + +# 自定义配置 +# 根路径默认页,'/'跳转至该页 +web.url.index=/index.htm +# 登录页 +web.url.login=/login.htm +# 拦截验证 +web.url.auth.included=/,/**/*.htm,/ajax/** +# 直接放行 +web.url.auth.excluded=/login.htm,/ajax/wframe/** +# 超级管理员 +web.url.auth.admin=admin +web.url.auth.pwd=17fac3376f76d65943d1d26d1f7cb1e5 diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 264b00e..40f9624 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,74 +1,3 @@ -# 开发环境 -server.port=8888 -server.servlet.context-path= -spring.mvc.static-path-pattern=/static/** -spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:/file-upload -spring.application.name=nginx-admin -spring.main.banner-mode=OFF -spring.devtools.restart.enabled=true -# 编码配置 -spring.http.encoding.force=true -spring.http.encoding.charset=UTF-8 -spring.http.encoding.enabled=true -server.tomcat.uri-encoding=UTF-8 -# 日志配置 -#logging.path=D:// -logging.levels=INFO -# SQLite spring.datasource.url=jdbc:sqlite::resource:example.db -spring.datasource.driver-class-name=org.sqlite.JDBC -spring.datasource.url=jdbc:sqlite:nginx-admin.db?date_string_format=yyyy-MM-dd HH:mm:ss -spring.datasource.username=test -spring.datasource.password=123456 -# mybatis -mybatis.mapper-locations=classpath:**/mpr/*.xml -mybatis.configuration.map-underscore-to-camel-case=true -# pagehelper -pagehelper.autoRuntimeDialect=true -pagehelper.reasonable=false -pagehelper.supportMethodsArguments=true -pagehelper.params=count=countSql -# jackson 相关配置 -spring.jackson.date-format=yyyy-MM-dd HH:mm:ss -spring.jackson.time-zone=GMT+8 -spring.jackson.default-property-inclusion=non_null -spring.jackson.mapper.sort-properties-alphabetically=true -spring.jackson.deserialization.fail-on-unknown-properties=false -# freemarker -spring.freemarker.enabled=true -spring.freemarker.allow-request-override=false -spring.freemarker.cache=true -spring.freemarker.check-template-location=true -spring.freemarker.charset=UTF-8 -spring.freemarker.content-type=text/html -spring.freemarker.expose-request-attributes=false -spring.freemarker.expose-session-attributes=false -spring.freemarker.expose-spring-macro-helpers=false -spring.freemarker.settings.template_update_delay=1 -spring.freemarker.settings.locale=zh_CN -spring.freemarker.settings.datetime_format=yyyy-MM-dd HH:mm:ss -spring.freemarker.settings.date_format=yyyy-MM-dd -spring.freemarker.settings.number_format=#.## -spring.freemarker.settings.classic_compatible=true -spring.freemarker.settings.whitespace_stripping=true -spring.freemarker.settings.url_escaping_charset=utf-8 -# 文件上传配置 -spring.servlet.multipart.resolveLazily=false -spring.servlet.multipart.max-file-size=100MB -spring.servlet.multipart.max-request-size=100MB -server.tomcat.max-http-post-size=-1 - -# 自定义配置 -# 根路径默认页,'/'跳转至该页 -web.home.page=/index.htm -# 登录页 -web.login.page=/login.htm -# 拦截验证 -web.url.auth.included=/,/**/*.htm,/ajax/**,/api/** -# 直接放行 -web.url.auth.excluded=/login.htm,/ajax/system/User/login,/ajax/system/User/logout -# 超级管理员 -web.url.auth.admin=admin -web.url.auth.pwd=17fac3376f76d65943d1d26d1f7cb1e5 - -nginx-path= -mapping.default.port=80 \ No newline at end of file +spring.profiles.active=dev +# 默认禁用所有端点 +management.endpoints.enabled-by-default=false \ No newline at end of file diff --git a/src/main/resources/dbtool/nginx-admin.xml b/src/main/resources/dbtool/nginx-admin.xml deleted file mode 100644 index 063866f..0000000 --- a/src/main/resources/dbtool/nginx-admin.xml +++ /dev/null @@ -1,35 +0,0 @@ - - -nginx-admin -xyz.wbsite -wangbing -false -false - - -配置 -CONF_ -conf -true - - - - - - - - - - - - - - - - - -
-
-
-
-
diff --git a/src/main/resources/logback-spring-dev.xml b/src/main/resources/logback-spring-dev.xml new file mode 100644 index 0000000..483bef2 --- /dev/null +++ b/src/main/resources/logback-spring-dev.xml @@ -0,0 +1,19 @@ + + + + + + + DEBUG + + + %highlight(%d{yyyy-MM-dd HH:mm:ss.SSS} [%-4level] [%thread] [%logger{36}-%method] %ex %msg%n) + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/logback-spring-prod.xml b/src/main/resources/logback-spring-prod.xml new file mode 100644 index 0000000..ba00d8d --- /dev/null +++ b/src/main/resources/logback-spring-prod.xml @@ -0,0 +1,105 @@ + + + + + + + + + + DEBUG + + + %highlight(%d{yyyy-MM-dd HH:mm:ss.SSS} [%-4level] [%thread] [%logger{36}-%method] %ex %msg%n) + + + + + + ${root}/log/all/all.log + + ${root}/log/all/all-%d{yyyy-MM-dd}-%i.log + 30 + + 10MB + + + + [%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n + + + INFO + + + + + + ${root}/log/error/error.log + + ${root}/log/error/error-%d{yyyy-MM-dd}-%i.log + 30 + + 10MB + + + + [%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n + + + ERROR + ACCEPT + DENY + + + + + + ${root}/log/warn/warn.log + + ${root}/log/warn/warn-%d{yyyy-MM-dd}-%i.log + 30 + + 10MB + + + + [%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n + + + WARN + ACCEPT + DENY + + + + + + ${root}/log/info/info.log + + ${root}/log/info/info-%d{yyyy-MM-dd}-%i.log + 30 + + 10MB + + + + [%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n + + + INFO + ACCEPT + DENY + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/nginx-admin.db b/src/main/resources/nginx-admin.db deleted file mode 100644 index 3316b66903d6743b30edca60226a98581e8e8947..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI#K}*9h6bJBh6NN(AZo7uTU;_n3#H(2sx3H|OX*TJpOq?*74z+?GK=5k~{4Rb9 z54K$=-Nx#9@Gq3SG>_N3UwesvBd5`XKFnVp#}PdzRbm+Aic&&IIlJQ_y^{Gs7AJ#| zi+6=(a`J6jl^;^F7Q|XqzIG+zIRqd80SG_<0uX=z1Rwwb2owu^5aX!UXc(V%G`^cn zY}dIC2h8(?)6K^vTXCj2)vPT!&9Bg=WzzVni%y-kMOQeQdP)qK3TU4P)NwU+hEg79 zX$~9kIvp`(_n2y4oVKi9bRTZPk&?*Wu7h)^o*HyUnkz z7qZOOW$CciZy03ybU%52eV)bV`EdLe&C_|9|JLDIewLo+t>pKr7XM>dg#ZK~009U< z00Izz00bZa0SG`~zXi->`^)oxX}>$c?jZmH2tWV=5P$##AOHafKmY;|*d_1_=X{lv diff --git a/src/main/resources/pt/ADMIN_table/SQLite_ALL_TABLE.sql b/src/main/resources/pt/ADMIN_table/SQLite_ALL_TABLE.sql deleted file mode 100644 index 1ed6ec3..0000000 --- a/src/main/resources/pt/ADMIN_table/SQLite_ALL_TABLE.sql +++ /dev/null @@ -1,24 +0,0 @@ --- ---------------------------- --- Table structure for NEW_TABLE - 默认对象 --- Target : SQLite --- Author : wangbing --- Date: : 2021-02-04 --- ---------------------------- -CREATE TABLE IF NOT EXISTS CONF_NEW_TABLE ( - "ID" BIGINT PRIMARY KEY NOT NULL, - "CONF_TITLE" VARCHAR(50) NOT NULL, - "CONF_NOTE" VARCHAR(50), - "CONF_PORT" VARCHAR(50) NOT NULL, - "CONF_PATH" VARCHAR(50) NOT NULL, - "CONF_TYPE" VARCHAR(50) NOT NULL, - "CONF_LOCATION" VARCHAR(50), - "CONF_VALID" VARCHAR(50) NOT NULL, - "CONF_ARG" VARCHAR(50), - "ROW_VERSION" BIGINT NOT NULL, - "IS_DELETED" BOOLEAN NOT NULL, - "CREATE_BY" BIGINT NOT NULL, - "CREATE_TIME" DATETIME NOT NULL, - "LAST_UPDATE_BY" BIGINT, - "LAST_UPDATE_TIME" DATETIME -); - diff --git a/src/main/resources/pt/admina_table/SQLite_ALL_TABLE.sql b/src/main/resources/pt/admina_table/SQLite_ALL_TABLE.sql new file mode 100644 index 0000000..1883232 --- /dev/null +++ b/src/main/resources/pt/admina_table/SQLite_ALL_TABLE.sql @@ -0,0 +1,87 @@ +-- ---------------------------- +-- Table structure for SERVICES - 虚拟主机 +-- Target : SQLite +-- Author : wangbing +-- Date: : 2021-02-07 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS NA_SERVICES ( + "ID" BIGINT PRIMARY KEY NOT NULL, + "TITLE" VARCHAR(50) NOT NULL, + "DOMAIN" VARCHAR(50) NOT NULL, + "TYPE" VARCHAR(20) NOT NULL, + "PORT" MEDIUMINT NOT NULL, + "VALID" BOOLEAN, + "FILTER" BOOLEAN NOT NULL, + "FILTER_CONF" VARCHAR(500), + "ROW_VERSION" BIGINT NOT NULL, + "IS_DELETED" BOOLEAN NOT NULL, + "CREATE_BY" BIGINT NOT NULL, + "CREATE_TIME" DATETIME NOT NULL, + "LAST_UPDATE_BY" BIGINT, + "LAST_UPDATE_TIME" DATETIME +); + +-- ---------------------------- +-- Table structure for LOCATIONS - 路径配置 +-- Target : SQLite +-- Author : wangbing +-- Date: : 2021-02-07 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS NA_LOCATIONS ( + "ID" BIGINT PRIMARY KEY NOT NULL, + "SERVICE_ID" BIGINT NOT NULL, + "LOCAL_TITLE" VARCHAR(50) NOT NULL, + "LOCAL_NOTE" VARCHAR(250), + "LOCAL_PATH" VARCHAR(50) NOT NULL, + "LOCAL_VALID" BOOLEAN NOT NULL, + "FILTER" BOOLEAN NOT NULL, + "FILTER_CONF" VARCHAR(500), + "ROW_VERSION" BIGINT NOT NULL, + "IS_DELETED" BOOLEAN NOT NULL, + "CREATE_BY" BIGINT NOT NULL, + "CREATE_TIME" DATETIME NOT NULL, + "LAST_UPDATE_BY" BIGINT, + "LAST_UPDATE_TIME" DATETIME +); + +-- ---------------------------- +-- Table structure for CONFIG - 配置预设 +-- Target : SQLite +-- Author : wangbing +-- Date: : 2021-02-07 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS NA_CONFIG ( + "ID" BIGINT PRIMARY KEY NOT NULL, + "CONF_NAME" VARCHAR(50) NOT NULL, + "CONF_TYPE" VARCHAR(50) NOT NULL, + "CONF_VALUE" VARCHAR(250), + "CONF_NOTE" VARCHAR(250), + "ROW_VERSION" BIGINT NOT NULL, + "IS_DELETED" BOOLEAN NOT NULL, + "CREATE_BY" BIGINT NOT NULL, + "CREATE_TIME" DATETIME NOT NULL, + "LAST_UPDATE_BY" BIGINT, + "LAST_UPDATE_TIME" DATETIME +); + +-- ---------------------------- +-- Table structure for CONFIG_DATA - 配置数据 +-- Target : SQLite +-- Author : wangbing +-- Date: : 2021-02-07 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS NA_CONFIG_DATA ( + "ID" BIGINT PRIMARY KEY NOT NULL, + "TARGET_ID" BIGINT NOT NULL, + "CONF_NAME" VARCHAR(50) NOT NULL, + "CONF_TYPE" VARCHAR(50) NOT NULL, + "CONF_VALUE" VARCHAR(250) NOT NULL, + "CONF_NOTE" VARCHAR(250), + "ROW_VERSION" BIGINT NOT NULL, + "IS_DELETED" BOOLEAN NOT NULL, + "CREATE_BY" BIGINT NOT NULL, + "CREATE_TIME" DATETIME NOT NULL, + "LAST_UPDATE_BY" BIGINT, + "LAST_UPDATE_TIME" DATETIME +); + diff --git a/src/main/resources/dbtool/conf_table/SQLite_ALL_TABLE.sql b/src/main/resources/pt/admina_table/SQLite_CONFIG.sql similarity index 53% rename from src/main/resources/dbtool/conf_table/SQLite_ALL_TABLE.sql rename to src/main/resources/pt/admina_table/SQLite_CONFIG.sql index 56b8618..8e3f89b 100644 --- a/src/main/resources/dbtool/conf_table/SQLite_ALL_TABLE.sql +++ b/src/main/resources/pt/admina_table/SQLite_CONFIG.sql @@ -1,17 +1,15 @@ -- ---------------------------- --- Table structure for MAPPING - 映射 +-- Table structure for CONFIG - 配置预设 -- Target : SQLite -- Author : wangbing --- Date: : 2020-03-18 +-- Date: : 2021-02-07 -- ---------------------------- -CREATE TABLE IF NOT EXISTS CONF_MAPPING ( +CREATE TABLE IF NOT EXISTS NA_CONFIG ( "ID" BIGINT PRIMARY KEY NOT NULL, - "NAME" VARCHAR(50) NOT NULL, - "PORT" VARCHAR(50) NOT NULL, - "PATH" VARCHAR(50) NOT NULL, - "TYPE" VARCHAR(50) NOT NULL, - "LOCATION" VARCHAR(50) NOT NULL, - "NOTE" VARCHAR(50), + "CONF_NAME" VARCHAR(50) NOT NULL, + "CONF_TYPE" VARCHAR(50) NOT NULL, + "CONF_VALUE" VARCHAR(250), + "CONF_NOTE" VARCHAR(250), "ROW_VERSION" BIGINT NOT NULL, "IS_DELETED" BOOLEAN NOT NULL, "CREATE_BY" BIGINT NOT NULL, diff --git a/src/main/resources/pt/admin_table/SQLite_CONFIG_DATA.sql b/src/main/resources/pt/admina_table/SQLite_CONFIG_DATA.sql similarity index 100% rename from src/main/resources/pt/admin_table/SQLite_CONFIG_DATA.sql rename to src/main/resources/pt/admina_table/SQLite_CONFIG_DATA.sql diff --git a/src/main/resources/pt/admina_table/SQLite_LOCATIONS.sql b/src/main/resources/pt/admina_table/SQLite_LOCATIONS.sql new file mode 100644 index 0000000..77e10d0 --- /dev/null +++ b/src/main/resources/pt/admina_table/SQLite_LOCATIONS.sql @@ -0,0 +1,22 @@ +-- ---------------------------- +-- Table structure for LOCATIONS - 路径配置 +-- Target : SQLite +-- Author : wangbing +-- Date: : 2021-02-07 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS NA_LOCATIONS ( + "ID" BIGINT PRIMARY KEY NOT NULL, + "SERVICE_ID" BIGINT NOT NULL, + "LOCAL_TITLE" VARCHAR(50) NOT NULL, + "LOCAL_NOTE" VARCHAR(250), + "LOCAL_PATH" VARCHAR(50) NOT NULL, + "LOCAL_VALID" BOOLEAN NOT NULL, + "FILTER" BOOLEAN NOT NULL, + "FILTER_CONF" VARCHAR(500), + "ROW_VERSION" BIGINT NOT NULL, + "IS_DELETED" BOOLEAN NOT NULL, + "CREATE_BY" BIGINT NOT NULL, + "CREATE_TIME" DATETIME NOT NULL, + "LAST_UPDATE_BY" BIGINT, + "LAST_UPDATE_TIME" DATETIME +); diff --git a/src/main/resources/pt/admin_table/SQLite_SERVICES.sql b/src/main/resources/pt/admina_table/SQLite_SERVICES.sql similarity index 100% rename from src/main/resources/pt/admin_table/SQLite_SERVICES.sql rename to src/main/resources/pt/admina_table/SQLite_SERVICES.sql diff --git a/src/main/resources/pt/nginx-admin.xml b/src/main/resources/pt/nginx-admin.xml index 3b6afed..13501e7 100644 --- a/src/main/resources/pt/nginx-admin.xml +++ b/src/main/resources/pt/nginx-admin.xml @@ -1,17 +1,73 @@ - - + +
- - - - - - - - + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + diff --git a/src/main/resources/start.bat b/src/main/resources/start.bat deleted file mode 100644 index 9838176..0000000 --- a/src/main/resources/start.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -cd %cd% -start java -Xmx256M -Dfile.encoding=UTF-8 -jar nginx-admin-0.0.1-SNAPSHOT.jar \ No newline at end of file diff --git a/src/main/resources/static/dist/echarts/echarts.min.js b/src/main/resources/static/dist/echarts/echarts.min.js new file mode 100644 index 0000000..4b25b97 --- /dev/null +++ b/src/main/resources/static/dist/echarts/echarts.min.js @@ -0,0 +1,22 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + + +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.echarts={})}(this,function(t){"use strict";var e=2311,n=function(){return e++},v="object"==typeof wx&&"function"==typeof wx.getSystemInfoSync?{browser:{},os:{},node:!1,wxa:!0,canvasSupported:!0,svgSupported:!1,touchEventsSupported:!0,domSupported:!1}:"undefined"==typeof document&&"undefined"!=typeof self?{browser:{},os:{},node:!1,worker:!0,canvasSupported:!0,domSupported:!1}:"undefined"==typeof navigator?{browser:{},os:{},node:!0,worker:!1,canvasSupported:!0,svgSupported:!0,domSupported:!1}:function(t){var e={},i=t.match(/Firefox\/([\d.]+)/),n=t.match(/MSIE\s([\d.]+)/)||t.match(/Trident\/.+?rv:(([\d.]+))/),o=t.match(/Edge\/([\d.]+)/),a=/micromessenger/i.test(t);i&&(e.firefox=!0,e.version=i[1]);n&&(e.ie=!0,e.version=n[1]);o&&(e.edge=!0,e.version=o[1]);a&&(e.weChat=!0);return{browser:e,os:{},node:!1,canvasSupported:!!document.createElement("canvas").getContext,svgSupported:"undefined"!=typeof SVGRect,touchEventsSupported:"ontouchstart"in window&&!e.ie&&!e.edge,pointerEventsSupported:"onpointerdown"in window&&(e.edge||e.ie&&11<=e.version),domSupported:"undefined"!=typeof document}}(navigator.userAgent);var s={"[object Function]":1,"[object RegExp]":1,"[object Date]":1,"[object Error]":1,"[object CanvasGradient]":1,"[object CanvasPattern]":1,"[object Image]":1,"[object Canvas]":1},l={"[object Int8Array]":1,"[object Uint8Array]":1,"[object Uint8ClampedArray]":1,"[object Int16Array]":1,"[object Uint16Array]":1,"[object Int32Array]":1,"[object Uint32Array]":1,"[object Float32Array]":1,"[object Float64Array]":1},u=Object.prototype.toString,i=Array.prototype,r=i.forEach,h=i.filter,o=i.slice,c=i.map,d=i.reduce,a={};function f(t,e){"createCanvas"===t&&(g=null),a[t]=e}function k(t){if(null==t||"object"!=typeof t)return t;var e=t,i=u.call(t);if("[object Array]"===i){if(!$(t)){e=[];for(var n=0,o=t.length;n>1)%2;s.cssText=["position: absolute","visibility: hidden","padding: 0","margin: 0","border-width: 0","user-select: none","width:0","height:0",n[l]+":0",o[u]+":0",n[1-l]+":auto",o[1-u]+":auto",""].join("!important;"),t.appendChild(r),i.push(r)}return i}(e,a),a,o);if(r)return r(t,i,n),!0}return!1}function zt(t){return"CANVAS"===t.nodeName.toUpperCase()}var Bt="undefined"!=typeof window&&!!window.addEventListener,Vt=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Gt=[];function Ft(t,e,i,n){return i=i||{},n||!v.canvasSupported?Wt(t,e,i):v.browser.firefox&&null!=e.layerX&&e.layerX!==e.offsetX?(i.zrX=e.layerX,i.zrY=e.layerY):null!=e.offsetX?(i.zrX=e.offsetX,i.zrY=e.offsetY):Wt(t,e,i),i}function Wt(t,e,i){if(v.domSupported&&t.getBoundingClientRect){var n=e.clientX,o=e.clientY;if(zt(t)){var a=t.getBoundingClientRect();return i.zrX=n-a.left,void(i.zrY=o-a.top)}if(Et(Gt,t,n,o))return i.zrX=Gt[0],void(i.zrY=Gt[1])}i.zrX=i.zrY=0}function Ht(t){return t||window.event}function Zt(t,e,i){if(null!=(e=Ht(e)).zrX)return e;var n=e.type;if(n&&0<=n.indexOf("touch")){var o="touchend"!==n?e.targetTouches[0]:e.changedTouches[0];o&&Ft(t,o,e,i)}else Ft(t,e,e,i),e.zrDelta=e.wheelDelta?e.wheelDelta/120:-(e.detail||0)/3;var a=e.button;return null==e.which&&void 0!==a&&Vt.test(e.type)&&(e.which=1&a?1:2&a?3:4&a?2:0),e}function Ut(t,e,i,n){Bt?t.addEventListener(e,i,n):t.attachEvent("on"+e,i)}var Xt=Bt?function(t){t.preventDefault(),t.stopPropagation(),t.cancelBubble=!0}:function(t){t.returnValue=!1,t.cancelBubble=!0};function Yt(t){return 2===t.which||3===t.which}function jt(){this._track=[]}function qt(t){var e=t[1][0]-t[0][0],i=t[1][1]-t[0][1];return Math.sqrt(e*e+i*i)}jt.prototype={constructor:jt,recognize:function(t,e,i){return this._doTrack(t,e,i),this._recognize(t)},clear:function(){return this._track.length=0,this},_doTrack:function(t,e,i){var n=t.touches;if(n){for(var o={points:[],touches:[],target:e,event:t},a=0,r=n.length;an.getWidth()||i<0||i>n.getHeight()}te.prototype={constructor:te,setHandlerProxy:function(e){this.proxy&&this.proxy.dispose(),e&&(R(ee,function(t){e.on&&e.on(t,this[t],this)},this),e.handler=this),this.proxy=e},mousemove:function(t){var e=t.zrX,i=t.zrY,n=ne(this,e,i),o=this._hovered,a=o.target;a&&!a.__zr&&(a=(o=this.findHover(o.x,o.y)).target);var r=this._hovered=n?{x:e,y:i}:this.findHover(e,i),s=r.target,l=this.proxy;l.setCursor&&l.setCursor(s?s.cursor:"default"),a&&s!==a&&this.dispatchToElement(o,"mouseout",t),this.dispatchToElement(r,"mousemove",t),s&&s!==a&&this.dispatchToElement(r,"mouseover",t)},mouseout:function(t){var e=t.zrEventControl,i=t.zrIsToLocalDOM;"only_globalout"!==e&&this.dispatchToElement(this._hovered,"mouseout",t),"no_globalout"!==e&&(i||this.trigger("globalout",{type:"globalout",event:t}))},resize:function(t){this._hovered={}},dispatch:function(t,e){var i=this[t];i&&i.call(this,e)},dispose:function(){this.proxy.dispose(),this.storage=this.proxy=this.painter=null},setCursorStyle:function(t){var e=this.proxy;e.setCursor&&e.setCursor(t)},dispatchToElement:function(t,e,i){var n=(t=t||{}).target;if(!n||!n.silent){for(var o="on"+e,a=function(t,e,i){return{type:t,event:i,target:e.target,topTarget:e.topTarget,cancelBubble:!1,offsetX:i.zrX,offsetY:i.zrY,gestureEvent:i.gestureEvent,pinchX:i.pinchX,pinchY:i.pinchY,pinchScale:i.pinchScale,wheelDelta:i.zrDelta,zrByTouch:i.zrByTouch,which:i.which,stop:Jt}}(e,t,i);n&&(n[o]&&(a.cancelBubble=n[o].call(n,a)),n.trigger(e,a),n=n.parent,!a.cancelBubble););a.cancelBubble||(this.trigger(e,a),this.painter&&this.painter.eachOtherLayer(function(t){"function"==typeof t[o]&&t[o].call(t,a),t.trigger&&t.trigger(e,a)}))}},findHover:function(t,e,i){for(var n=this.storage.getDisplayList(),o={x:t,y:e},a=n.length-1;0<=a;a--){var r;if(n[a]!==i&&!n[a].ignore&&(r=ie(n[a],t,e))&&(o.topTarget||(o.topTarget=n[a]),r!==$t)){o.target=n[a];break}}return o},processGesture:function(t,e){this._gestureMgr||(this._gestureMgr=new jt);var i=this._gestureMgr;"start"===e&&i.clear();var n=i.recognize(t,this.findHover(t.zrX,t.zrY,null).target,this.proxy.dom);if("end"===e&&i.clear(),n){var o=n.type;t.gestureEvent=o,this.dispatchToElement({target:n.target},o,n.event)}}},R(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(r){te.prototype[r]=function(t){var e,i,n=t.zrX,o=t.zrY,a=ne(this,n,o);if("mouseup"===r&&a||(i=(e=this.findHover(n,o)).target),"mousedown"===r)this._downEl=i,this._downPoint=[t.zrX,t.zrY],this._upEl=i;else if("mouseup"===r)this._upEl=i;else if("click"===r){if(this._downEl!==this._upEl||!this._downPoint||4=this._maxSize&&0>4|(3840&n)>>8,240&n|(240&n)>>4,15&n|(15&n)<<4,1),Ge(t,e),e):void Ee(e,0,0,0,1):7===o.length?0<=(n=parseInt(o.substr(1),16))&&n<=16777215?(Ee(e,(16711680&n)>>16,(65280&n)>>8,255&n,1),Ge(t,e),e):void Ee(e,0,0,0,1):void 0;var a=o.indexOf("("),r=o.indexOf(")");if(-1!==a&&r+1===o.length){var s=o.substr(0,a),l=o.substr(a+1,r-(a+1)).split(","),u=1;switch(s){case"rgba":if(4!==l.length)return void Ee(e,0,0,0,1);u=Ne(l.pop());case"rgb":return 3!==l.length?void Ee(e,0,0,0,1):(Ee(e,Pe(l[0]),Pe(l[1]),Pe(l[2]),u),Ge(t,e),e);case"hsla":return 4!==l.length?void Ee(e,0,0,0,1):(l[3]=Ne(l[3]),We(l,e),Ge(t,e),e);case"hsl":return 3!==l.length?void Ee(e,0,0,0,1):(We(l,e),Ge(t,e),e);default:return}}Ee(e,0,0,0,1)}}function We(t,e){var i=(parseFloat(t[0])%360+360)%360/360,n=Ne(t[1]),o=Ne(t[2]),a=o<=.5?o*(n+1):o+n-o*n,r=2*o-a;return Ee(e=e||[],Le(255*Oe(r,a,i+1/3)),Le(255*Oe(r,a,i)),Le(255*Oe(r,a,i-1/3)),1),4===t.length&&(e[3]=t[3]),e}function He(t,e){var i=Fe(t);if(i){for(var n=0;n<3;n++)i[n]=e<0?i[n]*(1-e)|0:(255-i[n])*e+i[n]|0,255e);i++);i=Math.min(i-1,u-2)}C=e;var n=g[(D=i)+1]-g[i];if(0!=n)if(S=(e-g[i])/n,l)if(I=m[i],M=m[0===i?i:i-1],T=m[u-2=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i.height},clone:function(){return new Di(this.x,this.y,this.width,this.height)},copy:function(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height},plain:function(){return{x:this.x,y:this.y,width:this.width,height:this.height}}},Di.create=function(t){return new Di(t.x,t.y,t.width,t.height)};var Ci=function(t){for(var e in t=t||{},_i.call(this,t),t)t.hasOwnProperty(e)&&(this[e]=t[e]);this._children=[],this.__storage=null,this.__dirty=!0};Ci.prototype={constructor:Ci,isGroup:!0,type:"group",silent:!1,children:function(){return this._children.slice()},childAt:function(t){return this._children[t]},childOfName:function(t){for(var e=this._children,i=0;i>>1])<0?l=a:s=1+a;var u=n-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;0>>1);0>>1);a(t,e[i+h])<0?l=h:r=h+1}return l}function Ei(p,g){var r,s,m=ki,l=0,v=[];function e(t){var e=r[t],i=s[t],n=r[t+1],o=s[t+1];s[t]=i+o,t===l-3&&(r[t+1]=r[t+2],s[t+1]=s[t+2]),l--;var a=Ri(p[n],p,e,i,0,g);e+=a,0!==(i-=a)&&0!==(o=Oi(p[e+i-1],p,n,o,o-1,g))&&(i<=o?function(t,e,i,n){var o=0;for(o=0;os[t+1])break;e(t)}},this.forceMergeRuns=function(){for(;1>=1;return t+e}(o);do{if((a=Pi(t,i,n,e))=e.maxIterations){t+=e.ellipsis;break}var s=0===r?bn(t,o,e.ascCharWidth,e.cnCharWidth):0f)return{lines:[],width:0,height:0};C.textWidth=pn(C.text,w);var S=x.textWidth,M=null==S||"auto"===S;if("string"==typeof S&&"%"===S.charAt(S.length-1))C.percentWidth=S,u.push(C),S=0;else{if(M){S=C.textWidth;var I=x.textBackgroundColor,T=I&&I.image;T&&sn(T=on(T))&&(S=Math.max(S,T.width*b/T.height))}var A=_?_[1]+_[3]:0;S+=A;var D=null!=d?d-v:null;null!=D&&Dn[0]){for(r=0;rt);r++);a=i[n[r]]}if(n.splice(r+1,0,t),!(i[t]=e).virtual)if(a){var l=a.dom;l.nextSibling?s.insertBefore(e.dom,l.nextSibling):s.appendChild(e.dom)}else s.firstChild?s.insertBefore(e.dom,s.firstChild):s.appendChild(e.dom)}else vi("Layer of zlevel "+t+" is not valid")},eachLayer:function(t,e){var i,n,o=this._zlevelList;for(n=0;n=a.length&&a.push({option:t})}}),a}function Zo(t){var r=Q();Ro(t,function(t,e){var i=t.exist;i&&r.set(i.id,t)}),Ro(t,function(t,e){var i=t.option;Y(!i||null==i.id||!r.get(i.id)||r.get(i.id)===t,"id duplicates: "+(i&&i.id)),i&&null!=i.id&&r.set(i.id,t),t.keyInfo||(t.keyInfo={})}),Ro(t,function(t,e){var i=t.exist,n=t.option,o=t.keyInfo;if(Eo(n)){if(o.name=null!=n.name?n.name+"":i?i.name:Bo+e,i)o.id=i.id;else if(null!=n.id)o.id=n.id+"";else for(var a=0;o.id="\0"+o.name+"\0"+a++,r.get(o.id););r.set(o.id,t)}})}function Uo(t){var e=t.name;return!(!e||!e.indexOf(Bo))}function Xo(t){return Eo(t)&&t.id&&0===(t.id+"").indexOf("\0_ec_\0")}function Yo(e,t){return null!=t.dataIndexInside?t.dataIndexInside:null!=t.dataIndex?L(t.dataIndex)?O(t.dataIndex,function(t){return e.indexOfRawIndex(t)}):e.indexOfRawIndex(t.dataIndex):null!=t.name?L(t.name)?O(t.name,function(t){return e.indexOfName(t)}):e.indexOfName(t.name):void 0}function jo(){var e="__\0ec_inner_"+qo+++"_"+Math.random().toFixed(5);return function(t){return t[e]||(t[e]={})}}var qo=0;function Ko(s,l,u){if(E(l)){var t={};t[l+"Index"]=0,l=t}var e=u&&u.defaultMainType;!e||$o(l,e+"Index")||$o(l,e+"Id")||$o(l,e+"Name")||(l[e+"Index"]=0);var h={};return Ro(l,function(t,e){t=l[e];if("dataIndex"!==e&&"dataIndexInside"!==e){var i=e.match(/^(\w+)(Index|Id|Name)$/)||[],n=i[1],o=(i[2]||"").toLowerCase();if(!(!n||!o||null==t||"index"===o&&"none"===t||u&&u.includeMainTypes&&_(u.includeMainTypes,n)<0)){var a={mainType:n};"index"===o&&"all"===t||(a[o]=t);var r=s.queryComponents(a);h[n+"Models"]=r,h[n+"Model"]=r[0]}}else h[e]=t}),h}function $o(t,e){return t&&t.hasOwnProperty(e)}function Jo(t,e,i){t.setAttribute?t.setAttribute(e,i):t[e]=i}function Qo(t){return"auto"===t?v.domSupported?"html":"richText":t||"html"}function ta(t,i){var n=Q(),o=[];return R(t,function(t){var e=i(t);(n.get(e)||(o.push(e),n.set(e,[]))).push(t)}),{keys:o,buckets:n}}var ea=".",ia="___EC__COMPONENT__CONTAINER___";function na(t){var e={main:"",sub:""};return t&&(t=t.split(ea),e.main=t[0]||"",e.sub=t[1]||""),e}function oa(t){(t.$constructor=t).extend=function(t){function e(){t.$constructor?t.$constructor.apply(this,arguments):i.apply(this,arguments)}var i=this;return P(e.prototype,t),e.extend=this.extend,e.superCall=sa,e.superApply=la,w(e,this),e.superClass=i,e}}var aa=0;function ra(t){var e=["__\0is_clz",aa++,Math.random().toFixed(3)].join("_");t.prototype[e]=!0,t.isInstance=function(t){return!(!t||!t[e])}}function sa(t,e){var i=U(arguments,2);return this.superClass.prototype[e].apply(t,i)}function la(t,e,i){return this.superClass.prototype[e].apply(t,i)}function ua(i,t){t=t||{};var o={};if(i.registerClass=function(t,e){if(e)if(function(t){Y(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(t),'componentType "'+t+'" illegal')}(e),(e=na(e)).sub){if(e.sub!==ia){(function(t){var e=o[t.main];e&&e[ia]||((e=o[t.main]={})[ia]=!0);return e})(e)[e.sub]=t}}else o[e.main]=t;return t},i.getClass=function(t,e,i){var n=o[t];if(n&&n[ia]&&(n=e?n[e]:null),i&&!n)throw new Error(e?"Component "+t+"."+(e||"")+" not exists. Load it first.":t+".type should be specified.");return n},i.getClassesByMainType=function(t){t=na(t);var i=[],e=o[t.main];return e&&e[ia]?R(e,function(t,e){e!==ia&&i.push(t)}):i.push(e),i},i.hasClass=function(t){return t=na(t),!!o[t.main]},i.getAllClassMainTypes=function(){var i=[];return R(o,function(t,e){i.push(e)}),i},i.hasSubTypes=function(t){t=na(t);var e=o[t.main];return e&&e[ia]},i.parseClassType=na,t.registerWhenExtend){var n=i.extend;n&&(i.extend=function(t){var e=n.call(this,t);return i.registerClass(e,t.type)})}return i}function ha(s){for(var t=0;tthis._ux||or(e-this._yi)>this._uy||this._len<5;return this.addData(ja.L,t,e),this._ctx&&i&&(this._needsDash()?this._dashedLineTo(t,e):this._ctx.lineTo(t,e)),i&&(this._xi=t,this._yi=e),this},bezierCurveTo:function(t,e,i,n,o,a){return this.addData(ja.C,t,e,i,n,o,a),this._ctx&&(this._needsDash()?this._dashedBezierTo(t,e,i,n,o,a):this._ctx.bezierCurveTo(t,e,i,n,o,a)),this._xi=o,this._yi=a,this},quadraticCurveTo:function(t,e,i,n){return this.addData(ja.Q,t,e,i,n),this._ctx&&(this._needsDash()?this._dashedQuadraticTo(t,e,i,n):this._ctx.quadraticCurveTo(t,e,i,n)),this._xi=i,this._yi=n,this},arc:function(t,e,i,n,o,a){return this.addData(ja.A,t,e,i,i,n,o-n,0,a?0:1),this._ctx&&this._ctx.arc(t,e,i,n,o,a),this._xi=er(o)*i+t,this._yi=ir(o)*i+e,this},arcTo:function(t,e,i,n,o){return this._ctx&&this._ctx.arcTo(t,e,i,n,o),this},rect:function(t,e,i,n){return this._ctx&&this._ctx.rect(t,e,i,n),this.addData(ja.R,t,e,i,n),this},closePath:function(){this.addData(ja.Z);var t=this._ctx,e=this._x0,i=this._y0;return t&&(this._needsDash()&&this._dashedLineTo(e,i),t.closePath()),this._xi=e,this._yi=i,this},fill:function(t){t&&t.fill(),this.toStatic()},stroke:function(t){t&&t.stroke(),this.toStatic()},setLineDash:function(t){if(t instanceof Array){this._lineDash=t;for(var e=this._dashIdx=0,i=0;ie.length&&(this._expandData(),e=this.data);for(var i=0;il||or(r-o)>u||c===h-1)&&(t.lineTo(a,r),n=a,o=r);break;case ja.C:t.bezierCurveTo(s[c++],s[c++],s[c++],s[c++],s[c++],s[c++]),n=s[c-2],o=s[c-1];break;case ja.Q:t.quadraticCurveTo(s[c++],s[c++],s[c++],s[c++]),n=s[c-2],o=s[c-1];break;case ja.A:var f=s[c++],p=s[c++],g=s[c++],m=s[c++],v=s[c++],y=s[c++],x=s[c++],_=s[c++],w=m=yr[n=0]+t&&r<=yr[1]+t?h:0}if(a){l=n;n=cr(o),o=cr(l)}else n=cr(n),o=cr(o);oMath.PI/2&&p<1.5*Math.PI&&(h=-h),c+=h)}}return c}function Sr(t,e,i,n,o){for(var a=0,r=0,s=0,l=0,u=0,h=0;hMath.abs(a[1])?0=e[1])return i[1]}else{if(t>=e[0])return i[0];if(t<=e[1])return i[1]}else{if(t===e[0])return i[0];if(t===e[1])return i[1]}return(t-e[0])/o*a+i[0]}function El(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return"string"==typeof t?function(t){return t.replace(/^\s+|\s+$/g,"")}(t).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t}function zl(t,e,i){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),t=(+t).toFixed(e),i?t:+t}function Bl(t){return t.sort(function(t,e){return t-e}),t}function Vl(t){if(t=+t,isNaN(t))return 0;for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i}function Gl(t){var e=t.toString(),i=e.indexOf("e");if(0h&&(h=u[d],c=d);++s[c],u[c]=0,++l}return s[e]/o}var Hl=9007199254740991;function Zl(t){var e=2*Math.PI;return(t%e+e)%e}function Ul(t){return-Ol"'])/g,ou={"&":"&","<":"<",">":">",'"':""","'":"'"};function au(t){return null==t?"":(t+"").replace(nu,function(t,e){return ou[e]})}function ru(t,e){return"{"+t+(null==e?"":e)+"}"}var su=["a","b","c","d","e","f","g"];function lu(t,e,i){L(e)||(e=[e]);var n=e.length;if(!n)return"";for(var o=e[0].$vars||[],a=0;a':'':{renderMode:o,content:"{marker"+a+"|} ",style:{color:i}}:""}function cu(t,e){return"0000".substr(0,e-(t+="").length)+t}function du(t,e,i){"week"!==t&&"month"!==t&&"quarter"!==t&&"half-year"!==t&&"year"!==t||(t="MM-dd\nyyyy");var n=Yl(e),o=i?"UTC":"",a=n["get"+o+"FullYear"](),r=n["get"+o+"Month"]()+1,s=n["get"+o+"Date"](),l=n["get"+o+"Hours"](),u=n["get"+o+"Minutes"](),h=n["get"+o+"Seconds"](),c=n["get"+o+"Milliseconds"]();return t=t.replace("MM",cu(r,2)).replace("M",r).replace("yyyy",a).replace("yy",a%100).replace("dd",cu(s,2)).replace("d",s).replace("hh",cu(l,2)).replace("h",l).replace("mm",cu(u,2)).replace("m",u).replace("ss",cu(h,2)).replace("s",h).replace("SSS",cu(c,3))}function fu(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t}var pu=xn;function gu(t,e){if("_blank"===e||"blank"===e){var i=window.open();i.opener=null,i.location=t}else window.open(t,e)}var mu=(Object.freeze||Object)({addCommas:tu,toCamelCase:eu,normalizeCssArray:iu,encodeHTML:au,formatTpl:lu,formatTplSimple:uu,getTooltipMarker:hu,formatTime:du,capitalFirst:fu,truncateText:pu,getTextBoundingRect:function(t){return gn(t.text,t.font,t.textAlign,t.textVerticalAlign,t.textPadding,t.textLineHeight,t.rich,t.truncate)},getTextRect:function(t,e,i,n,o,a,r,s){return gn(t,e,i,n,o,s,a,r)},windowOpen:gu}),vu=R,yu=["left","right","top","bottom","width","height"],xu=[["width","left","right"],["height","top","bottom"]];function _u(h,c,d,f,p){var g=0,m=0;null==f&&(f=1/0),null==p&&(p=1/0);var v=0;c.eachChild(function(t,e){var i,n,o=t.position,a=t.getBoundingRect(),r=c.childAt(e+1),s=r&&r.getBoundingRect();if("horizontal"===h){var l=a.width+(s?-s.x+a.x:0);v=f<(i=g+l)||t.newline?(g=0,i=l,m+=v+d,a.height):Math.max(v,a.height)}else{var u=a.height+(s?-s.y+a.y:0);v=p<(n=m+u)||t.newline?(g+=v+d,m=0,n=u,a.width):Math.max(v,a.width)}t.newline||(o[0]=g,o[1]=m,"horizontal"===h?g=i+d:m=n+d)})}var wu=_u;T(_u,"vertical"),T(_u,"horizontal");function bu(t,e,i){i=iu(i||0);var n=e.width,o=e.height,a=El(t.left,n),r=El(t.top,o),s=El(t.right,n),l=El(t.bottom,o),u=El(t.width,n),h=El(t.height,o),c=i[2]+i[0],d=i[1]+i[3],f=t.aspect;switch(isNaN(u)&&(u=n-s-d-a),isNaN(h)&&(h=o-l-c-r),null!=f&&(isNaN(u)&&isNaN(h)&&(n/oe)return t[n];return t[i-1]}(s,i):r;if((l=l||r)&&l.length){var u=l[o];return t&&(a[t]=u),n.colorIdx=(o+1)%l.length,u}}},zu="original",Bu="arrayRows",Vu="objectRows",Gu="keyedColumns",Fu="unknown",Wu="typedArray",Hu="column",Zu="row";function Uu(t){this.fromDataset=t.fromDataset,this.data=t.data||(t.sourceFormat===Gu?{}:[]),this.sourceFormat=t.sourceFormat||Fu,this.seriesLayoutBy=t.seriesLayoutBy||Hu,this.dimensionsDefine=t.dimensionsDefine,this.encodeDefine=t.encodeDefine&&Q(t.encodeDefine),this.startIndex=t.startIndex||0,this.dimensionsDetectCount=t.dimensionsDetectCount}Uu.seriesDataToSource=function(t){return new Uu({data:t,sourceFormat:V(t)?Wu:zu,fromDataset:!1})},ra(Uu);var Xu={Must:1,Might:2,Not:3},Yu=jo();function ju(t){var e=t.option,i=e.data,n=V(i)?Wu:zu,o=!1,a=e.seriesLayoutBy,r=e.sourceHeader,s=e.dimensions,l=Qu(t);if(l){var u=l.option;i=u.source,n=Yu(l).sourceFormat,o=!0,a=a||u.seriesLayoutBy,null==r&&(r=u.sourceHeader),s=s||u.dimensions}var h=function(t,e,i,n,o){if(!t)return{dimensionsDefine:qu(o)};var a,r;if(e===Bu)"auto"===n||null==n?Ku(function(t){null!=t&&"-"!==t&&(E(t)?null==r&&(r=1):r=0)},i,t,10):r=n?1:0,o||1!==r||(o=[],Ku(function(t,e){o[e]=null!=t?t:""},i,t)),a=o?o.length:i===Zu?t.length:t[0]?t[0].length:null;else if(e===Vu)o=o||function(t){var e,i=0;for(;i":"\n",f="richText"===c,p={},g=0;function i(t){return{renderMode:c,content:au(tu(t)),style:p}}var m=this.getData(),a=m.mapDimension("defaultedTooltip",!0),n=a.length,r=this.getRawValue(o),s=L(r),v=m.getItemVisual(o,"color");z(v)&&v.colorStops&&(v=(v.colorStops[0]||{}).color),v=v||"transparent";var l=(1":"",n=i+u.join(i||", ");return{renderMode:c,content:n,style:p}}(r):i(n?Hh(m,o,a[0]):s?r[0]:r)).content,u=d.seriesIndex+"at"+g,y=hu({color:v,type:"item",renderMode:c,markerId:u});p[u]=v,++g;var x=m.getName(o),_=this.name;Uo(this)||(_=""),_=_?au(_)+(h?": ":e):"";var w="string"==typeof y?y:y.content;return{html:h?w+_+l:_+w+(x?au(x)+": "+l:l),markers:p}},isAnimationEnabled:function(){if(v.node)return!1;var t=this.getShallow("animation");return t&&this.getData().count()>this.getShallow("animationThreshold")&&(t=!1),t},restoreData:function(){this.dataTask.dirty()},getColorFromPalette:function(t,e,i){var n=this.ecModel,o=Eu.getColorFromPalette.call(this,t,e,i);return o=o||n.getColorFromPalette(t,e,i)},coordDimToDataDim:function(t){return this.getRawData().mapDimension(t,!0)},getProgressive:function(){return this.get("progressive")},getProgressiveThreshold:function(){return this.get("progressiveThreshold")},getAxisTooltipData:null,getTooltipPosition:null,pipeTask:null,preventIncremental:null,pipelineContext:null});function lc(t){var e=t.name;Uo(t)||(t.name=function(t){var i=t.getRawData(),e=i.mapDimension("seriesName",!0),n=[];return R(e,function(t){var e=i.getDimensionInfo(t);e.displayName&&n.push(e.displayName)}),n.join(" ")}(t)||e)}function uc(t){return t.model.getRawData().count()}function hc(t){var e=t.model;return e.setData(e.getRawData().cloneShallow()),cc}function cc(t,e){e.outputData&&t.end>e.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function dc(e,i){R(e.CHANGABLE_METHODS,function(t){e.wrapMethod(t,T(fc,i))})}function fc(t){var e=pc(t);e&&e.setOutputEnd(this.count())}function pc(t){var e=(t.ecModel||{}).scheduler,i=e&&e.getPipeline(t.uid);if(i){var n=i.currentTask;if(n){var o=n.agentStubMap;o&&(n=o.get(t.uid))}return n}}b(sc,Xh),b(sc,Eu);var gc=function(){this.group=new Ci,this.uid=Nl("viewComponent")};gc.prototype={constructor:gc,init:function(t,e){},render:function(t,e,i,n){},dispose:function(){},filterForExposedEvent:null};var mc=gc.prototype;mc.updateView=mc.updateLayout=mc.updateVisual=function(t,e,i,n){},oa(gc),ua(gc,{registerWhenExtend:!0});function vc(){var s=jo();return function(t){var e=s(t),i=t.pipelineContext,n=e.large,o=e.progressiveRender,a=e.large=i&&i.large,r=e.progressiveRender=i&&i.progressiveRender;return!!(n^a||o^r)&&"reset"}}var yc=jo(),xc=vc();function _c(){this.group=new Ci,this.uid=Nl("viewChart"),this.renderTask=Yh({plan:Mc,reset:Ic}),this.renderTask.context={view:this}}var wc=_c.prototype={type:"chart",init:function(t,e){},render:function(t,e,i,n){},highlight:function(t,e,i,n){Sc(t.getData(),n,"emphasis")},downplay:function(t,e,i,n){Sc(t.getData(),n,"normal")},remove:function(t,e){this.group.removeAll()},dispose:function(){},incrementalPrepareRender:null,incrementalRender:null,updateTransform:null,filterForExposedEvent:null};function bc(t,e,i){if(t&&(t.trigger(e,i),t.isGroup&&!Qs(t)))for(var n=0,o=t.childCount();nc?i+=p(g("data.partialData"),{displayCnt:c}):i+=g("data.allData");for(var r=[],s=0;si.blockIndex?i.step:null,a=n&&n.modDataCount;return{step:o,modBy:null!=a?Math.ceil(a/o):null,modDataCount:a}}},Bc.getPipeline=function(t){return this._pipelineMap.get(t)},Bc.updateStreamModes=function(t,e){var i=this._pipelineMap.get(t.uid),n=t.getData().count(),o=i.progressiveEnabled&&e.incrementalPrepareRender&&n>=i.threshold,a=t.get("large")&&n>=t.get("largeThreshold"),r="mod"===t.get("progressiveChunkMode")?n:null;t.pipelineContext=i.context={progressiveRender:o,modDataCount:r,large:a}},Bc.restorePipelines=function(t){var n=this,o=n._pipelineMap=Q();t.eachSeries(function(t){var e=t.getProgressive(),i=t.uid;o.set(i,{id:i,head:null,tail:null,threshold:t.getProgressiveThreshold(),progressiveEnabled:e&&!(t.preventIncremental&&t.preventIncremental()),blockIndex:-1,step:Math.round(e||700),count:0}),Kc(n,t,t.dataTask)})},Bc.prepareStageTasks=function(){var i=this._stageTaskMap,n=this.ecInstance.getModel(),o=this.api;R(this._allHandlers,function(t){var e=i.get(t.uid)||i.set(t.uid,[]);t.reset&&function(n,o,t,a,r){var s=t.seriesTaskMap||(t.seriesTaskMap=Q()),e=o.seriesType,i=o.getTargetSeries;o.createOnAllSeries?a.eachRawSeries(l):e?a.eachRawSeriesByType(e,l):i&&i(a,r).each(l);function l(t){var e=t.uid,i=s.get(e)||s.set(e,Yh({plan:Uc,reset:Xc,count:qc}));i.context={model:t,ecModel:a,api:r,useClearVisual:o.isVisual&&!o.isLayout,plan:o.plan,reset:o.reset,scheduler:n},Kc(n,t,i)}var u=n._pipelineMap;s.each(function(t,e){u.get(e)||(t.dispose(),s.removeKey(e))})}(this,t,e,n,o),t.overallReset&&function(n,t,e,i,o){var a=e.overallTask=e.overallTask||Yh({reset:Fc});a.context={ecModel:i,api:o,overallReset:t.overallReset,scheduler:n};var r=a.agentStubMap=a.agentStubMap||Q(),s=t.seriesType,l=t.getTargetSeries,u=!0,h=t.modifyOutputEnd;s?i.eachRawSeriesByType(s,c):l?l(i,o).each(c):(u=!1,R(i.getSeries(),c));function c(t){var e=t.uid,i=r.get(e);i||(i=r.set(e,Yh({reset:Wc,onDirty:Zc})),a.dirty()),i.context={model:t,overallProgress:u,modifyOutputEnd:h},i.agent=a,i.__block=u,Kc(n,t,i)}var d=n._pipelineMap;r.each(function(t,e){d.get(e)||(t.dispose(),a.dirty(),r.removeKey(e))})}(this,t,e,n,o)},this)},Bc.prepareView=function(t,e,i,n){var o=t.renderTask,a=o.context;a.model=e,a.ecModel=i,a.api=n,o.__block=!t.incrementalPrepareRender,Kc(this,e,o)},Bc.performDataProcessorTasks=function(t,e){Vc(this,this._dataProcessorHandlers,t,e,{block:!0})},Bc.performVisualTasks=function(t,e,i){Vc(this,this._visualHandlers,t,e,i)},Bc.performSeriesTasks=function(t){var e;t.eachSeries(function(t){e|=t.dataTask.perform()}),this.unfinished|=e},Bc.plan=function(){this._pipelineMap.each(function(t){var e=t.tail;do{if(e.__block){t.blockIndex=e.__idxInPipeline;break}e=e.getUpstream()}while(e)})};var Gc=Bc.updatePayload=function(t,e){"remain"!==e&&(t.context.payload=e)};function Fc(t){t.overallReset(t.ecModel,t.api,t.payload)}function Wc(t,e){return t.overallProgress&&Hc}function Hc(){this.agent.dirty(),this.getDownstream().dirty()}function Zc(){this.agent&&this.agent.dirty()}function Uc(t){return t.plan&&t.plan(t.model,t.ecModel,t.api,t.payload)}function Xc(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=Vo(t.reset(t.model,t.ecModel,t.api,t.payload));return 1'+t.dom+""}),p.painter.getSvgRoot().innerHTML=g,o.connectedBackgroundColor&&p.painter.setBackgroundColor(o.connectedBackgroundColor),p.refreshImmediately(),p.painter.toDataURL()}return o.connectedBackgroundColor&&p.add(new rs({shape:{x:0,y:0,width:t,height:e},style:{fill:o.connectedBackgroundColor}})),Td(f,function(t){var e=new Qn({style:{x:t.left*i-u,y:t.top*i-h,image:t.dom}});p.add(e)}),p.refreshImmediately(),n.toDataURL("image/"+(o&&o.type||"png"))}return this.getDataURL(o)}},zd.convertToPixel=T(Bd,"convertToPixel"),zd.convertFromPixel=T(Bd,"convertFromPixel"),zd.containPixel=function(t,o){var a;if(!this._disposed)return R(t=Ko(this._model,t),function(t,n){0<=n.indexOf("Models")&&R(t,function(t){var e=t.coordinateSystem;if(e&&e.containPoint)a|=!!e.containPoint(o);else if("seriesModels"===n){var i=this._chartsMap[t.__viewId];i&&i.containPoint&&(a|=i.containPoint(o,t))}},this)},this),!!a},zd.getVisual=function(t,e){var i=(t=Ko(this._model,t,{defaultMainType:"series"})).seriesModel.getData(),n=t.hasOwnProperty("dataIndexInside")?t.dataIndexInside:t.hasOwnProperty("dataIndex")?i.indexOfRawIndex(t.dataIndex):null;return null!=n?i.getItemVisual(n,e):i.getVisual(e)},zd.getViewOfComponentModel=function(t){return this._componentsMap[t.__viewId]},zd.getViewOfSeriesModel=function(t){return this._chartsMap[t.__viewId]};var Vd={prepareAndUpdate:function(t){Gd(this),Vd.update.call(this,t)},update:function(t){var e=this._model,i=this._api,n=this._zr,o=this._coordSysMgr,a=this._scheduler;if(e){a.restoreData(e,t),a.performSeriesTasks(e),o.create(e,i),a.performDataProcessorTasks(e,t),Wd(this,e),o.update(e,i),Yd(e),a.performVisualTasks(e,t),jd(this,e,i,t);var r=e.get("backgroundColor")||"transparent";if(v.canvasSupported)n.setBackgroundColor(r);else{var s=Fe(r);r=$e(s,"rgb"),0===s[3]&&(r="transparent")}Kd(e,i)}},updateTransform:function(o){var a=this._model,r=this,s=this._api;if(a){var l=[];a.eachComponent(function(t,e){var i=r.getViewOfComponentModel(e);if(i&&i.__alive)if(i.updateTransform){var n=i.updateTransform(e,a,s,o);n&&n.update&&l.push(i)}else l.push(i)});var n=Q();a.eachSeries(function(t){var e=r._chartsMap[t.__viewId];if(e.updateTransform){var i=e.updateTransform(t,a,s,o);i&&i.update&&n.set(t.uid,1)}else n.set(t.uid,1)}),Yd(a),this._scheduler.performVisualTasks(a,o,{setDirty:!0,dirtyMap:n}),qd(r,a,s,o,n),Kd(a,this._api)}},updateView:function(t){var e=this._model;e&&(_c.markUpdateMethod(t,"updateView"),Yd(e),this._scheduler.performVisualTasks(e,t,{setDirty:!0}),jd(this,this._model,this._api,t),Kd(e,this._api))},updateVisual:function(t){Vd.update.call(this,t)},updateLayout:function(t){Vd.update.call(this,t)}};function Gd(t){var e=t._model,i=t._scheduler;i.restorePipelines(e),i.prepareStageTasks(),Xd(t,"component",e,i),Xd(t,"chart",e,i),i.plan()}function Fd(e,i,n,o,t){var a=e._model;if(o){var r={};r[o+"Id"]=n[o+"Id"],r[o+"Index"]=n[o+"Index"],r[o+"Name"]=n[o+"Name"];var s={mainType:o,query:r};t&&(s.subType=t);var l=n.excludeSeriesId;null!=l&&(l=Q(Vo(l))),a&&a.eachComponent(s,function(t){l&&null!=l.get(t.id)||u(e["series"===o?"_chartsMap":"_componentsMap"][t.__viewId])},e)}else Td(e._componentsViews.concat(e._chartsViews),u);function u(t){t&&t.__alive&&t[i]&&t[i](t.__model,a,e._api,n)}}function Wd(t,e){var i=t._chartsMap,n=t._scheduler;e.eachSeries(function(t){n.updateStreamModes(t,i[t.__viewId])})}function Hd(e,t){var i=e.type,n=e.escapeConnect,o=tf[i],a=o.actionInfo,r=(a.update||"update").split(":"),s=r.pop();r=null!=r[0]&&Cd(r[0]),this[kd]=!0;var l=[e],u=!1;e.batch&&(u=!0,l=O(e.batch,function(t){return(t=D(P({},t),e)).batch=null,t}));var h,c=[],d="highlight"===i||"downplay"===i;Td(l,function(t){(h=(h=o.action(t,this._model,this._api))||P({},t)).type=a.event||h.type,c.push(h),d?Fd(this,s,t,"series"):r&&Fd(this,s,t,r.main,r.sub)},this),"none"===s||d||r||(this[Pd]?(Gd(this),Vd.update.call(this,e),this[Pd]=!1):Vd[s].call(this,e)),h=u?{type:a.event||i,escapeConnect:n,batch:c}:c[0],this[kd]=!1,t||this._messageCenter.trigger(h.type,h)}function Zd(t){for(var e=this._pendingActions;e.length;){var i=e.shift();Hd.call(this,i,t)}}function Ud(t){t||this.trigger("updated")}function Xd(t,e,o,a){for(var r="component"===e,s=r?t._componentsViews:t._chartsViews,l=r?t._componentsMap:t._chartsMap,u=t._zr,h=t._api,i=0;it.get("hoverLayerThreshold")&&!v.node&&t.eachSeries(function(t){if(!t.preventUsingHoverLayer){var e=i._chartsMap[t.__viewId];e.__alive&&e.group.traverse(function(t){t.useHoverLayer=!0})}})}(n,t),Rc(n._zr.dom,t)}function Kd(e,i){Td(af,function(t){t(e,i)})}zd.resize=function(t){if(!this._disposed){this._zr.resize(t);var e=this._model;if(this._loadingFX&&this._loadingFX.resize(),e){var i=e.resetOption("media"),n=t&&t.silent;this[kd]=!0,i&&Gd(this),Vd.update.call(this),this[kd]=!1,Zd.call(this,n),Ud.call(this,n)}}},zd.showLoading=function(t,e){if(!this._disposed&&(Dd(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),lf[t])){var i=lf[t](this._api,e),n=this._zr;this._loadingFX=i,n.add(i)}},zd.hideLoading=function(){this._disposed||(this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null)},zd.makeActionFromEvent=function(t){var e=P({},t);return e.type=ef[t.type],e},zd.dispatchAction=function(t,e){this._disposed||(Dd(e)||(e={silent:!!e}),tf[t.type]&&this._model&&(this[kd]?this._pendingActions.push(t):(Hd.call(this,t,e.silent),e.flush?this._zr.flush(!0):!1!==e.flush&&v.browser.weChat&&this._throttledZrFlush(),Zd.call(this,e.silent),Ud.call(this,e.silent))))},zd.appendData=function(t){if(!this._disposed){var e=t.seriesIndex;this.getModel().getSeriesByIndex(e).appendData(t),this._scheduler.unfinished=!0}},zd.on=Od("on",!1),zd.off=Od("off",!1),zd.one=Od("one",!1);var $d=["click","dblclick","mouseover","mouseout","mousemove","mousedown","mouseup","globalout","contextmenu"];function Jd(t,e){var i=t.get("z"),n=t.get("zlevel");e.group.traverse(function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=n&&(t.zlevel=n))})}function Qd(){this.eventInfo}zd._initEvents=function(){Td($d,function(u){function t(t){var e,i=this.getModel(),n=t.target;if("globalout"===u)e={};else if(n&&null!=n.dataIndex){var o=n.dataModel||i.getSeriesByIndex(n.seriesIndex);e=o&&o.getDataParams(n.dataIndex,n.dataType,n)||{}}else n&&n.eventData&&(e=P({},n.eventData));if(e){var a=e.componentType,r=e.componentIndex;"markLine"!==a&&"markPoint"!==a&&"markArea"!==a||(a="series",r=e.seriesIndex);var s=a&&null!=r&&i.getComponent(a,r),l=s&&this["series"===s.mainType?"_chartsMap":"_componentsMap"][s.__viewId];e.event=t,e.type=u,this._ecEventProcessor.eventInfo={targetEl:n,packedEvent:e,model:s,view:l},this.trigger(u,e)}}t.zrEventfulCallAtLast=!0,this._zr.on(u,t,this)},this),Td(ef,function(t,e){this._messageCenter.on(e,function(t){this.trigger(e,t)},this)},this)},zd.isDisposed=function(){return this._disposed},zd.clear=function(){this._disposed||this.setOption({series:[]},!0)},zd.dispose=function(){if(!this._disposed){this._disposed=!0,Jo(this.getDom(),ff,"");var e=this._api,i=this._model;Td(this._componentsViews,function(t){t.dispose(i,e)}),Td(this._chartsViews,function(t){t.dispose(i,e)}),this._zr.dispose(),delete uf[this.id]}},b(Ed,Ct),Qd.prototype={constructor:Qd,normalizeQuery:function(t){var s={},l={},u={};if(E(t)){var e=Cd(t);s.mainType=e.main||null,s.subType=e.sub||null}else{var h=["Index","Name","Id"],c={name:1,dataIndex:1,dataType:1};R(t,function(t,e){for(var i=!1,n=0;nx[1]&&(x[1]=y)}e&&(this._nameList[d]=e[f])}this._rawCount=this._count=l,this._extent={},Kf(this)},jf._initDataFromProvider=function(t,e){if(!(e<=t)){for(var i,n=this._chunkSize,o=this._rawData,a=this._storage,r=this.dimensions,s=r.length,l=this._dimensionInfos,u=this._nameList,h=this._idList,c=this._rawExtent,d=this._nameRepeatCount={},f=this._chunkCount,p=0;pM[1]&&(M[1]=S)}if(!o.pure){var I=u[v];if(m&&null==I)if(null!=m.name)u[v]=I=m.name;else if(null!=i){var T=r[i],A=a[T][y];if(A){I=A[x];var D=l[T].ordinalMeta;D&&D.categories.length&&(I=D.categories[I])}}var C=null==m?null:m.id;null==C&&null!=I&&(d[I]=d[I]||0,0=this._rawCount||t<0)return-1;if(!this._indices)return t;var e=this._indices,i=e[t];if(null!=i&&it))return a;o=a-1}}return-1},jf.indicesOfNearest=function(t,e,i){var n=[];if(!this._storage[t])return n;null==i&&(i=1/0);for(var o=1/0,a=-1,r=0,s=0,l=this.count();st[I][1])&&(M=!1)}M&&(a[r++]=this.getRawIndex(m))}return rw[1]&&(w[1]=_)}}}return o},jf.downSample=function(t,e,i,n){for(var o=ip(this,[t]),a=o._storage,r=[],s=Math.floor(1/e),l=a[t],u=this.count(),h=this._chunkSize,c=o._rawExtent[t],d=new(Hf(this))(u),f=0,p=0;pc[1]&&(c[1]=x),d[f++]=_}return o._count=f,o._indices=d,o.getRawIndex=Qf,o},jf.getItemModel=function(t){var e=this.hostModel;return new Cl(this.getRawDataItem(t),e,e&&e.ecModel)},jf.diff=function(e){var i=this;return new kf(e?e.getIndices():[],this.getIndices(),function(t){return tp(e,t)},function(t){return tp(i,t)})},jf.getVisual=function(t){var e=this._visual;return e&&e[t]},jf.setVisual=function(t,e){if(zf(t))for(var i in t)t.hasOwnProperty(i)&&this.setVisual(i,t[i]);else this._visual=this._visual||{},this._visual[t]=e},jf.setLayout=function(t,e){if(zf(t))for(var i in t)t.hasOwnProperty(i)&&this.setLayout(i,t[i]);else this._layout[t]=e},jf.getLayout=function(t){return this._layout[t]},jf.getItemLayout=function(t){return this._itemLayouts[t]},jf.setItemLayout=function(t,e,i){this._itemLayouts[t]=i?P(this._itemLayouts[t]||{},e):e},jf.clearItemLayouts=function(){this._itemLayouts.length=0},jf.getItemVisual=function(t,e,i){var n=this._itemVisuals[t],o=n&&n[e];return null!=o||i?o:this.getVisual(e)},jf.setItemVisual=function(t,e,i){var n=this._itemVisuals[t]||{},o=this.hasItemVisual;if(this._itemVisuals[t]=n,zf(e))for(var a in e)e.hasOwnProperty(a)&&(n[a]=e[a],o[a]=!0);else n[e]=i,o[e]=!0},jf.clearAllVisual=function(){this._visual={},this._itemVisuals=[],this.hasItemVisual={}};function ap(t){t.seriesIndex=this.seriesIndex,t.dataIndex=this.dataIndex,t.dataType=this.dataType}function rp(t,e,i){Uu.isInstance(e)||(e=Uu.seriesDataToSource(e)),i=i||{},t=(t||[]).slice();for(var n=(i.dimsDef||[]).slice(),o=Q(),a=Q(),l=[],r=function(t,e,i,n){var o=Math.max(t.dimensionsDetectCount||1,e.length,i.length,n||0);return R(e,function(t){var e=t.dimsDef;e&&(o=Math.max(o,e.length))}),o}(e,t,n,i.dimCount),s=0;s=e[0]&&t<=e[1]},mp.prototype.normalize=function(t){var e=this._extent;return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])},mp.prototype.scale=function(t){var e=this._extent;return t*(e[1]-e[0])+e[0]},mp.prototype.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1])},mp.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},mp.prototype.getExtent=function(){return this._extent.slice()},mp.prototype.setExtent=function(t,e){var i=this._extent;isNaN(t)||(i[0]=t),isNaN(e)||(i[1]=e)},mp.prototype.isBlank=function(){return this._isBlank},mp.prototype.setBlank=function(t){this._isBlank=t},mp.prototype.getLabel=null,oa(mp),ua(mp,{registerWhenExtend:!0}),vp.createByAxisModel=function(t){var e=t.option,i=e.data,n=i&&O(i,_p);return new vp({categories:n,needCollect:!n,deduplication:!1!==e.dedplication})};var yp=vp.prototype;function xp(t){return t._map||(t._map=Q(t.categories))}function _p(t){return z(t)&&null!=t.value?t.value:t+""}yp.getOrdinal=function(t){return xp(this).get(t)},yp.parseAndCollect=function(t){var e,i=this._needCollect;if("string"!=typeof t&&!i)return t;if(i&&!this._deduplication)return e=this.categories.length,this.categories[e]=t,e;var n=xp(this);return null==(e=n.get(t))&&(i?(e=this.categories.length,this.categories[e]=t,n.set(t,e)):e=NaN),e};var wp=mp.prototype,bp=mp.extend({type:"ordinal",init:function(t,e){t&&!L(t)||(t=new vp({categories:t})),this._ordinalMeta=t,this._extent=e||[0,t.categories.length-1]},parse:function(t){return"string"==typeof t?this._ordinalMeta.getOrdinal(t):Math.round(t)},contain:function(t){return t=this.parse(t),wp.contain.call(this,t)&&null!=this._ordinalMeta.categories[t]},normalize:function(t){return wp.normalize.call(this,this.parse(t))},scale:function(t){return Math.round(wp.scale.call(this,t))},getTicks:function(){for(var t=[],e=this._extent,i=e[0];i<=e[1];)t.push(i),i++;return t},getLabel:function(t){if(!this.isBlank())return this._ordinalMeta.categories[t]},count:function(){return this._extent[1]-this._extent[0]+1},unionExtentFromData:function(t,e){this.unionExtent(t.getApproximateExtent(e))},getOrdinalMeta:function(){return this._ordinalMeta},niceTicks:et,niceExtent:et});bp.create=function(){return new bp};var Sp=zl;function Mp(t){return Gl(t)+2}function Ip(t,e,i){t[e]=Math.max(Math.min(t[e],i[1]),i[0])}function Tp(t,e){isFinite(t[0])||(t[0]=e[0]),isFinite(t[1])||(t[1]=e[1]),Ip(t,0,e),Ip(t,1,e),t[0]>t[1]&&(t[0]=t[1])}var Ap=zl,Dp=mp.extend({type:"interval",_interval:0,_intervalPrecision:2,setExtent:function(t,e){var i=this._extent;isNaN(t)||(i[0]=parseFloat(t)),isNaN(e)||(i[1]=parseFloat(e))},unionExtent:function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1]),Dp.prototype.setExtent.call(this,e[0],e[1])},getInterval:function(){return this._interval},setInterval:function(t){this._interval=t,this._niceExtent=this._extent.slice(),this._intervalPrecision=Mp(t)},getTicks:function(t){var e=this._interval,i=this._extent,n=this._niceExtent,o=this._intervalPrecision,a=[];if(!e)return a;i[0]s&&(t?a.push(Ap(s+e,o)):a.push(i[1])),a},getMinorTicks:function(t){for(var e=this.getTicks(!0),i=[],n=this.getExtent(),o=1;on[0]&&h>>1;t[o][1]>1^-(1&s),l=l>>1^-(1&l),o=s+=o,a=l+=a,n.push([s/i,l/i])}return n}Ag.prototype={constructor:Ag,properties:null,getBoundingRect:function(){var t=this._rect;if(t)return t;for(var e=Number.MAX_VALUE,i=[e,e],n=[-e,-e],o=[],a=[],r=this.geometries,s=0;ss[1];d(e[0].coord,s[0])&&(n?e[0].coord=s[0]:e.shift());n&&d(s[0],e[0].coord)&&e.unshift({coord:s[0]});d(s[1],a.coord)&&(n?a.coord=s[1]:e.pop());n&&d(a.coord,s[1])&&e.push({coord:s[1]});function d(t,e){return t=zl(t),e=zl(e),c?en[0]&&(n[0]=a[0]),a[1]>n[1]&&(n[1]=a[1])}return{min:e?i:n,max:e?n:i}}var xm=Ar.extend({type:"ec-polyline",shape:{points:[],smooth:0,smoothConstraint:!0,smoothMonotone:null,connectNulls:!1},style:{fill:null,stroke:"#000"},brush:Xr(Ar.prototype.brush),buildPath:function(t,e){var i=e.points,n=0,o=i.length,a=ym(i,e.smoothConstraint);if(e.connectNulls){for(;0n)return!1;return!0}(a,e))){var r=e.mapDimension(a.dim),s={};return R(a.getViewLabels(),function(t){s[t.tickValue]=1}),function(t){return!s.hasOwnProperty(e.get(r,t))}}}}function Cm(t,e,i){if("cartesian2d"!==t.type)return bm(t,e,i);var n=t.getBaseAxis().isHorizontal(),o=wm(t,e,i);if(!i.get("clip",!0)){var a=o.shape,r=Math.max(a.width,a.height);n?(a.y-=r,a.height+=2*r):(a.x-=r,a.width+=2*r)}return o}_c.extend({type:"line",init:function(){var t=new Ci,e=new im;this.group.add(e.group),this._symbolDraw=e,this._lineGroup=t},render:function(t,e,i){var n=t.coordinateSystem,o=this.group,a=t.getData(),r=t.getModel("lineStyle"),s=t.getModel("areaStyle"),l=a.mapArray(a.getItemLayout),u="polar"===n.type,h=this._coordSys,c=this._symbolDraw,d=this._polyline,f=this._polygon,p=this._lineGroup,g=t.get("animation"),m=!s.isEmpty(),v=s.get("origin"),y=function(t,e,i){if(!i.valueDim)return[];for(var n=[],o=0,a=e.count();oh[c-1].coord&&(h.reverse(),d.reverse());var f=h[0].coord-10,p=h[c-1].coord+10,g=p-f;if(g<.001)return"transparent";R(h,function(t){t.offset=(t.coord-f)/g}),h.push({offset:c?h[c-1].offset:.5,color:d[1]||"transparent"}),h.unshift({offset:c?h[0].offset:.5,color:d[0]||"transparent"});var m=new gs(0,0,0,0,h,!0);return m[n]=f,m[n+"2"]=p,m}}}(a,n)||a.getVisual("color");d.useStyle(D(r.getLineStyle(),{fill:"none",stroke:M,lineJoin:"bevel"}));var I=t.get("smooth");if(I=Tm(t.get("smooth")),d.setShape({smooth:I,smoothMonotone:t.get("smoothMonotone"),connectNulls:t.get("connectNulls")}),f){var T=a.getCalculationInfo("stackedOnSeries"),A=0;f.useStyle(D(s.getAreaStyle(),{fill:M,opacity:.7,lineJoin:"bevel"})),T&&(A=Tm(T.get("smooth"))),f.setShape({smooth:I,stackedOnSmooth:A,smoothMonotone:t.get("smoothMonotone"),connectNulls:t.get("connectNulls")})}this._data=a,this._coordSys=n,this._stackedOnPoints=y,this._points=l,this._step=S,this._valueOrigin=v},dispose:function(){},highlight:function(t,e,i,n){var o=t.getData(),a=Yo(o,n);if(!(a instanceof Array)&&null!=a&&0<=a){var r=o.getItemGraphicEl(a);if(!r){var s=o.getItemLayout(a);if(!s)return;if(this._clipShapeForSymbol&&!this._clipShapeForSymbol.contain(s[0],s[1]))return;(r=new Xg(o,a)).position=s,r.setZ(t.get("zlevel"),t.get("z")),r.ignore=isNaN(s[0])||isNaN(s[1]),r.__temp=!0,o.setItemGraphicEl(a,r),r.stopSymbolAnimation(!0),this.group.add(r)}r.highlight()}else _c.prototype.highlight.call(this,t,e,i,n)},downplay:function(t,e,i,n){var o=t.getData(),a=Yo(o,n);if(null!=a&&0<=a){var r=o.getItemGraphicEl(a);r&&(r.__temp?(o.setItemGraphicEl(a,null),this.group.remove(r)):r.downplay())}else _c.prototype.downplay.call(this,t,e,i,n)},_newPolyline:function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new xm({shape:{points:t},silent:!0,z2:10}),this._lineGroup.add(e),this._polyline=e},_newPolygon:function(t,e){var i=this._polygon;return i&&this._lineGroup.remove(i),i=new _m({shape:{points:t,stackedOnPoints:e},silent:!0}),this._lineGroup.add(i),this._polygon=i},_updateAnimation:function(t,e,i,n,o,a){var r=this._polyline,s=this._polygon,l=t.hostModel,u=function(t,e,i,n,o,a,r,s){for(var l=function(t,e){var i=[];return e.diff(t).add(function(t){i.push({cmd:"+",idx:t})}).update(function(t,e){i.push({cmd:"=",idx:e,idx1:t})}).remove(function(t){i.push({cmd:"-",idx:t})}).execute(),i}(t,e),u=[],h=[],c=[],d=[],f=[],p=[],g=[],m=sm(o,e,r),v=sm(a,t,s),y=0;ye&&(e=t[i]);return isFinite(e)?e:NaN},min:function(t){for(var e=1/0,i=0;ie[1]&&e.reverse(),e},getOtherAxis:function(){this.grid.getOtherAxis()},pointToData:function(t,e){return this.coordToData(this.toLocalCoord(t["x"===this.dim?0:1]),e)},toLocalCoord:null,toGlobalCoord:null},w(zm,Gg);var Bm={show:!0,zlevel:0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisPointer:{},axisLine:{show:!0,onZero:!0,onZeroAxisIndex:null,lineStyle:{color:"#333",width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15]},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,showMinLabel:null,showMaxLabel:null,margin:8,fontSize:12},splitLine:{show:!0,lineStyle:{color:["#ccc"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.3)","rgba(200,200,200,0.3)"]}}},Vm={};Vm.categoryAxis=m({boundaryGap:!0,deduplication:null,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},Bm),Vm.valueAxis=m({boundaryGap:[0,0],splitNumber:5,minorTick:{show:!1,splitNumber:5,length:3,lineStyle:{}},minorSplitLine:{show:!1,lineStyle:{color:"#eee",width:1}}},Bm),Vm.timeAxis=D({scale:!0,min:"dataMin",max:"dataMax"},Vm.valueAxis),Vm.logAxis=D({scale:!0,logBase:10},Vm.valueAxis);function Gm(a,t,r,e){R(Fm,function(o){t.extend({type:a+"Axis."+o,mergeDefaultAndTheme:function(t,e){var i=this.layoutMode,n=i?Iu(t):{};m(t,e.getTheme().get(o+"Axis")),m(t,this.getDefaultOption()),t.type=r(a,t),i&&Mu(t,n,i)},optionUpdated:function(){"category"===this.option.type&&(this.__ordinalMeta=vp.createByAxisModel(this))},getCategories:function(t){var e=this.option;if("category"===e.type)return t?e.data:this.__ordinalMeta.categories},getOrdinalMeta:function(){return this.__ordinalMeta},defaultOption:p([{},Vm[o+"Axis"],e],!0)})}),ku.registerSubTypeDefaulter(a+"Axis",T(r,a))}var Fm=["value","category","time","log"],Wm=ku.extend({type:"cartesian2dAxis",axis:null,init:function(){Wm.superApply(this,"init",arguments),this.resetRange()},mergeOption:function(){Wm.superApply(this,"mergeOption",arguments),this.resetRange()},restoreData:function(){Wm.superApply(this,"restoreData",arguments),this.resetRange()},getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"grid",index:this.option.gridIndex,id:this.option.gridId})[0]}});function Hm(t,e){return e.type||(e.data?"category":"value")}m(Wm.prototype,dg);var Zm={offset:0};function Um(t,e){return t.getCoordSysModel()===e}function Xm(t,e,i){this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this._initCartesian(t,e,i),this.model=t}Gm("x",Wm,Hm,Zm),Gm("y",Wm,Hm,Zm),ku.extend({type:"grid",dependencies:["xAxis","yAxis"],layoutMode:"box",coordinateSystem:null,defaultOption:{show:!1,zlevel:0,z:0,left:"10%",top:60,right:"10%",bottom:60,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"}});var Ym=Xm.prototype;function jm(t,e,i,n){i.getAxesOnZeroOf=function(){return o?[o]:[]};var o,a=t[e],r=i.model,s=r.get("axisLine.onZero"),l=r.get("axisLine.onZeroAxisIndex");if(s){if(null!=l)qm(a[l])&&(o=a[l]);else for(var u in a)if(a.hasOwnProperty(u)&&qm(a[u])&&!n[h(a[u])]){o=a[u];break}o&&(n[h(o)]=!0)}function h(t){return t.dim+"_"+t.index}}function qm(t){return t&&"category"!==t.type&&"time"!==t.type&&function(t){var e=t.scale.getExtent(),i=e[0],n=e[1];return!(0u[1]?-1:1,c=["start"===a?u[0]-h*l:"end"===a?u[1]+h*l:(u[0]+u[1])/2,sv(a)?t.labelOffset+r*l:0],d=e.get("nameRotate");null!=d&&(d=d*tv/180),sv(a)?n=nv(t.rotation,null!=d?d:t.rotation,r):(n=function(t,e,i,n){var o,a,r=Zl(i-t.rotation),s=n[0]>n[1],l="start"===e&&!s||"start"!==e&&s;o=Ul(r-tv/2)?(a=l?"bottom":"top","center"):Ul(r-1.5*tv)?(a=l?"top":"bottom","center"):(a="middle",r<1.5*tv&&tv/2l[1]&&l.reverse(),(null==r||r>l[1])&&(r=l[1]),r=i.r0}}});var ny=Math.PI/180;function oy(o,t,e,i,n,a,r,s,l,u){function h(t,e,i){for(var n=t;nl+r);n++)if(o[n].y+=i,to[n].y+o[n].height)return void c(n,i/2);c(e-1,i/2)}function c(t,e){for(var i=t;0<=i&&!(o[i].y-eo[i-1].y+o[i-1].height));i--);}function d(t,e,i,n,o,a){for(var r=e?Number.MAX_VALUE:0,s=0,l=t.length;s=e?v.push(o[y]):m.push(o[y]);d(m,!1,t,e,i,n),d(v,!0,t,e,i,n)}function ay(t){return"center"===t.position}function ry(L,k,P,t,N,e){var O,R,E=L.getData(),z=[],B=!1,V=(L.get("minShowLabelAngle")||0)*ny;E.each(function(t){var e=E.getItemLayout(t),i=E.getItemModel(t),n=i.getModel("label"),o=n.get("position")||i.get("emphasis.label.position"),a=n.get("distanceToLabelLine"),r=n.get("alignTo"),s=El(n.get("margin"),P),l=n.get("bleedMargin"),u=n.getFont(),h=i.getModel("labelLine"),c=h.get("length");c=El(c,P);var d=h.get("length2");if(d=El(d,P),!(e.anglei[0]&&isFinite(h)&&isFinite(i[0]););else{var l=o.getTicks().length-1;c":"\n";return au(""===r?this.name:r)+s+O(a,function(t,e){var i=o.get(o.mapDimension(t.dim),n);return au(t.name+" : "+i)}).join(s)},getTooltipPosition:function(t){if(null!=t)for(var e=this.getData(),i=this.coordinateSystem,n=e.getValues(O(i.dimensions,function(t){return e.mapDimension(t)}),t,!0),o=0,a=n.length;o":"\n";return l.join(", ")+d+au(r+" : "+a)},getTooltipPosition:function(t){if(null!=t){var e=this.getData().getName(t),i=this.coordinateSystem,n=i.getRegion(e);return n&&i.dataToPoint(n.center)}},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},defaultOption:{zlevel:0,z:2,coordinateSystem:"geo",map:"",left:"center",top:"center",aspectScale:.75,showLegendSymbol:!0,dataRangeHoverLink:!0,boundingCoords:null,center:null,zoom:1,scaleLimit:null,label:{show:!1,color:"#000"},itemStyle:{borderWidth:.5,borderColor:"#444",areaColor:"#eee"},emphasis:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{areaColor:"rgba(255,215,0,0.8)"}},nameProperty:"name"}}),jv);var Ey="\0_ec_interaction_mutex";function zy(t,e){return!!By(t)[e]}function By(t){return t[Ey]||(t[Ey]={})}function Vy(i){this.pointerChecker,this._zr=i,this._opt={};var t=A,n=t(Gy,this),o=t(Fy,this),a=t(Wy,this),r=t(Hy,this),s=t(Zy,this);Ct.call(this),this.setPointerChecker=function(t){this.pointerChecker=t},this.enable=function(t,e){this.disable(),this._opt=D(k(e)||{},{zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!1,preventDefaultMouseMove:!0}),null==t&&(t=!0),!0!==t&&"move"!==t&&"pan"!==t||(i.on("mousedown",n),i.on("mousemove",o),i.on("mouseup",a)),!0!==t&&"scale"!==t&&"zoom"!==t||(i.on("mousewheel",r),i.on("pinch",s))},this.disable=function(){i.off("mousedown",n),i.off("mousemove",o),i.off("mouseup",a),i.off("mousewheel",r),i.off("pinch",s)},this.dispose=this.disable,this.isDragging=function(){return this._dragging},this.isPinching=function(){return this._pinching}}function Gy(t){if(!(Yt(t)||t.target&&t.target.draggable)){var e=t.offsetX,i=t.offsetY;this.pointerChecker&&this.pointerChecker(t,e,i)&&(this._x=e,this._y=i,this._dragging=!0)}}function Fy(t){if(this._dragging&&Yy("moveOnMouseMove",t,this._opt)&&"pinch"!==t.gestureEvent&&!zy(this._zr,"globalPan")){var e=t.offsetX,i=t.offsetY,n=this._x,o=this._y,a=e-n,r=i-o;this._x=e,this._y=i,this._opt.preventDefaultMouseMove&&Xt(t.event),Xy(this,"pan","moveOnMouseMove",t,{dx:a,dy:r,oldX:n,oldY:o,newX:e,newY:i})}}function Wy(t){Yt(t)||(this._dragging=!1)}function Hy(t){var e=Yy("zoomOnMouseWheel",t,this._opt),i=Yy("moveOnMouseWheel",t,this._opt),n=t.wheelDelta,o=Math.abs(n),a=t.offsetX,r=t.offsetY;if(0!==n&&(e||i)){if(e){var s=3e&&(e=n.height)}this.height=e+1},getNodeById:function(t){if(this.getId()===t)return this;for(var e=0,i=this.children,n=i.length;ei&&(i=t.depth)});var a=t.expandAndCollapse&&0<=t.initialTreeDepth?t.initialTreeDepth:i;return o.root.eachNode("preorder",function(t){var e=t.hostTree.data.getRawDataItem(t.dataIndex);t.isExpand=e&&null!=e.collapsed?!e.collapsed:t.depth<=a}),o.data},getOrient:function(){var t=this.get("orient");return"horizontal"===t?t="LR":"vertical"===t&&(t="TB"),t},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},formatTooltip:function(t){for(var e=this.getData().tree,i=e.root.children[0],n=e.getNodeByDataIndex(t),o=n.getValue(),a=n.name;n&&n!==i;)a=n.parentNode.name+"."+a,n=n.parentNode;return au(a+(isNaN(o)||null==o?"":" : "+o))},defaultOption:{zlevel:0,z:2,coordinateSystem:"view",left:"12%",top:"12%",right:"12%",bottom:"12%",layout:"orthogonal",edgeShape:"curve",edgeForkPosition:"50%",roam:!1,nodeScaleRatio:.4,center:null,zoom:1,orient:"LR",symbol:"emptyCircle",symbolSize:7,expandAndCollapse:!0,initialTreeDepth:2,lineStyle:{color:"#ccc",width:1.5,curveness:.5},itemStyle:{color:"lightsteelblue",borderColor:"#c23531",borderWidth:1.5},label:{show:!0,color:"#555"},leaves:{label:{show:!0}},animationEasing:"linear",animationDuration:700,animationDurationUpdate:1e3}});var zx=Cs({shape:{parentPoint:[],childPoints:[],orient:"",forkPosition:""},style:{stroke:"#000",fill:null},buildPath:function(t,e){var i=e.childPoints,n=i.length,o=e.parentPoint,a=i[0],r=i[n-1];if(1===n)return t.moveTo(o[0],o[1]),void t.lineTo(a[0],a[1]);var s=e.orient,l="TB"===s||"BT"===s?0:1,u=1-l,h=El(e.forkPosition,1),c=[];c[l]=o[l],c[u]=o[u]+(r[u]-o[u])*h,t.moveTo(o[0],o[1]),t.lineTo(c[0],c[1]),t.moveTo(a[0],a[1]),c[l]=a[l],t.lineTo(c[0],c[1]),c[l]=r[l],t.lineTo(c[0],c[1]),t.lineTo(r[0],r[1]);for(var d=1;dx.x)||(m-=Math.PI);var b=v?"left":"right",S=a.labelModel.get("rotate"),M=S*(Math.PI/180);g.setStyle({textPosition:a.labelModel.get("position")||b,textRotation:null==S?-m:M,textOrigin:"center",verticalAlign:"middle"})}!function(t,e,i,n,o,a,r,s,l){var u=l.edgeShape,h=n.__edge;if("curve"===u)e.parentNode&&e.parentNode!==i&&cl(h=h||(n.__edge=new ds({shape:Wx(l,o,o),style:D({opacity:0,strokeNoScale:!0},l.lineStyle)})),{shape:Wx(l,a,r),style:D({opacity:1},l.lineStyle)},t);else if("polyline"===u&&"orthogonal"===l.layout&&e!==i&&e.children&&0!==e.children.length&&!0===e.isExpand){for(var c=e.children,d=[],f=0;fh.getLayout().x&&(h=t),t.depth>c.depth&&(c=t)});var d=u===h?1:r(u,h)/2,f=d-u.getLayout().x,p=0,g=0,m=0,v=0;if("radial"===n)p=o/(h.getLayout().x+d+f),g=a/(c.depth-1||1),Hx(l,function(t){m=(t.getLayout().x+f)*p,v=(t.depth-1)*g;var e=Px(m,v);t.setLayout({x:e.x,y:e.y,rawX:m,rawY:v},!0)});else{var y=t.getOrient();"RL"===y||"LR"===y?(g=a/(h.getLayout().x+d+f),p=o/(c.depth-1||1),Hx(l,function(t){v=(t.getLayout().x+f)*g,m="LR"===y?(t.depth-1)*p:o-(t.depth-1)*p,t.setLayout({x:m,y:v},!0)})):"TB"!==y&&"BT"!==y||(p=o/(h.getLayout().x+d+f),g=a/(c.depth-1||1),Hx(l,function(t){m=(t.getLayout().x+f)*p,v="TB"===y?(t.depth-1)*g:a-(t.depth-1)*g,t.setLayout({x:m,y:v},!0)}))}}}(t,e)})}),sc.extend({type:"series.treemap",layoutMode:"box",dependencies:["grid","polar"],preventUsingHoverLayer:!0,_viewRoot:null,defaultOption:{progressive:0,left:"center",top:"middle",right:null,bottom:null,width:"80%",height:"80%",sort:!0,clipWindow:"origin",squareRatio:.5*(1+Math.sqrt(5)),leafDepth:null,drillDownIcon:"▶",zoomToNodeRatio:.1024,roam:!0,nodeClick:"zoomToNode",animation:!0,animationDurationUpdate:900,animationEasing:"quinticInOut",breadcrumb:{show:!0,height:22,left:"center",top:"bottom",emptyItemWidth:25,itemStyle:{color:"rgba(0,0,0,0.7)",borderColor:"rgba(255,255,255,0.7)",borderWidth:1,shadowColor:"rgba(150,150,150,1)",shadowBlur:3,shadowOffsetX:0,shadowOffsetY:0,textStyle:{color:"#fff"}},emphasis:{textStyle:{}}},label:{show:!0,distance:0,padding:5,position:"inside",color:"#fff",ellipsis:!0},upperLabel:{show:!1,position:[0,"50%"],height:20,color:"#fff",ellipsis:!0,verticalAlign:"middle"},itemStyle:{color:null,colorAlpha:null,colorSaturation:null,borderWidth:0,gapWidth:0,borderColor:"#fff",borderColorSaturation:null},emphasis:{upperLabel:{show:!0,position:[0,"50%"],color:"#fff",ellipsis:!0,verticalAlign:"middle"}},visualDimension:0,visualMin:null,visualMax:null,color:[],colorAlpha:null,colorSaturation:null,colorMappingBy:"index",visibleMin:10,childrenVisibleMin:null,levels:[]},getInitialData:function(t,e){var i={name:t.name,children:t.data};!function i(t){var n=0;R(t.children,function(t){i(t);var e=t.value;L(e)&&(e=e[0]),n+=e});var e=t.value;L(e)&&(e=e[0]);null!=e&&!isNaN(e)||(e=n);e<0&&(e=0);L(t.value)?t.value[0]=e:t.value=e}(i);var n=t.levels||[],o=new Cl({itemStyle:this.designatedVisualItemStyle={}},this,e),a=O((n=t.levels=function(t,e){var n,i=e.get("color");if(!i)return;if(R(t=t||[],function(t){var e=new Cl(t),i=e.get("color");(e.get("itemStyle.color")||i&&"none"!==i)&&(n=!0)}),!n){(t[0]||(t[0]={})).color=i.slice()}return t}(n,e))||[],function(t){return new Cl(t,o,e)},this),r=Ax.createTree(i,this,function(t){t.wrapMethod("getItemModel",function(t,e){var i=r.getNodeByDataIndex(e),n=a[i.depth];return t.parentModel=n||o,t})});return r.data},optionUpdated:function(){this.resetViewRoot()},formatTooltip:function(t){var e=this.getData(),i=this.getRawValue(t),n=L(i)?tu(i[0]):tu(i);return au(e.getName(t)+": "+n)},getDataParams:function(t){var e=sc.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(t);return e.treePathInfo=Yx(i,this),e},setLayoutInfo:function(t){this.layoutInfo=this.layoutInfo||{},P(this.layoutInfo,t)},mapIdToIndex:function(t){var e=this._idIndexMap;e||(e=this._idIndexMap=Q(),this._idIndexMapCount=0);var i=e.get(t);return null==i&&e.set(t,i=this._idIndexMapCount++),i},getViewRoot:function(){return this._viewRoot},resetViewRoot:function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)}});var jx=5;function qx(t){this.group=new Ci,t.add(this.group)}function Kx(t,e,i,n,o,a){var r=[[o?t:t-jx,e],[t+i,e],[t+i,e+n],[o?t:t-jx,e+n]];return a||r.splice(2,0,[t+i+jx,e+n/2]),o||r.push([t,e+n/2]),r}qx.prototype={constructor:qx,render:function(t,e,i,n){var o=t.getModel("breadcrumb"),a=this.group;if(a.removeAll(),o.get("show")&&i){var r=o.getModel("itemStyle"),s=r.getModel("textStyle"),l={pos:{left:o.get("left"),right:o.get("right"),top:o.get("top"),bottom:o.get("bottom")},box:{width:e.getWidth(),height:e.getHeight()},emptyItemWidth:o.get("emptyItemWidth"),totalWidth:0,renderList:[]};this._prepare(i,l,s),this._renderContent(t,l,r,s,n),Su(a,l.pos,l.box)}},_prepare:function(t,e,i){for(var n=t;n;n=n.parentNode){var o=n.getModel().get("name"),a=i.getTextRect(o),r=Math.max(a.width+16,e.emptyItemWidth);e.totalWidth+=r+8,e.renderList.push({node:n,text:o,width:r})}},_renderContent:function(t,e,i,n,o){for(var a,r,s=0,l=e.emptyItemWidth,u=t.get("breadcrumb.height"),h=function(t,e,i){var n=e.width,o=e.height,a=El(t.x,n),r=El(t.y,o),s=El(t.x2,n),l=El(t.y2,o);return(isNaN(a)||isNaN(parseFloat(t.x)))&&(a=0),(isNaN(s)||isNaN(parseFloat(t.x2)))&&(s=n),(isNaN(r)||isNaN(parseFloat(t.y)))&&(r=0),(isNaN(l)||isNaN(parseFloat(t.y2)))&&(l=o),i=iu(i||0),{width:Math.max(s-a-i[1]-i[3],0),height:Math.max(l-r-i[0]-i[2],0)}}(e.pos,e.box),c=e.totalWidth,d=e.renderList,f=d.length-1;0<=f;f--){var p=d[f],g=p.node,m=p.width,v=p.text;c>h.width&&(c-=m-l,m=l,v=null);var y=new Qr({shape:{points:Kx(s,0,m,u,f===d.length-1,0===f)},style:D(i.getItemStyle(),{lineJoin:"bevel",text:v,textFill:n.getTextColor(),textFont:n.getFont()}),z:10,onclick:T(o,g)});this.group.add(y),a=t,r=g,y.eventData={componentType:"series",componentSubType:"treemap",componentIndex:a.componentIndex,seriesIndex:a.componentIndex,seriesName:a.name,seriesType:"treemap",selfType:"breadcrumb",nodeData:{dataIndex:r&&r.dataIndex,name:r&&r.name},treePathInfo:r&&Yx(r,a)},s+=m+8}},remove:function(){this.group.removeAll()}};function $x(t){var e=s_(t);return e.stroke=e.fill=e.lineWidth=null,e}var Jx=A,Qx=Ci,t_=rs,e_=R,i_=["label"],n_=["emphasis","label"],o_=["upperLabel"],a_=["emphasis","upperLabel"],r_=10,s_=ha([["fill","color"],["stroke","strokeColor"],["lineWidth","strokeWidth"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]);function l_(h,r,s,l,u,e,c,t,i,n){if(c){var d=c.getLayout(),o=h.getData();if(o.setItemGraphicEl(c.dataIndex,null),d&&d.isInView){var f=d.width,p=d.height,g=d.borderWidth,m=d.invisible,v=c.getRawIndex(),y=t&&t.getRawIndex(),a=c.viewChildren,x=d.upperHeight,_=a&&a.length,w=c.getModel("itemStyle"),b=c.getModel("emphasis.itemStyle"),S=L("nodeGroup",Qx);if(S){if(i.add(S),S.attr("position",[d.x||0,d.y||0]),S.__tmNodeWidth=f,S.__tmNodeHeight=p,d.isAboveViewRoot)return S;var M=c.getModel(),I=L("background",t_,n,1);if(I&&function(t,e,i){if(e.dataIndex=c.dataIndex,e.seriesIndex=h.seriesIndex,e.setShape({x:0,y:0,width:f,height:p}),m)A(e);else{e.invisible=!1;var n=c.getVisual("borderColor",!0),o=b.get("borderColor"),a=$x(w);a.fill=n;var r=s_(b);if(r.fill=o,i){var s=f-2*g;D(a,r,n,s,x,{x:g,y:0,width:s,height:x})}else a.text=r.text=null;e.setStyle(a),Us(e,r)}t.add(e)}(S,I,_&&d.upperLabelHeight),_)Qs(S)&&Js(S,!1),I&&(Js(I,!0),o.setItemGraphicEl(c.dataIndex,I));else{var T=L("content",t_,n,2);T&&function(t,e){e.dataIndex=c.dataIndex,e.seriesIndex=h.seriesIndex;var i=Math.max(f-2*g,0),n=Math.max(p-2*g,0);if(e.culling=!0,e.setShape({x:g,y:g,width:i,height:n}),m)A(e);else{e.invisible=!1;var o=c.getVisual("color",!0),a=$x(w);a.fill=o;var r=s_(b);D(a,r,o,i,n),e.setStyle(a),Us(e,r)}t.add(e)}(S,T),I&&Qs(I)&&Js(I,!1),Js(S,!0),o.setItemGraphicEl(c.dataIndex,S)}return S}}}function A(t){t.invisible||e.push(t)}function D(t,e,i,n,o,a){var r=M.get("name"),s=M.getModel(a?o_:i_),l=M.getModel(a?a_:n_),u=s.getShallow("show");el(t,e,s,l,{defaultText:u?r:null,autoColor:i,isRectText:!0,labelFetcher:h,labelDataIndex:c.dataIndex,labelProp:a?"upperLabel":"label"}),C(t,a,d),C(e,a,d),a&&(t.textRect=k(a)),t.truncate=u&&s.get("ellipsis")?{outerWidth:n,outerHeight:o,minChar:2}:null}function C(t,e,i){var n=t.text;if(!e&&i.isLeafRoot&&null!=n){var o=h.get("drillDownIcon",!0);t.text=o?o+" "+n:n}}function L(t,e,i,n){var o=null!=y&&s[t][y],a=u[t];return o?(s[t][y]=null,function(t,e,i){(t[v]={}).old="nodeGroup"===i?e.position.slice():P({},e.shape)}(a,o,t)):m||((o=new e({z:function(t,e){var i=t*r_+e;return(i-1)/i}(i,n)})).__tmDepth=i,function(t,e,i){var n=t[v]={},o=c.parentNode;if(o&&(!l||"drillDown"===l.direction)){var a=0,r=0,s=u.background[o.getRawIndex()];!l&&s&&s.old&&(a=s.old.width,r=s.old.height),n.old="nodeGroup"===i?[0,r]:{x:a,y:r,width:0,height:0}}n.fadein="nodeGroup"!==i}(a,0,o.__tmStorageName=t)),r[t][v]=o}}Cf({type:"treemap",init:function(t,e){this._containerGroup,this._storage={nodeGroup:[],background:[],content:[]},this._oldTree,this._breadcrumb,this._controller,this._state="ready"},render:function(t,e,i,n){if(!(_(e.findComponents({mainType:"series",subType:"treemap",query:n}),t)<0)){this.seriesModel=t,this.api=i,this.ecModel=e;var o=Zx(n,["treemapZoomToNode","treemapRootToNode"],t),a=n&&n.type,r=t.layoutInfo,s=!this._oldTree,l=this._storage,u="treemapRootToNode"===a&&o&&l?{rootNodeGroup:l.nodeGroup[o.node.getRawIndex()],direction:n.direction}:null,h=this._giveContainerGroup(r),c=this._doRender(h,t,u);s||a&&"treemapZoomToNode"!==a&&"treemapRootToNode"!==a?c.renderFinally():this._doAnimation(h,c,t,u),this._resetController(i),this._renderBreadcrumb(t,i,o)}},_giveContainerGroup:function(t){var e=this._containerGroup;return e||(e=this._containerGroup=new Qx,this._initEvents(e),this.group.add(e)),e.attr("position",[t.x,t.y]),e},_doRender:function(t,e,i){var n=e.getData().tree,o=this._oldTree,a={nodeGroup:[],background:[],content:[]},r={nodeGroup:[],background:[],content:[]},s=this._storage,l=[],c=T(l_,e,r,s,i,a,l);!function a(r,s,l,u,h){u?e_(s=r,function(t,e){t.isRemoved()||i(e,e)}):new kf(s,r,t,t).add(i).update(i).remove(T(i,null)).execute();function t(t){return t.getId()}function i(t,e){var i=null!=t?r[t]:null,n=null!=e?s[e]:null,o=c(i,n,l,h);o&&a(i&&i.viewChildren||[],n&&n.viewChildren||[],o,u,h+1)}}(n.root?[n.root]:[],o&&o.root?[o.root]:[],t,n===o||!o,0);var u,h,d=(h={nodeGroup:[],background:[],content:[]},(u=s)&&e_(u,function(t,e){var i=h[e];e_(t,function(t){t&&(i.push(t),t.__tmWillDelete=1)})}),h);return this._oldTree=n,this._storage=r,{lastsForAnimation:a,willDeleteEls:d,renderFinally:function(){e_(d,function(t){e_(t,function(t){t.parent&&t.parent.remove(t)})}),e_(l,function(t){t.invisible=!0,t.dirty()})}}},_doAnimation:function(t,a,e,s){if(e.get("animation")){var l=e.get("animationDurationUpdate"),u=e.get("animationEasing"),h=function(){var a,r=[],s={};return{add:function(t,e,i,n,o){return E(n)&&(o=n,n=0),!s[t.id]&&(s[t.id]=1,r.push({el:t,target:e,time:i,delay:n,easing:o}),!0)},done:function(t){return a=t,this},start:function(){for(var t=r.length,e=0,i=r.length;e=o.length||t===o[t.depth]){var i=E_(r,l,t,e,g,a);n(t,i,o,a)}})}else c=P_(l),t.setVisual("color",c)}(o,{},t.getViewRoot().getAncestors(),t)}};function k_(i,n,t){var o=P({},n),a=t.designatedVisualItemStyle;return R(["color","colorAlpha","colorSaturation"],function(t){a[t]=n[t];var e=i.get(t);(a[t]=null)!=e&&(o[t]=e)}),o}function P_(t){var e=N_(t,"color");if(e){var i=N_(t,"colorAlpha"),n=N_(t,"colorSaturation");return n&&(e=qe(e,null,null,n)),i&&(e=Ke(e,i)),e}}function N_(t,e){var i=t[e];if(null!=i&&"none"!==i)return i}function O_(t,e,i,n,o,a){if(a&&a.length){var r=R_(e,"color")||null!=o.color&&"none"!==o.color&&(R_(e,"colorAlpha")||R_(e,"colorSaturation"));if(r){var s=e.get("visualMin"),l=e.get("visualMax"),u=i.dataExtent.slice();null!=s&&su[1]&&(u[1]=l);var h=e.get("colorMappingBy"),c={type:r.name,dataExtent:u,visual:r.range};"color"!==c.type||"index"!==h&&"id"!==h?c.mappingMethod="linear":(c.mappingMethod="category",c.loop=!0);var d=new g_(c);return d.__drColorMappingBy=h,d}}}function R_(t,e){var i=t.get(e);return D_(i)&&i.length?{name:e,range:i}:null}function E_(t,e,i,n,o,a){var r=P({},e);if(o){var s=o.type,l="color"===s&&o.__drColorMappingBy,u="index"===l?n:"id"===l?a.mapIdToIndex(i.getId()):i.getValue(t.get("visualDimension"));r[s]=o.mapValueToVisual(u)}return r}var z_=Math.max,B_=Math.min,V_=W,G_=R,F_=["itemStyle","borderWidth"],W_=["itemStyle","gapWidth"],H_=["upperLabel","show"],Z_=["upperLabel","height"],U_={seriesType:"treemap",reset:function(t,e,i,n){var o=i.getWidth(),a=i.getHeight(),r=t.option,s=bu(t.getBoxLayoutParams(),{width:i.getWidth(),height:i.getHeight()}),l=r.size||[],u=El(V_(s.width,l[0]),o),h=El(V_(s.height,l[1]),a),c=n&&n.type,d=Zx(n,["treemapZoomToNode","treemapRootToNode"],t),f="treemapRender"===c||"treemapMove"===c?n.rootRect:null,p=t.getViewRoot(),g=Ux(p);if("treemapMove"!==c){var m="treemapZoomToNode"===c?function(t,e,i,n,o){var a,r=(e||{}).node,s=[n,o];if(!r||r===i)return s;var l=n*o,u=l*t.option.zoomToNodeRatio;for(;a=r.parentNode;){for(var h=0,c=a.children,d=0,f=c.length;ds[1]&&(s[1]=e)})}else s=[NaN,NaN];return{sum:n,dataExtent:s}}(e,r,s);if(0===u.sum)return t.viewChildren=[];if(u.sum=function(t,e,i,n,o){if(!n)return i;for(var a=t.get("visibleMin"),r=o.length,s=r,l=r-1;0<=l;l--){var u=o["asc"===n?r-l-1:l].getValue();u/i*ei[l[r]])&&(h=i[l[r]]);for(var c=0,d=t.length;c "+d)),u++)}var f,p=i.get("coordinateSystem");if("cartesian2d"===p||"polar"===p)f=gp(t,i);else{var g=lh.get(p),m=g&&"view"!==g.type&&g.dimensions||[];_(m,"value")<0&&m.concat(["value"]);var v=lp(t,{coordDimensions:m});(f=new Yf(v,i)).initData(t)}var y=new Yf(["value"],i);return y.initData(l,s),o&&o(f,y),yx({mainData:f,struct:a,structAttr:"graph",datas:{node:f,edge:y},datasAttr:{node:"data",edge:"edgeData"}}),a.update(),a}var nw="--\x3e",ow=function(t){return t.get("autoCurveness")||null},aw=function(t,e){var i=ow(t),n=20,o=[];if("number"==typeof i)n=i;else if(L(i))return void(t.__curvenessList=i);n ")),o.value&&(l+=" : "+au(o.value)),l},_updateCategoriesData:function(){var t=O(this.option.categories||[],function(t){return null!=t.value?t:P({value:0},t)}),e=new Yf(["value"],this);e.initData(t),this._categoriesData=e,this._categoriesModels=e.mapArray(function(t){return e.getItemModel(t,!0)})},setZoom:function(t){this.option.zoom=t},setCenter:function(t){this.option.center=t},isAnimationEnabled:function(){return dw.superCall(this,"isAnimationEnabled")&&!("force"===this.get("layout")&&this.get("force.layoutAnimation"))},defaultOption:{zlevel:0,z:2,coordinateSystem:"view",legendHoverLink:!0,hoverAnimation:!0,layout:null,focusNodeAdjacency:!1,circular:{rotateLabel:!1},force:{initLayout:null,repulsion:[0,50],gravity:.1,friction:.6,edgeLength:30,layoutAnimation:!0},left:"center",top:"center",symbol:"circle",symbolSize:10,edgeSymbol:["none","none"],edgeSymbolSize:10,edgeLabel:{position:"middle",distance:5},draggable:!1,roam:!1,center:null,zoom:1,nodeScaleRatio:.6,label:{show:!1,formatter:"{b}"},itemStyle:{},lineStyle:{color:"#aaa",width:1,opacity:.5},emphasis:{label:{show:!0}}}}),fw=ls.prototype,pw=ds.prototype;function gw(t){return isNaN(+t.cpx1)||isNaN(+t.cpy1)}var mw=Cs({type:"ec-line",style:{stroke:"#000",fill:null},shape:{x1:0,y1:0,x2:0,y2:0,percent:1,cpx1:null,cpy1:null},buildPath:function(t,e){this[gw(e)?"_buildPathLine":"_buildPathCurve"](t,e)},_buildPathLine:fw.buildPath,_buildPathCurve:pw.buildPath,pointAt:function(t){return this[gw(this.shape)?"_pointAtLine":"_pointAtCurve"](t)},_pointAtLine:fw.pointAt,_pointAtCurve:pw.pointAt,tangentAt:function(t){var e=this.shape,i=gw(e)?[e.x2-e.x1,e.y2-e.y1]:this._tangentAtCurve(t);return mt(i,i)},_tangentAtCurve:pw.tangentAt}),vw=["fromSymbol","toSymbol"];function yw(t){return"_"+t+"Type"}function xw(t,e,i){var n=e.getItemVisual(i,t);if(n&&"none"!==n){var o=e.getItemVisual(i,"color"),a=e.getItemVisual(i,t+"Size"),r=e.getItemVisual(i,t+"Rotate");L(a)||(a=[a,a]);var s=wg(n,-a[0]/2,-a[1]/2,a[0],a[1],o);return s.__specifiedRotation=null==r||isNaN(r)?void 0:+r*Math.PI/180||0,s.name=t,s}}function _w(t,e){t.x1=e[0][0],t.y1=e[0][1],t.x2=e[1][0],t.y2=e[1][1],t.percent=1;var i=e[2];i?(t.cpx1=i[0],t.cpy1=i[1]):(t.cpx1=NaN,t.cpy1=NaN)}function ww(t,e,i){Ci.call(this),this._createLine(t,e,i)}var bw=ww.prototype;function Sw(t){this._ctor=t||ww,this.group=new Ci}bw.beforeUpdate=function(){var t=this.childOfName("fromSymbol"),e=this.childOfName("toSymbol"),i=this.childOfName("label");if(t||e||!i.ignore){for(var n=1,o=this.parent;o;)o.scale&&(n/=o.scale[0]),o=o.parent;var a=this.childOfName("line");if(this.__dirty||a.__dirty){var r=a.shape.percent,s=a.pointAt(0),l=a.pointAt(r),u=ht([],l,s);if(mt(u,u),t){if(t.attr("position",s),null==(c=t.__specifiedRotation)){var h=a.tangentAt(0);t.attr("rotation",Math.PI/2-Math.atan2(h[1],h[0]))}else t.attr("rotation",c);t.attr("scale",[n*r,n*r])}if(e){var c;if(e.attr("position",l),null==(c=e.__specifiedRotation)){h=a.tangentAt(1);e.attr("rotation",-Math.PI/2-Math.atan2(h[1],h[0]))}else e.attr("rotation",c);e.attr("scale",[n*r,n*r])}if(!i.ignore){var d,f,p,g;i.attr("position",l);var m=i.__labelDistance,v=m[0]*n,y=m[1]*n,x=r/2,_=[(h=a.tangentAt(x))[1],-h[0]],w=a.pointAt(x);0<_[1]&&(_[0]=-_[0],_[1]=-_[1]);var b,S=h[0]<0?-1:1;if("start"!==i.__position&&"end"!==i.__position){var M=-Math.atan2(h[1],h[0]);l[0]=t&&(0===e?0:n[e-1][0])a&&(e[1-n]=e[n]+c.sign*a),e}function lb(t,e){var i=t[e]-t[1-e];return{span:Math.abs(i),sign:0o*(1-h[0])?(l="jump",r=s-o*(1-h[2])):0<=(r=s-o*h[1])&&(r=s-o*(1-h[1]))<=0&&(r=0),(r*=e.axisExpandWidth/u)?sb(r,n,a,"all"):l="none";else{o=n[1]-n[0];(n=[db(0,a[1]*s/o-o/2)])[1]=cb(a[1],n[0]+o),n[0]=n[1]-o}return{axisExpandWindow:n,behavior:l}}},lh.register("parallel",{create:function(n,o){var a=[];return n.eachComponent("parallel",function(t,e){var i=new vb(t,n,o);i.name="parallel_"+e,i.resize(t,o),(t.coordinateSystem=i).model=t,a.push(i)}),n.eachSeries(function(t){if("parallel"===t.get("coordinateSystem")){var e=n.queryComponents({mainType:"parallel",index:t.get("parallelIndex"),id:t.get("parallelId")})[0];t.coordinateSystem=e.coordinateSystem}}),a}});var xb=ku.extend({type:"baseParallelAxis",axis:null,activeIntervals:[],getAreaSelectStyle:function(){return ha([["fill","color"],["lineWidth","borderWidth"],["stroke","borderColor"],["width","width"],["opacity","opacity"]])(this.getModel("areaSelectStyle"))},setActiveIntervals:function(t){var e=this.activeIntervals=k(t);if(e)for(var i=e.length-1;0<=i;i--)Bl(e[i])},getActiveState:function(t){var e=this.activeIntervals;if(!e.length)return"normal";if(null==t||isNaN(t))return"inactive";if(1===e.length){var i=e[0];if(i[0]<=t&&t<=i[1])return"active"}else for(var n=0,o=e.length;nn.getWidth()||i<0||i>n.getHeight()}(t,e)){var n=t._zr,o=t._covers,a=Fb(t,e,i);if(!t._dragging)for(var r=0;rf&&(f=m.depth),g.setLayout({depth:v?m.depth:c},!0),"vertical"===a?g.setLayout({dy:i},!0):g.setLayout({dx:i},!0);for(var y=0;y "))},preventIncremental:function(){return!!this.get("effect.show")},getProgressive:function(){var t=this.option.progressive;return null==t?this.option.large?1e4:this.get("progressive"):t},getProgressiveThreshold:function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?2e4:this.get("progressiveThreshold"):t},defaultOption:{coordinateSystem:"geo",zlevel:0,z:2,legendHoverLink:!0,hoverAnimation:!0,xAxisIndex:0,yAxisIndex:0,symbol:["none","none"],symbolSize:[10,10],geoIndex:0,effect:{show:!1,period:4,constantSpeed:0,symbol:"circle",symbolSize:3,loop:!0,trailLength:.2},large:!1,largeThreshold:2e3,polyline:!1,clip:!0,label:{show:!1,position:"end"},lineStyle:{opacity:.5}}});function bM(t,e,i){Ci.call(this),this.add(this.createLine(t,e,i)),this._updateEffectSymbol(t,e)}var SM=bM.prototype;function MM(t,e,i){Ci.call(this),this._createPolyline(t,e,i)}SM.createLine=function(t,e,i){return new ww(t,e,i)},SM._updateEffectSymbol=function(t,e){var i=t.getItemModel(e).getModel("effect"),n=i.get("symbolSize"),o=i.get("symbol");L(n)||(n=[n,n]);var a=i.get("color")||t.getItemVisual(e,"color"),r=this.childAt(1);this._symbolType!==o&&(this.remove(r),(r=wg(o,-.5,-.5,1,1,a)).z2=100,r.culling=!0,this.add(r)),r&&(r.setStyle("shadowColor",a),r.setStyle(i.getItemStyle(["color"])),r.attr("scale",n),r.setColor(a),r.attr("scale",n),this._symbolType=o,this._symbolScale=n,this._updateEffectAnimation(t,i,e))},SM._updateEffectAnimation=function(e,t,i){var n=this.childAt(1);if(n){var o=this,a=e.getItemLayout(i),r=1e3*t.get("period"),s=t.get("loop"),l=t.get("constantSpeed"),u=W(t.get("delay"),function(t){return t/e.count()*r/3}),h="function"==typeof u;if(n.ignore=!0,this.updateAnimationPoints(n,a),0e);r++);r=Math.min(r-1,o-2)}wt(t.position,i[r],i[r+1],(e-n[r])/(n[r+1]-n[r]));var s=i[r+1][0]-i[r][0],l=i[r+1][1]-i[r][1];t.rotation=-Math.atan2(l,s)-Math.PI/2,this._lastFrame=r,this._lastFramePercent=e,t.ignore=!1}},w(TM,bM);var DM=Cs({shape:{polyline:!1,curveness:0,segs:[]},buildPath:function(t,e){var i=e.segs,n=e.curveness;if(e.polyline)for(var o=0;o=e[0]&&t<=e[1]}}(y,e.option.range):function(e,n,o){var i=e[1]-e[0],a=(n=O(n,function(t){return{interval:[(t.interval[0]-e[0])/i,(t.interval[1]-e[0])/i]}})).length,r=0;return function(t){for(var e=r;e=e.y&&t[1]<=e.y+e.height:i.contain(i.toLocalCoord(t[1]))&&t[0]>=e.y&&t[0]<=e.y+e.height},pointToData:function(t){var e=this.getAxis();return[e.coordToData(e.toLocalCoord(t["horizontal"===e.orient?0:1]))]},dataToPoint:function(t){var e=this.getAxis(),i=this.getRect(),n=[],o="horizontal"===e.orient?0:1;return t instanceof Array&&(t=t[0]),n[o]=e.toGlobalCoord(e.dataToCoord(+t)),n[1-o]=0==o?i.y+i.height/2:i.x+i.width/2,n}}).dimensions});var sI=["axisLine","axisTickLabel","axisName"],lI=["splitArea","splitLine"],uI=mv.extend({type:"singleAxis",axisPointerClass:"SingleAxisPointer",render:function(e,t,i,n){var o=this.group;o.removeAll();var a=this._axisGroup;this._axisGroup=new Ci;var r=rI(e),s=new Qm(e,r);R(sI,s.add,s),o.add(this._axisGroup),o.add(s.getGroup()),R(lI,function(t){e.get(t+".show")&&this["_"+t](e)},this),ml(a,this._axisGroup,e),uI.superCall(this,"render",e,t,i,n)},remove:function(){bv(this)},_splitLine:function(t){var e=t.axis;if(!e.scale.isBlank()){var i=t.getModel("splitLine"),n=i.getModel("lineStyle"),o=n.get("width"),a=n.get("color");a=a instanceof Array?a:[a];for(var r=t.coordinateSystem.getRect(),s=e.isHorizontal(),l=[],u=0,h=e.getTicksCoords({tickModel:i}),c=[],d=[],f=0;fr)return!0;if(a){var s=fv(t).seriesDataCount,l=n.getExtent();return Math.abs(l[0]-l[1])/s>r}return!1},makeElOption:function(t,e,i,n,o){},createPointerEl:function(t,e,i,n){var o=e.pointer;if(o){var a=AI(t).pointerEl=new bl[o.type](DI(e.pointer));t.add(a)}},createLabelEl:function(t,e,i,n){if(e.label){var o=AI(t).labelEl=new rs(DI(e.label));t.add(o),PI(o,n)}},updatePointerEl:function(t,e,i){var n=AI(t).pointerEl;n&&e.pointer&&(n.setStyle(e.pointer.style),i(n,{shape:e.pointer.shape}))},updateLabelEl:function(t,e,i,n){var o=AI(t).labelEl;o&&(o.setStyle(e.label.style),i(o,{shape:e.label.shape,position:e.label.position}),PI(o,n))},_renderHandle:function(t){if(!this._dragging&&this.updateHandleTransform){var e,i=this._axisPointerModel,n=this._api.getZr(),o=this._handle,a=i.getModel("handle"),r=i.get("status");if(!a.get("show")||!r||"hide"===r)return o&&n.remove(o),void(this._handle=null);this._handle||(e=!0,o=this._handle=yl(a.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){Xt(t.event)},onmousedown:CI(this._onHandleDragMove,this,0,0),drift:CI(this._onHandleDragMove,this),ondragend:CI(this._onHandleDragEnd,this)}),n.add(o)),OI(o,i,!1);o.setStyle(a.getItemStyle(null,["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"]));var s=a.get("size");L(s)||(s=[s,s]),o.attr("scale",[s[0]/2,s[1]/2]),kc(this,"_doDispatchAxisPointer",a.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,e)}},_moveHandleToValue:function(t,e){kI(this._axisPointerModel,!e&&this._moveAnimation,this._handle,NI(this.getHandleTransform(t,this._axisModel,this._axisPointerModel)))},_onHandleDragMove:function(t,e){var i=this._handle;if(i){this._dragging=!0;var n=this.updateHandleTransform(NI(i),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=n,i.stopAnimation(),i.attr(NI(n)),AI(i).lastProp=null,this._doDispatchAxisPointer()}},_doDispatchAxisPointer:function(){if(this._handle){var t=this._payloadInfo,e=this._axisModel;this._api.dispatchAction({type:"updateAxisPointer",x:t.cursorPoint[0],y:t.cursorPoint[1],tooltipOption:t.tooltipOption,axesInfo:[{axisDim:e.axis.dim,axisIndex:e.componentIndex}]})}},_onHandleDragEnd:function(t){if(this._dragging=!1,this._handle){var e=this._axisPointerModel.get("value");this._moveHandleToValue(e),this._api.dispatchAction({type:"hideTip"})}},getHandleTransform:null,updateHandleTransform:null,clear:function(t){this._lastValue=null,this._lastStatus=null;var e=t.getZr(),i=this._group,n=this._handle;e&&i&&(this._lastGraphicKey=null,i&&e.remove(i),n&&e.remove(n),this._group=null,this._handle=null,this._payloadInfo=null)},doClear:function(){},buildLabel:function(t,e,i){return{x:t[i=i||0],y:t[1-i],width:e[i],height:e[1-i]}}}).constructor=LI);var HI=LI.extend({makeElOption:function(t,e,i,n,o){var a=i.axis,r=a.grid,s=n.get("type"),l=ZI(r,a).getOtherAxis(a).getGlobalExtent(),u=a.toGlobalCoord(a.dataToCoord(e,!0));if(s&&"none"!==s){var h=RI(n),c=UI[s](a,u,l);c.style=h,t.graphicKey=c.type,t.pointer=c}VI(e,t,_v(r.model,i),i,n,o)},getHandleTransform:function(t,e,i){var n=_v(e.axis.grid.model,e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:BI(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i,n){var o=i.axis,a=o.grid,r=o.getGlobalExtent(!0),s=ZI(a,o).getOtherAxis(o).getGlobalExtent(),l="x"===o.dim?0:1,u=t.position;u[l]+=e[l],u[l]=Math.min(r[1],u[l]),u[l]=Math.max(r[0],u[l]);var h=(s[1]+s[0])/2,c=[h,h];c[l]=u[l];return{position:u,rotation:t.rotation,cursorPoint:c,tooltipOption:[{verticalAlign:"middle"},{align:"center"}][l]}}});function ZI(t,e){var i={};return i[e.dim+"AxisIndex"]=e.index,t.getCartesian(i)}var UI={line:function(t,e,i){return{type:"Line",subPixelOptimize:!0,shape:GI([e,i[0]],[e,i[1]],XI(t))}},shadow:function(t,e,i){var n=Math.max(1,t.getBandWidth()),o=i[1]-i[0];return{type:"Rect",shape:FI([e-n/2,i[0]],[n,o],XI(t))}}};function XI(t){return"x"===t.dim?0:1}mv.registerAxisPointerClass("CartesianAxisPointer",HI),yf(function(t){if(t){t.axisPointer&&0!==t.axisPointer.length||(t.axisPointer={});var e=t.axisPointer.link;e&&!L(e)&&(t.axisPointer.link=[e])}}),xf(Ld.PROCESSOR.STATISTIC,function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=cv(t,e)}),_f({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},function(t,e,i){var n=t.currTrigger,r=[t.x,t.y],o=t,a=t.dispatchAction||A(i.dispatchAction,i),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){xI(r)&&(r=cI({seriesIndex:o.seriesIndex,dataIndex:o.dataIndex},e).point);var l=xI(r),u=o.axesInfo,h=s.axesInfo,c="leave"===n||xI(r),d={},f={},p={list:[],map:{}},g={showPointer:fI(mI,f),showTooltip:fI(vI,p)};dI(s.coordSysMap,function(t,e){var a=l||t.containPoint(r);dI(s.coordSysAxesInfo[e],function(t,e){var i=t.axis,n=function(t,e){for(var i=0;i<(t||[]).length;i++){var n=t[i];if(e.axis.dim===n.axisDim&&e.axis.model.componentIndex===n.axisIndex)return n}}(u,t);if(!c&&a&&(!u||n)){var o=n&&n.value;null!=o||l||(o=i.pointToData(r)),null!=o&&gI(t,o,g,!1,d)}})});var m={};return dI(h,function(o,t){var a=o.linkGroup;a&&!f[t]&&dI(a.axesInfo,function(t,e){var i=f[e];if(t!==o&&i){var n=i.value;a.mapper&&(n=o.axis.scale.parse(a.mapper(n,yI(t),yI(o)))),m[o.key]=n}})}),dI(m,function(t,e){gI(h[e],t,g,!0,d)}),function(o,t,e){var a=e.axesInfo=[];dI(t,function(t,e){var i=t.axisPointerModel.option,n=o[e];n?(t.useHandle||(i.status="show"),i.value=n.value,i.seriesDataIndices=(n.payloadBatch||[]).slice()):t.useHandle||(i.status="hide"),"show"===i.status&&a.push({axisDim:t.axis.dim,axisIndex:t.axis.model.componentIndex,value:i.value})})}(f,h,d),function(t,e,i,n){if(xI(e)||!t.list.length)return n({type:"hideTip"});var o=((t.list[0].dataByAxis[0]||{}).seriesDataIndices||[])[0]||{};n({type:"showTip",escapeConnect:!0,x:e[0],y:e[1],tooltipOption:i.tooltipOption,position:i.position,dataIndexInside:o.dataIndexInside,dataIndex:o.dataIndex,seriesIndex:o.seriesIndex,dataByCoordSys:t.list})}(p,r,t,a),function(t,e,i){var n=i.getZr(),o="axisPointerLastHighlights",a=pI(n)[o]||{},r=pI(n)[o]={};dI(t,function(t,e){var i=t.axisPointerModel.option;"show"===i.status&&dI(i.seriesDataIndices,function(t){var e=t.seriesIndex+" | "+t.dataIndex;r[e]=t})});var s=[],l=[];R(a,function(t,e){r[e]||l.push(t)}),R(r,function(t,e){a[e]||s.push(t)}),l.length&&i.dispatchAction({type:"downplay",escapeConnect:!0,batch:l}),s.length&&i.dispatchAction({type:"highlight",escapeConnect:!0,batch:s})}(h,0,i),d}});var YI=["x","y"],jI=["width","height"],qI=LI.extend({makeElOption:function(t,e,i,n,o){var a=i.axis,r=a.coordinateSystem,s=JI(r,1-$I(a)),l=r.dataToPoint(e)[0],u=n.get("type");if(u&&"none"!==u){var h=RI(n),c=KI[u](a,l,s);c.style=h,t.graphicKey=c.type,t.pointer=c}VI(e,t,rI(i),i,n,o)},getHandleTransform:function(t,e,i){var n=rI(e,{labelInside:!1});return n.labelMargin=i.get("handle.margin"),{position:BI(e.axis,t,n),rotation:n.rotation+(n.labelDirection<0?Math.PI:0)}},updateHandleTransform:function(t,e,i,n){var o=i.axis,a=o.coordinateSystem,r=$I(o),s=JI(a,r),l=t.position;l[r]+=e[r],l[r]=Math.min(s[1],l[r]),l[r]=Math.max(s[0],l[r]);var u=JI(a,1-r),h=(u[1]+u[0])/2,c=[h,h];return c[r]=l[r],{position:l,rotation:t.rotation,cursorPoint:c,tooltipOption:{verticalAlign:"middle"}}}}),KI={line:function(t,e,i){return{type:"Line",subPixelOptimize:!0,shape:GI([e,i[0]],[e,i[1]],$I(t))}},shadow:function(t,e,i){var n=t.getBandWidth(),o=i[1]-i[0];return{type:"Rect",shape:FI([e-n/2,i[0]],[n,o],$I(t))}}};function $I(t){return t.isHorizontal()?0:1}function JI(t,e){var i=t.getRect();return[i[YI[e]],i[YI[e]]+i[jI[e]]]}mv.registerAxisPointerClass("SingleAxisPointer",qI),Af({type:"single"});var QI=sc.extend({type:"series.themeRiver",dependencies:["singleAxis"],nameMap:null,init:function(t){QI.superApply(this,"init",arguments),this.legendVisualProvider=new qv(A(this.getData,this),A(this.getRawData,this))},fixData:function(t){var e=t.length,i={},n=ta(t,function(t){return i.hasOwnProperty(t[0])||(i[t[0]]=-1),t[2]}),o=[];n.buckets.each(function(t,e){o.push({name:e,dataList:t})});for(var a=o.length,r=0;rMath.PI/2?"right":"left"):x&&"center"!==x?"left"===x?(f=u.r0+y,p>Math.PI/2&&(x="right")):"right"===x&&(f=u.r-y,p>Math.PI/2&&(x="left")):(f=(u.r+u.r0)/2,x="center"),d.attr("style",{text:l,textAlign:x,textVerticalAlign:M("verticalAlign")||"middle",opacity:M("opacity")});var _=f*g+u.cx,w=f*m+u.cy;d.attr("position",[_,w]);var b=M("rotate"),S=0;function M(t){var e=a.get(t);return null==e?o.get(t):e}"radial"===b?(S=-p)<-Math.PI/2&&(S+=Math.PI):"tangential"===b?(S=Math.PI/2-p)>Math.PI/2?S-=Math.PI:S<-Math.PI/2&&(S+=Math.PI):"number"==typeof b&&(S=b*Math.PI/180),d.attr("rotation",S)},sT._initEvents=function(t,e,i,n){t.off("mouseover").off("mouseout").off("emphasis").off("normal");function o(){r.onEmphasis(n)}function a(){r.onNormal()}var r=this;i.isAnimationEnabled()&&t.on("mouseover",o).on("mouseout",a).on("emphasis",o).on("normal",a).on("downplay",function(){r.onDownplay()}).on("highlight",function(){r.onHighlight()})},w(rT,Ci);_c.extend({type:"sunburst",init:function(){},render:function(o,a,t,e){var n=this;this.seriesModel=o,this.api=t,this.ecModel=a;var r=o.getData(),s=r.tree.root,i=o.getViewRoot(),l=this.group,u=o.get("renderLabelForZeroData"),h=[];i.eachNode(function(t){h.push(t)});var c=this._oldChildren||[];if(function(i,n){if(0===i.length&&0===n.length)return;function t(t){return t.getId()}function e(t,e){!function(t,e){u||!t||t.getValue()||(t=null);if(t!==s&&e!==s)if(e&&e.piece)t?(e.piece.updateData(!1,t,"normal",o,a),r.setItemGraphicEl(t.dataIndex,e.piece)):function(t){if(!t)return;t.piece&&(l.remove(t.piece),t.piece=null)}(e);else if(t){var i=new rT(t,o,a);l.add(i),r.setItemGraphicEl(t.dataIndex,i)}}(null==t?null:i[t],null==e?null:n[e])}new kf(n,i,t,t).add(e).update(e).remove(T(e,null)).execute()}(h,c),function(t,e){if(0=i.r0}}});var lT="sunburstRootToNode";_f({type:lT,update:"updateView"},function(o,t){t.eachComponent({mainType:"series",subType:"sunburst",query:o},function(t,e){var i=Zx(o,[lT],t);if(i){var n=t.getViewRoot();n&&(o.direction=Xx(n,i.node)?"rollUp":"drillDown"),t.resetViewRoot(i.node)}})});var uT="sunburstHighlight";_f({type:uT,update:"updateView"},function(n,t){t.eachComponent({mainType:"series",subType:"sunburst",query:n},function(t,e){var i=Zx(n,[uT],t);i&&(n.highlight=i.node)})});_f({type:"sunburstUnhighlight",update:"updateView"},function(i,t){t.eachComponent({mainType:"series",subType:"sunburst",query:i},function(t,e){i.unhighlight=!0})});var hT=Math.PI/180;function cT(t,e){if("function"==typeof e)return t.sort(e);var n="asc"===e;return t.sort(function(t,e){var i=(t.getValue()-e.getValue())*(n?1:-1);return 0==i?(t.dataIndex-e.dataIndex)*(n?-1:1):i})}function dT(a,r){return r=r||[0,0],O(["x","y"],function(t,e){var i=this.getAxis(t),n=r[e],o=a[e]/2;return"category"===i.type?i.getBandWidth():Math.abs(i.dataToCoord(n-o)-i.dataToCoord(n+o))},this)}Sf(T(iy,"sunburst")),bf(T(function(t,e,C,i){e.eachSeriesByType(t,function(t){var e=t.get("center"),i=t.get("radius");L(i)||(i=[0,i]),L(e)||(e=[e,e]);var n=C.getWidth(),o=C.getHeight(),h=Math.min(n,o),c=El(e[0],n),d=El(e[1],o),f=El(i[0],h/2),a=El(i[1],h/2),r=-t.get("startAngle")*hT,p=t.get("minAngle")*hT,g=t.getData().tree.root,s=t.getViewRoot(),m=s.depth,l=t.get("sort");null!=l&&!function e(t,i){var n=t.children||[];t.children=cT(n,i);n.length&&R(t.children,function(t){e(t,i)})}(s,l);var u=0;R(s.children,function(t){isNaN(t.getValue())||u++});var v=s.getValue(),y=Math.PI/(v||u)*2,x=0t[1]&&t.reverse(),{coordSys:{type:"polar",cx:o.cx,cy:o.cy,r:t[1],r0:t[0]},api:{coord:A(function(t){var e=a.dataToRadius(t[0]),i=r.dataToAngle(t[1]),n=o.coordToPoint([e,i]);return n.push(e,i*Math.PI/180),n}),size:A(gT,o)}}},calendar:function(i){var t=i.getRect(),e=i.getRangeInfo();return{coordSys:{type:"calendar",x:t.x,y:t.y,width:t.width,height:t.height,cellWidth:i.getCellWidth(),cellHeight:i.getCellHeight(),rangeInfo:{start:e.start,end:e.end,weeks:e.weeks,dayCount:e.allDay}},api:{coord:function(t,e){return i.dataToPoint(t,e)}}}}};function ST(t,e,i,n,o){null==i[t]||o||(e[t]=i[t],i[t]=n[t])}function MT(a,r,e,t){var i=a.get("renderItem"),n=a.coordinateSystem,o={};n&&(o=n.prepareCustoms?n.prepareCustoms():bT[n.type](n));var s,l,u,h,c,d=D({getWidth:t.getWidth,getHeight:t.getHeight,getZr:t.getZr,getDevicePixelRatio:t.getDevicePixelRatio,value:function(t,e){return null==e&&(e=s),r.get(r.getDimension(t||0),e)},style:function(t,e){null==e&&(e=s),g(e);var i=l.getModel(vT).getItemStyle();null!=c&&(i.fill=c);var n=r.getItemVisual(e,"opacity");null!=n&&(i.opacity=n);var o=t?CT(t,u):u;return nl(i,o,null,{autoColor:c,isRectText:!0}),i.text=o.getShallow("show")?H(a.getFormattedLabel(e,"normal"),Ug(r,e)):null,t&<(i,t),i},styleEmphasis:function(t,e){null==e&&(e=s),g(e);var i=l.getModel(yT).getItemStyle(),n=t?CT(t,h):h;return nl(i,n,null,{isRectText:!0},!0),i.text=n.getShallow("show")?Z(a.getFormattedLabel(e,"emphasis"),a.getFormattedLabel(e,"normal"),Ug(r,e)):null,t&<(i,t),i},visual:function(t,e){return null==e&&(e=s),r.getItemVisual(e,t)},barLayout:function(t){if(n.getBaseAxis){return function(t){var e=[],i=t.axis;if("category"===i.type){for(var n=i.getBandWidth(),o=0;oe[1]&&e.reverse();var i=t.getExtent(),n=Math.PI/180;return{cx:this.cx,cy:this.cy,r0:e[0],r:e[1],startAngle:-i[0]*n,endAngle:-i[1]*n,clockwise:t.inverse,contain:function(t,e){var i=t-this.cx,n=e-this.cy,o=i*i+n*n,a=this.r,r=this.r0;return o<=a*a&&r*r<=o}}}};var GT=ku.extend({type:"polarAxis",axis:null,getCoordSysModel:function(){return this.ecModel.queryComponents({mainType:"polar",index:this.option.polarIndex,id:this.option.polarId})[0]}});m(GT.prototype,dg);var FT={splitNumber:5};function WT(t,e){return e.type||(e.data?"category":"value")}function HT(t,e){var i=this,n=i.getAngleAxis(),o=i.getRadiusAxis();if(n.scale.setExtent(1/0,-1/0),o.scale.setExtent(1/0,-1/0),t.eachSeries(function(t){if(t.coordinateSystem===i){var e=t.getData();R(e.mapDimension("radius",!0),function(t){o.scale.unionExtentFromData(e,pp(e,t))}),R(e.mapDimension("angle",!0),function(t){n.scale.unionExtentFromData(e,pp(e,t))})}}),rg(n.scale,n.model),rg(o.scale,o.model),"category"===n.type&&!n.onBand){var a=n.getExtent(),r=360/n.scale.count();n.inverse?a[1]+=r:a[1]-=r,n.setExtent(a[0],a[1])}}function ZT(t,e){if(t.type=e.get("type"),t.scale=sg(e),t.onBand=e.get("boundaryGap")&&"category"===t.type,t.inverse=e.get("inverse"),"angleAxis"===e.mainType){t.inverse^=e.get("clockwise");var i=e.get("startAngle");t.setExtent(i,i+(t.inverse?-360:360))}(e.axis=t).model=e}Gm("angle",GT,WT,{startAngle:90,clockwise:!0,splitNumber:12,axisLabel:{rotate:!1}}),Gm("radius",GT,WT,FT),Tf({type:"polar",dependencies:["polarAxis","angleAxis"],coordinateSystem:null,findAxisModel:function(t){var e;return this.ecModel.eachComponent(t,function(t){t.getCoordSysModel()===this&&(e=t)},this),e},defaultOption:{zlevel:0,z:0,center:["50%","50%"],radius:"80%"}}),lh.register("polar",{dimensions:VT.prototype.dimensions,create:function(i,s){var l=[];return i.eachComponent("polar",function(t,e){var i=new VT(e);i.update=HT;var n=i.getRadiusAxis(),o=i.getAngleAxis(),a=t.findAxisModel("radiusAxis"),r=t.findAxisModel("angleAxis");ZT(n,a),ZT(o,r),function(t,e,i){var n=e.get("center"),o=i.getWidth(),a=i.getHeight();t.cx=El(n[0],o),t.cy=El(n[1],a);var r=t.getRadiusAxis(),s=Math.min(o,a)/2,l=e.get("radius");null==l?l=[0,"100%"]:L(l)||(l=[0,l]),l=[El(l[0],s),El(l[1],s)],r.inverse?r.setExtent(l[1],l[0]):r.setExtent(l[0],l[1])}(i,t,s),l.push(i),(t.coordinateSystem=i).model=t}),i.eachSeries(function(t){if("polar"===t.get("coordinateSystem")){var e=i.queryComponents({mainType:"polar",index:t.get("polarIndex"),id:t.get("polarId")})[0];t.coordinateSystem=e.coordinateSystem}}),l}});var UT=["axisLine","axisLabel","axisTick","minorTick","splitLine","minorSplitLine","splitArea"];function XT(t,e,i){e[1]>e[0]&&(e=e.slice().reverse());var n=t.coordToPoint([e[0],i]),o=t.coordToPoint([e[1],i]);return{x1:n[0],y1:n[1],x2:o[0],y2:o[1]}}function YT(t){return t.getRadiusAxis().inverse?0:1}function jT(t){var e=t[0],i=t[t.length-1];e&&i&&Math.abs(Math.abs(e.coord-i.coord)-360)<1e-4&&t.pop()}mv.extend({type:"angleAxis",axisPointerClass:"PolarAxisPointer",render:function(e,t){if(this.group.removeAll(),e.get("show")){var i=e.axis,n=i.polar,o=n.getRadiusAxis().getExtent(),a=i.getTicksCoords(),r=i.getMinorTicksCoords(),s=O(i.getViewLabels(),function(t){return(t=k(t)).coord=i.dataToCoord(t.tickValue),t});jT(s),jT(a),R(UT,function(t){!e.get(t+".show")||i.scale.isBlank()&&"axisLine"!==t||this["_"+t](e,n,a,r,o,s)},this)}},_axisLine:function(t,e,i,n,o){var a,r=t.getModel("axisLine.lineStyle"),s=YT(e),l=s?0:1;(a=0===o[l]?new Yr({shape:{cx:e.cx,cy:e.cy,r:o[s]},style:r.getLineStyle(),z2:1,silent:!0}):new Kr({shape:{cx:e.cx,cy:e.cy,r:o[s],r0:o[l]},style:r.getLineStyle(),z2:1,silent:!0})).style.fill=null,this.group.add(a)},_axisTick:function(t,e,i,n,o){var a=t.getModel("axisTick"),r=(a.get("inside")?-1:1)*a.get("length"),s=o[YT(e)],l=O(i,function(t){return new ls({shape:XT(e,[s,s+r],t.coord)})});this.group.add(Rs(l,{style:D(a.getModel("lineStyle").getLineStyle(),{stroke:t.get("axisLine.lineStyle.color")})}))},_minorTick:function(t,e,i,n,o){if(n.length){for(var a=t.getModel("axisTick"),r=t.getModel("minorTick"),s=(a.get("inside")?-1:1)*r.get("length"),l=o[YT(e)],u=[],h=0;hr?"left":"right",u=Math.abs(a[1]-s)/o<.3?"middle":a[1]>s?"top":"bottom";p&&p[n]&&p[n].textStyle&&(i=new Cl(p[n].textStyle,g,g.ecModel));var h=new Ur({silent:Qm.isLabelSilent(c)});this.group.add(h),nl(h.style,i,{x:a[0],y:a[1],textFill:i.getTextColor()||c.get("axisLine.lineStyle.color"),text:t.formattedLabel,textAlign:l,textVerticalAlign:u}),v&&(h.eventData=Qm.makeAxisEventDataBase(c),h.eventData.targetType="axisLabel",h.eventData.value=t.rawLabel)},this)},_splitLine:function(t,e,i,n,o){var a=t.getModel("splitLine").getModel("lineStyle"),r=a.get("color"),s=0;r=r instanceof Array?r:[r];for(var l=[],u=0;um?"left":"right",h=Math.abs(l[1]-v)/g<.3?"middle":l[1]>v?"top":"bottom"}return{position:l,align:u,verticalAlign:h}}(e,i,0,s,d))}});var JT={line:function(t,e,i,n,o){return"angle"===t.dim?{type:"Line",shape:GI(e.coordToPoint([n[0],i]),e.coordToPoint([n[1],i]))}:{type:"Circle",shape:{cx:e.cx,cy:e.cy,r:i}}},shadow:function(t,e,i,n,o){var a=Math.max(1,t.getBandWidth()),r=Math.PI/180;return"angle"===t.dim?{type:"Sector",shape:WI(e.cx,e.cy,n[0],n[1],(-i-a/2)*r,(a/2-i)*r)}:{type:"Sector",shape:WI(e.cx,e.cy,i-a/2,i+a/2,0,2*Math.PI)}}};function QT(n,t){t.update="updateView",_f(t,function(t,e){var i={};return e.eachComponent({mainType:"geo",query:t},function(e){e[n](t.name),R(e.coordinateSystem.regions,function(t){i[t.name]=e.isSelected(t.name)||!1})}),{selected:i,name:t.name}})}mv.registerAxisPointerClass("PolarAxisPointer",$T),bf(T(function(t,e,i){var N={},O=function(t){var g={};R(t,function(t,e){var i=t.getData(),n=t.coordinateSystem,o=n.getBaseAxis(),a=RT(n,o),r=o.getExtent(),s="category"===o.type?o.getBandWidth():Math.abs(r[1]-r[0])/i.count(),l=g[a]||{bandWidth:s,remainedWidth:s,autoWidthCount:0,categoryGap:"20%",gap:"30%",stacks:{}},u=l.stacks;g[a]=l;var h=OT(t);u[h]||l.autoWidthCount++,u[h]=u[h]||{width:0,maxWidth:0};var c=El(t.get("barWidth"),s),d=El(t.get("barMaxWidth"),s),f=t.get("barGap"),p=t.get("barCategoryGap");c&&!u[h].width&&(c=Math.min(l.remainedWidth,c),u[h].width=c,l.remainedWidth-=c),d&&(u[h].maxWidth=d),null!=f&&(l.gap=f),null!=p&&(l.categoryGap=p)});var d={};return R(g,function(t,i){d[i]={};var e=t.stacks,n=t.bandWidth,o=El(t.categoryGap,n),a=El(t.gap,1),r=t.remainedWidth,s=t.autoWidthCount,l=(r-o)/(s+(s-1)*a);l=Math.max(l,0),R(e,function(t,e){var i=t.maxWidth;i&&i=n.start.time&&i.timea.end.time&&t.reverse(),t},_getRangeInfo:function(t){var e;(t=[this.getDateInfo(t[0]),this.getDateInfo(t[1])])[0].time>t[1].time&&(e=!0,t.reverse());var i=Math.floor(t[1].time/864e5)-Math.floor(t[0].time/864e5)+1,n=new Date(t[0].time),o=n.getDate(),a=t[1].date.getDate();n.setDate(o+i-1);var r=n.getDate();if(r!==a)for(var s=0n.weeks||0===t&&en.lweek)return!1;var o=7*(t-1)-n.fweek+e,a=new Date(n.start.time);return a.setDate(n.start.d+o),this.getDateInfo(a)}},tA.dimensions=tA.prototype.dimensions,tA.getDimensionsInfo=tA.prototype.getDimensionsInfo,tA.create=function(i,n){var o=[];return i.eachComponent("calendar",function(t){var e=new tA(t,i,n);o.push(e),t.coordinateSystem=e}),i.eachSeries(function(t){"calendar"===t.get("coordinateSystem")&&(t.coordinateSystem=o[t.get("calendarIndex")||0])}),o},lh.register("calendar",tA);var iA=ku.extend({type:"calendar",coordinateSystem:null,defaultOption:{zlevel:0,z:2,left:80,top:60,cellSize:20,orient:"horizontal",splitLine:{show:!0,lineStyle:{color:"#000",width:1,type:"solid"}},itemStyle:{color:"#fff",borderWidth:1,borderColor:"#ccc"},dayLabel:{show:!0,firstDay:0,position:"start",margin:"50%",nameMap:"en",color:"#000"},monthLabel:{show:!0,position:"start",margin:5,align:"center",nameMap:"en",formatter:null,color:"#000"},yearLabel:{show:!0,position:null,margin:30,formatter:null,color:"#ccc",fontFamily:"sans-serif",fontWeight:"bolder",fontSize:20}},init:function(t,e,i,n){var o=Iu(t);iA.superApply(this,"init",arguments),nA(t,o)},mergeOption:function(t,e){iA.superApply(this,"mergeOption",arguments),nA(this.option,t)}});function nA(t,e){var i=t.cellSize;L(i)?1===i.length&&(i[1]=i[0]):i=t.cellSize=[i,i];var n=O([0,1],function(t){return function(t,e){return null!=t[xu[e][0]]||null!=t[xu[e][1]]&&null!=t[xu[e][2]]}(e,t)&&(i[t]="auto"),null!=i[t]&&"auto"!==i[t]});Mu(t,e,{type:"box",ignoreSize:n})}var oA={EN:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],CN:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]},aA={EN:["S","M","T","W","T","F","S"],CN:["日","一","二","三","四","五","六"]};Af({type:"calendar",_tlpoints:null,_blpoints:null,_firstDayOfMonth:null,_firstDayPoints:null,render:function(t,e,i){var n=this.group;n.removeAll();var o=t.coordinateSystem,a=o.getRangeInfo(),r=o.getOrient();this._renderDayRect(t,a,n),this._renderLines(t,a,r,n),this._renderYearText(t,a,r,n),this._renderMonthText(t,r,n),this._renderWeekText(t,a,r,n)},_renderDayRect:function(t,e,i){for(var n=t.coordinateSystem,o=t.getModel("itemStyle").getItemStyle(),a=n.getCellWidth(),r=n.getCellHeight(),s=e.start.time;s<=e.end.time;s=n.getNextNDay(s,1).time){var l=n.dataToRect([s],!1).tl,u=new rs({shape:{x:l[0],y:l[1],width:a,height:r},cursor:"default",style:o});i.add(u)}},_renderLines:function(i,t,n,o){var a=this,r=i.coordinateSystem,s=i.getModel("splitLine.lineStyle").getLineStyle(),l=i.get("splitLine.show"),e=s.lineWidth;this._tlpoints=[],this._blpoints=[],this._firstDayOfMonth=[],this._firstDayPoints=[];for(var u=t.start,h=0;u.time<=t.end.time;h++){d(u.formatedDate),0===h&&(u=r.getDateInfo(t.start.y+"-"+t.start.m));var c=u.date;c.setMonth(c.getMonth()+1),u=r.getDateInfo(c)}function d(t){a._firstDayOfMonth.push(r.getDateInfo(t)),a._firstDayPoints.push(r.dataToRect([t],!1).tl);var e=a._getLinePointsOfOneWeek(i,t,n);a._tlpoints.push(e[0]),a._blpoints.push(e[e.length-1]),l&&a._drawSplitline(e,s,o)}d(r.getNextNDay(t.end.time,1).formatedDate),l&&this._drawSplitline(a._getEdgesPoints(a._tlpoints,e,n),s,o),l&&this._drawSplitline(a._getEdgesPoints(a._blpoints,e,n),s,o)},_getEdgesPoints:function(t,e,i){var n=[t[0].slice(),t[t.length-1].slice()],o="horizontal"===i?0:1;return n[0][o]=n[0][o]-e/2,n[1][o]=n[1][o]+e/2,n},_drawSplitline:function(t,e,i){var n=new ts({z2:20,shape:{points:t},style:e});i.add(n)},_getLinePointsOfOneWeek:function(t,e,i){var n=t.coordinateSystem;e=n.getDateInfo(e);for(var o=[],a=0;a<7;a++){var r=n.getNextNDay(e.time,a),s=n.dataToRect([r.time],!1);o[2*r.day]=s.tl,o[2*r.day+1]=s["horizontal"===i?"bl":"tr"]}return o},_formatterLabel:function(t,e){return"string"==typeof t&&t?uu(t,e):"function"==typeof t?t(e):e.nameMap},_yearTextPositionControl:function(t,e,i,n,o){e=e.slice();var a=["center","bottom"];"bottom"===n?(e[1]+=o,a=["center","top"]):"left"===n?e[0]-=o:"right"===n?(e[0]+=o,a=["center","top"]):e[1]-=o;var r=0;return"left"!==n&&"right"!==n||(r=Math.PI/2),{rotation:r,position:e,style:{textAlign:a[0],textVerticalAlign:a[1]}}},_renderYearText:function(t,e,i,n){var o=t.getModel("yearLabel");if(o.get("show")){var a=o.get("margin"),r=o.get("position");r=r||("horizontal"!==i?"top":"left");var s=[this._tlpoints[this._tlpoints.length-1],this._blpoints[0]],l=(s[0][0]+s[1][0])/2,u=(s[0][1]+s[1][1])/2,h="horizontal"===i?0:1,c={top:[l,s[h][1]],bottom:[l,s[1-h][1]],left:[s[1-h][0],u],right:[s[h][0],u]},d=e.start.y;+e.end.y>+e.start.y&&(d=d+"-"+e.end.y);var f=o.get("formatter"),p={start:e.start.y,end:e.end.y,nameMap:d},g=this._formatterLabel(f,p),m=new Ur({z2:30});nl(m.style,o,{text:g}),m.attr(this._yearTextPositionControl(m,c[r],i,r,a)),n.add(m)}},_monthTextPositionControl:function(t,e,i,n,o){var a="left",r="top",s=t[0],l=t[1];return"horizontal"===i?(l+=o,e&&(a="center"),"start"===n&&(r="bottom")):(s+=o,e&&(r="middle"),"start"===n&&(a="right")),{x:s,y:l,textAlign:a,textVerticalAlign:r}},_renderMonthText:function(t,e,i){var n=t.getModel("monthLabel");if(n.get("show")){var o=n.get("nameMap"),a=n.get("margin"),r=n.get("position"),s=n.get("align"),l=[this._tlpoints,this._blpoints];E(o)&&(o=oA[o.toUpperCase()]||[]);var u="start"===r?0:1,h="horizontal"===e?0:1;a="start"===r?-a:a;for(var c="center"===s,d=0;dd.getHeight()&&(i.textPosition="top",a=!0);var r=a?-5-n.height:p+8;o+n.width/2>d.getWidth()?(i.textPosition=["100%",r],i.textAlign="right"):o-n.width/2<0&&(i.textPosition=[0,r],i.textAlign="left")}})}function t(t,e){var i,n=m[t],o=m[e],a=u[n],r=new Cl(a,h,h.ecModel);if(l&&null!=l.newTitle&&l.featureName===n&&(a.title=l.newTitle),n&&!o){if(function(t){return 0===t.indexOf("my")}(n))i={model:r,onclick:r.option.onclick,featureName:n};else{var s=fA(n);if(!s)return;i=new s(r,c,d)}g[n]=i}else{if(!(i=g[o]))return;i.model=r,i.ecModel=c,i.api=d}n||!o?r.get("show")&&!i.unusable?(function(o,a,t){var r=o.getModel("iconStyle"),s=o.getModel("emphasis.iconStyle"),e=a.getIcons?a.getIcons():o.get("icon"),l=o.get("title")||{};if("string"==typeof e){var i=e,n=l;l={},(e={})[t]=i,l[t]=n}var u=o.iconPaths={};R(e,function(t,e){var i=yl(t,{},{x:-p/2,y:-p/2,width:p,height:p});i.setStyle(r.getItemStyle()),i.hoverStyle=s.getItemStyle(),i.setStyle({text:l[e],textAlign:s.get("textAlign"),textBorderRadius:s.get("textBorderRadius"),textPadding:s.get("textPadding"),textFill:null});var n=h.getModel("tooltip");n&&n.get("show")&&i.attr("tooltip",P({content:l[e],formatter:n.get("formatter",!0)||function(){return l[e]},formatterParams:{componentType:"toolbox",name:e,title:l[e],$vars:["name","title"]},position:n.get("position",!0)||"bottom"},n.option)),$s(i),h.get("showTitle")&&(i.__title=l[e],i.on("mouseover",function(){var t=s.getItemStyle(),e="vertical"===h.get("orient")?null==h.get("right")?"right":"left":null==h.get("bottom")?"bottom":"top";i.setStyle({textFill:s.get("textFill")||t.fill||t.stroke||"#000",textBackgroundColor:s.get("textBackgroundColor"),textPosition:s.get("textPosition")||e})}).on("mouseout",function(){i.setStyle({textFill:null,textBackgroundColor:null})})),i.trigger(o.get("iconStatus."+e)||"normal"),f.add(i),i.on("click",A(a.onclick,a,c,d,e)),u[e]=i})}(r,i,n),r.setIconStatus=function(t,e){var i=this.option,n=this.iconPaths;i.iconStatus=i.iconStatus||{},i.iconStatus[t]=e,n[t]&&n[t].trigger(e)},i.render&&i.render(r,c,d,l)):i.remove&&i.remove(c,d):i.dispose&&i.dispose(c,d)}},updateView:function(t,e,i,n){R(this._features,function(t){t.updateView&&t.updateView(t.model,e,i,n)})},remove:function(e,i){R(this._features,function(t){t.remove&&t.remove(e,i)}),this.group.removeAll()},dispose:function(e,i){R(this._features,function(t){t.dispose&&t.dispose(e,i)})}});var mA=Oc.toolbox.saveAsImage;function vA(t){this.model=t}vA.defaultOption={show:!0,icon:"M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0",title:mA.title,type:"png",connectedBackgroundColor:"#fff",name:"",excludeComponents:["toolbox"],pixelRatio:1,lang:mA.lang.slice()},vA.prototype.unusable=!v.canvasSupported,vA.prototype.onclick=function(t,e){var i=this.model,n=i.get("name")||t.get("title.0.text")||"echarts",o="svg"===e.getZr().painter.getType()?"svg":i.get("type",!0)||"png",a=e.getConnectedDataURL({type:o,backgroundColor:i.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",connectedBackgroundColor:i.get("connectedBackgroundColor"),excludeComponents:i.get("excludeComponents"),pixelRatio:i.get("pixelRatio")});if("function"!=typeof MouseEvent||v.browser.ie||v.browser.edge)if(window.navigator.msSaveOrOpenBlob){for(var r=atob(a.split(",")[1]),s=r.length,l=new Uint8Array(s);s--;)l[s]=r.charCodeAt(s);var u=new Blob([l]);window.navigator.msSaveOrOpenBlob(u,n+"."+o)}else{var h=i.get("lang"),c='';window.open().document.write(c)}else{var d=document.createElement("a");d.download=n+"."+o,d.target="_blank",d.href=a;var f=new MouseEvent("click",{view:document.defaultView,bubbles:!0,cancelable:!1});d.dispatchEvent(f)}},dA("saveAsImage",vA);var yA=Oc.toolbox.magicType,xA="__ec_magicType_stack__";function _A(t){this.model=t}_A.defaultOption={show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",stack:"M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z"},title:k(yA.title),option:{},seriesIndex:{}};var wA=_A.prototype;wA.getIcons=function(){var t=this.model,e=t.get("icon"),i={};return R(t.get("type"),function(t){e[t]&&(i[t]=e[t])}),i};var bA={line:function(t,e,i,n){if("bar"===t)return m({id:e,type:"line",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},n.get("option.line")||{},!0)},bar:function(t,e,i,n){if("line"===t)return m({id:e,type:"bar",data:i.get("data"),stack:i.get("stack"),markPoint:i.get("markPoint"),markLine:i.get("markLine")},n.get("option.bar")||{},!0)},stack:function(t,e,i,n){var o=i.get("stack")===xA;if("line"===t||"bar"===t)return n.setIconStatus("stack",o?"normal":"emphasis"),m({id:e,stack:o?"":xA},n.get("option.stack")||{},!0)}},SA=[["line","bar"],["stack"]];wA.onclick=function(u,t,h){var c=this.model,e=c.get("seriesIndex."+h);if(bA[h]){var i,d={series:[]};if(R(SA,function(t){0<=_(t,h)&&R(t,function(t){c.setIconStatus(t,"normal")})}),c.setIconStatus(h,"emphasis"),u.eachComponent({mainType:"series",query:null==e?null:{seriesIndex:e}},function(t){var e=t.subType,i=t.id,n=bA[h](e,i,t,c);n&&(D(n,t.option),d.series.push(n));var o=t.coordinateSystem;if(o&&"cartesian2d"===o.type&&("line"===h||"bar"===h)){var a=o.getAxesByScale("ordinal")[0];if(a){var r=a.dim+"Axis",s=u.queryComponents({mainType:r,index:t.get(name+"Index"),id:t.get(name+"Id")})[0].componentIndex;d[r]=d[r]||[];for(var l=0;l<=s;l++)d[r][s]=d[r][s]||{};d[r][s].boundaryGap="bar"===h}}}),"stack"===h)i=d.series&&d.series[0]&&d.series[0].stack===xA?m({stack:yA.title.tiled},yA.title):k(yA.title);t.dispatchAction({type:"changeMagicType",currentType:h,newOption:d,newTitle:i,featureName:"magicType"})}},_f({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},function(t,e){e.mergeOption(t.newOption)}),dA("magicType",_A);var MA=Oc.toolbox.dataView,IA=new Array(60).join("-"),TA="\t";function AA(t){var e=function(t){var o={},a=[],r=[];return t.eachRawSeries(function(t){var e=t.coordinateSystem;if(!e||"cartesian2d"!==e.type&&"polar"!==e.type)a.push(t);else{var i=e.getBaseAxis();if("category"===i.type){var n=i.dim+"_"+i.index;o[n]||(o[n]={categoryAxis:i,valueAxis:e.getOtherAxis(i),series:[]},r.push({axisDim:i.dim,axisIndex:i.index})),o[n].series.push(t)}else a.push(t)}}),{seriesGroupByCategoryAxis:o,other:a,meta:r}}(t);return{value:M([function(t){var h=[];return R(t,function(t,e){var i=t.categoryAxis,n=t.valueAxis.dim,o=[" "].concat(O(t.series,function(t){return t.name})),a=[i.model.getCategories()];R(t.series,function(t){var e=t.getRawData();a.push(t.getRawData().mapArray(e.mapDimension(n),function(t){return t}))});for(var r=[o.join(TA)],s=0;st[1]&&t.reverse(),t}function GA(t,e){return Ko(t,e,{includeMainTypes:EA})}BA.setOutputRanges=function(t,e){this.matchOutputRanges(t,e,function(t,e,i){if((t.coordRanges||(t.coordRanges=[])).push(e),!t.coordRange){t.coordRange=e;var n=ZA[t.brushType](0,i,e);t.__rangeOffset={offset:XA[t.brushType](n.values,t.range,[1,1]),xyMinMax:n.xyMinMax}}})},BA.matchOutputRanges=function(t,n,o){PA(t,function(i){var t=this.findTargetInfo(i,n);t&&!0!==t&&R(t.coordSyses,function(t){var e=ZA[i.brushType](1,t,i.range);o(i,e.values,t,n)})},this)},BA.setInputRanges=function(t,o){PA(t,function(t){var e=this.findTargetInfo(t,o);if(t.range=t.range||[],e&&!0!==e){t.panelId=e.panelId;var i=ZA[t.brushType](0,e.coordSys,t.coordRange),n=t.__rangeOffset;t.range=n?XA[t.brushType](i.values,n.offset,function(t,e){var i=jA(t),n=jA(e),o=[i[0]/n[0],i[1]/n[1]];return isNaN(o[0])&&(o[0]=1),isNaN(o[1])&&(o[1]=1),o}(i.xyMinMax,n.xyMinMax)):i.values}},this)},BA.makePanelOpts=function(i,n){return O(this._targetInfoList,function(t){var e=t.getPanelRect();return{panelId:t.panelId,defaultBrushType:n&&n(t),clipPath:hS(e),isTargetByCursor:dS(e,i,t.coordSysModel),getLinearBrushOtherExtent:cS(e)}})},BA.controlSeries=function(t,e,i){var n=this.findTargetInfo(t,i);return!0===n||n&&0<=NA(n.coordSyses,e.coordinateSystem)},BA.findTargetInfo=function(t,e){for(var i=this._targetInfoList,n=GA(e,t),o=0;on[1]&&(n[1]=e[1])})}),n[1]c[1];if(r&&!s&&!l)return!0;r&&(n=!0),s&&(e=!0),l&&(i=!0)}return n&&e&&i}):rD(h,function(t){if("empty"===o)i.setData(u=u.map(t,function(t){return function(t){return t>=c[0]&&t<=c[1]}(t)?t:NaN}));else{var e={};e[t]=c,u.selectRange(e)}}),rD(h,function(t){u.setApproximateExtent(c,t)}))})}}};var uD=R,hD=nD,cD=Tf({type:"dataZoom",dependencies:["xAxis","yAxis","zAxis","radiusAxis","angleAxis","singleAxis","series"],defaultOption:{zlevel:0,z:4,orient:null,xAxisIndex:null,yAxisIndex:null,filterMode:"filter",throttle:null,start:0,end:100,startValue:null,endValue:null,minSpan:null,maxSpan:null,minValueSpan:null,maxValueSpan:null,rangeMode:null},init:function(t,e,i){this._dataIntervalByAxis={},this._dataInfo={},this._axisProxies={},this.textStyleModel,this._autoThrottle=!0,this._rangePropMode=["percent","percent"];var n=dD(t);this.settledOption=n,this.mergeDefaultAndTheme(t,i),this.doInit(n)},mergeOption:function(t){var e=dD(t);m(this.option,t,!0),m(this.settledOption,e,!0),this.doInit(e)},doInit:function(t){var i=this.option;v.canvasSupported||(i.realtime=!1),this._setDefaultThrottle(t),fD(this,t);var n=this.settledOption;uD([["start","startValue"],["end","endValue"]],function(t,e){"value"===this._rangePropMode[e]&&(i[t[0]]=n[t[0]]=null)},this),this.textStyleModel=this.getModel("textStyle"),this._resetTarget(),this._giveAxisProxies()},_giveAxisProxies:function(){var r=this._axisProxies;this.eachTargetAxis(function(t,e,i,n){var o=this.dependentModels[t.axis][e],a=o.__dzAxisProxy||(o.__dzAxisProxy=new aD(t.name,e,this,n));r[t.name+"_"+e]=a},this)},_resetTarget:function(){var i=this.option,t=this._judgeAutoMode();hD(function(t){var e=t.axisIndex;i[e]=Vo(i[e])},this),"axisIndex"===t?this._autoSetAxisIndex():"orient"===t&&this._autoSetOrient()},_judgeAutoMode:function(){var e=this.option,i=!1;hD(function(t){null!=e[t.axisIndex]&&(i=!0)},this);var t=e.orient;return null==t&&i?"orient":i?void 0:(null==t&&(e.orient="horizontal"),"axisIndex")},_autoSetAxisIndex:function(){var a=!0,e=this.get("orient",!0),r=this.option,t=this.dependentModels;if(a){var i="vertical"===e?"y":"x";t[i+"Axis"].length?(r[i+"AxisIndex"]=[0],a=!1):uD(t.singleAxis,function(t){a&&t.get("orient",!0)===e&&(r.singleAxisIndex=[t.componentIndex],a=!1)})}a&&hD(function(t){if(a){var e=[],i=this.dependentModels[t.axis];if(i.length&&!e.length)for(var n=0,o=i.length;ne[0][1]&&(e[0][1]=a[0]),a[1]e[1][1]&&(e[1][1]=a[1])}return e&&eC(e)}};function eC(t){return new Di(t[0][0],t[1][0],t[0][1]-t[0][0],t[1][1]-t[1][0])}var iC=["#ddd"];Tf({type:"brush",dependencies:["geo","grid","xAxis","yAxis","parallel","series"],defaultOption:{toolbox:null,brushLink:null,seriesIndex:"all",geoIndex:null,xAxisIndex:null,yAxisIndex:null,brushType:"rect",brushMode:"single",transformable:!0,brushStyle:{borderWidth:1,color:"rgba(120,140,180,0.3)",borderColor:"rgba(120,140,180,0.8)"},throttleType:"fixRate",throttleDelay:0,removeOnClick:!0,z:1e4},areas:[],brushType:null,brushOption:{},coordInfoList:[],optionUpdated:function(t,e){var i=this.option;e||WD(i,t,["inBrush","outOfBrush"]);var n=i.inBrush=i.inBrush||{};i.outOfBrush=i.outOfBrush||{color:iC},n.hasOwnProperty("liftZ")||(n.liftZ=5)},setAreas:function(t){t&&(this.areas=O(t,function(t){return nC(this.option,t)},this))},setBrushOption:function(t){this.brushOption=nC(this.option,t),this.brushType=this.brushOption.brushType}});function nC(t,e){return m({brushType:t.brushType,brushMode:t.brushMode,transformable:t.transformable,brushStyle:new Cl(t.brushStyle).getItemStyle(),removeOnClick:t.removeOnClick,z:t.z},e,!0)}function oC(t,e,i,n){n&&n.$from===t.id||this._brushController.setPanels(t.brushTargetManager.makePanelOpts(i)).enableBrush(t.brushOption).updateCovers(t.areas.slice())}Af({type:"brush",init:function(t,e){this.ecModel=t,this.api=e,this.model,(this._brushController=new Ob(e.getZr())).on("brush",A(this._onBrush,this)).mount()},render:function(t){return this.model=t,oC.apply(this,arguments)},updateTransform:function(t,e){return KD(e),oC.apply(this,arguments)},updateView:oC,dispose:function(){this._brushController.dispose()},_onBrush:function(t,e){var i=this.model.id;this.model.brushTargetManager.setOutputRanges(t,this.ecModel),e.isEnd&&!e.removeOnClick||this.api.dispatchAction({type:"brush",brushId:i,areas:k(t),$from:i}),e.isEnd&&this.api.dispatchAction({type:"brushEnd",brushId:i,areas:k(t),$from:i})}}),_f({type:"brush",event:"brush"},function(e,t){t.eachComponent({mainType:"brush",query:e},function(t){t.setAreas(e.areas)})}),_f({type:"brushSelect",event:"brushSelected",update:"none"},function(){}),_f({type:"brushEnd",event:"brushEnd",update:"none"},function(){});var aC=Oc.toolbox.brush;function rC(t,e,i){this.model=t,this.ecModel=e,this.api=i,this._brushType,this._brushMode}rC.defaultOption={show:!0,type:["rect","polygon","lineX","lineY","keep","clear"],icon:{rect:"M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13",polygon:"M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2",lineX:"M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4",lineY:"M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4",keep:"M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z",clear:"M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2"},title:k(aC.title)};var sC=rC.prototype;sC.render=sC.updateView=function(e,t,i){var n,o,a;t.eachComponent({mainType:"brush"},function(t){n=t.brushType,o=t.brushOption.brushMode||"single",a|=t.areas.length}),this._brushType=n,this._brushMode=o,R(e.get("type",!0),function(t){e.setIconStatus(t,("keep"===t?"multiple"===o:"clear"===t?a:t===n)?"emphasis":"normal")})},sC.getIcons=function(){var t=this.model,e=t.get("icon",!0),i={};return R(t.get("type",!0),function(t){e[t]&&(i[t]=e[t])}),i},sC.onclick=function(t,e,i){var n=this._brushType,o=this._brushMode;"clear"===i?(e.dispatchAction({type:"axisAreaSelect",intervals:[]}),e.dispatchAction({type:"brush",command:"clear",areas:[]})):e.dispatchAction({type:"takeGlobalCursor",key:"brush",brushOption:{brushType:"keep"===i?n:n!==i&&i,brushMode:"keep"===i?"multiple"===o?"single":"multiple":o}})},dA("brush",rC),yf(function(t,e){var i=t&&t.brush;if(L(i)||(i=i?[i]:[]),i.length){var n=[];R(i,function(t){var e=t.hasOwnProperty("toolbox")?t.toolbox:[];e instanceof Array&&(n=n.concat(e))});var o=t&&t.toolbox;L(o)&&(o=o[0]),o||(o={feature:{}},t.toolbox=[o]);var a=o.feature||(o.feature={}),r=a.brush||(a.brush={}),s=r.type||(r.type=[]);s.push.apply(s,n),function(i){var e={};R(i,function(t){e[t]=1}),i.length=0,R(e,function(t,e){i.push(e)})}(s),e&&!s.length&&s.push.apply(s,BD)}}),Tf({type:"title",layoutMode:{type:"box",ignoreSize:!0},defaultOption:{zlevel:0,z:6,show:!0,text:"",target:"blank",subtext:"",subtarget:"blank",left:0,top:0,backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,padding:5,itemGap:10,textStyle:{fontSize:18,fontWeight:"bolder",color:"#333"},subtextStyle:{color:"#aaa"}}}),Af({type:"title",render:function(t,e,i){if(this.group.removeAll(),t.get("show")){var n=this.group,o=t.getModel("textStyle"),a=t.getModel("subtextStyle"),r=t.get("textAlign"),s=H(t.get("textBaseline"),t.get("textVerticalAlign")),l=new Ur({style:nl({},o,{text:t.get("text"),textFill:o.getTextColor()},{disableBox:!0}),z2:10}),u=l.getBoundingRect(),h=t.get("subtext"),c=new Ur({style:nl({},a,{text:h,textFill:a.getTextColor(),y:u.height+t.get("itemGap"),textVerticalAlign:"top"},{disableBox:!0}),z2:10}),d=t.get("link"),f=t.get("sublink"),p=t.get("triggerEvent",!0);l.silent=!d&&!p,c.silent=!f&&!p,d&&l.on("click",function(){gu(d,"_"+t.get("target"))}),f&&c.on("click",function(){gu(f,"_"+t.get("subtarget"))}),l.eventData=c.eventData=p?{componentType:"title",componentIndex:t.componentIndex}:null,n.add(l),h&&n.add(c);var g=n.getBoundingRect(),m=t.getBoxLayoutParams();m.width=g.width,m.height=g.height;var v=bu(m,{width:i.getWidth(),height:i.getHeight()},t.get("padding"));r||("middle"===(r=t.get("left")||t.get("right"))&&(r="center"),"right"===r?v.x+=v.width:"center"===r&&(v.x+=v.width/2)),s||("center"===(s=t.get("top")||t.get("bottom"))&&(s="middle"),"bottom"===s?v.y+=v.height:"middle"===s&&(v.y+=v.height/2),s=s||"top"),n.attr("position",[v.x,v.y]);var y={textAlign:r,textVerticalAlign:s};l.setStyle(y),c.setStyle(y),g=n.getBoundingRect();var x=v.margin,_=t.getItemStyle(["color","opacity"]);_.fill=t.get("backgroundColor");var w=new rs({shape:{x:g.x-x[3],y:g.y-x[0],width:g.width+x[1]+x[3],height:g.height+x[0]+x[2],r:t.get("borderRadius")},style:_,subPixelOptimize:!0,silent:!0});n.add(w)}}});function lC(t){var e=t.itemStyle||(t.itemStyle={}),i=e.emphasis||(e.emphasis={}),n=t.label||t.label||{},o=n.normal||(n.normal={}),a={normal:1,emphasis:1};R(n,function(t,e){a[e]||uC(o,e)||(o[e]=t)}),i.label&&!uC(n,"emphasis")&&(n.emphasis=i.label,delete i.label)}function uC(t,e){return t.hasOwnProperty(e)}ku.registerSubTypeDefaulter("timeline",function(){return"slider"}),_f({type:"timelineChange",event:"timelineChanged",update:"prepareAndUpdate"},function(t,e){var i=e.getComponent("timeline");return i&&null!=t.currentIndex&&(i.setCurrentIndex(t.currentIndex),!i.get("loop",!0)&&i.isIndexMax()&&i.setPlayState(!1)),e.resetOption("timeline"),D({currentIndex:i.option.currentIndex},t)}),_f({type:"timelinePlayChange",event:"timelinePlayChanged",update:"update"},function(t,e){var i=e.getComponent("timeline");i&&null!=t.playState&&i.setPlayState(t.playState)});var hC=ku.extend({type:"timeline",layoutMode:"box",defaultOption:{zlevel:0,z:4,show:!0,axisType:"time",realtime:!0,left:"20%",top:null,right:"20%",bottom:0,width:null,height:40,padding:5,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:"#000"},data:[]},init:function(t,e,i){this._data,this._names,this.mergeDefaultAndTheme(t,i),this._initData()},mergeOption:function(t){hC.superApply(this,"mergeOption",arguments),this._initData()},setCurrentIndex:function(t){null==t&&(t=this.option.currentIndex);var e=this._data.count();this.option.loop?t=(t%e+e)%e:(e<=t&&(t=e-1),t<0&&(t=0)),this.option.currentIndex=t},getCurrentIndex:function(){return this.option.currentIndex},isIndexMax:function(){return this.getCurrentIndex()>=this._data.count()-1},setPlayState:function(t){this.option.autoPlay=!!t},getPlayState:function(){return!!this.option.autoPlay},_initData:function(){var t=this.option,e=t.data||[],i=t.axisType,o=this._names=[];if("category"===i){var a=[];R(e,function(t,e){var i,n=Wo(t);z(t)?(i=k(t)).value=e:i=e,a.push(i),E(n)||null!=n&&!isNaN(n)||(n=""),o.push(n+"")}),e=a}var n={category:"ordinal",time:"time"}[i]||"number";(this._data=new Yf([{name:"value",type:n}],this)).initData(e,o)},getData:function(){return this._data},getCategories:function(){if("category"===this.get("axisType"))return this._names.slice()}});b(hC.extend({type:"timeline.slider",defaultOption:{backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"emptyCircle",symbolSize:10,lineStyle:{show:!0,width:2,color:"#304654"},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:"#304654"},itemStyle:{color:"#304654",borderWidth:1},checkpointStyle:{symbol:"circle",symbolSize:13,color:"#c23531",borderWidth:5,borderColor:"rgba(194,53,49, 0.5)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:22,itemGap:12,position:"left",playIcon:"path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z",stopIcon:"path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z",nextIcon:"path://M18.6,50.8l22.5-22.5c0.2-0.2,0.3-0.4,0.3-0.7c0-0.3-0.1-0.5-0.3-0.7L18.7,4.4c-0.1-0.1-0.2-0.3-0.2-0.5 c0-0.4,0.3-0.8,0.8-0.8c0.2,0,0.5,0.1,0.6,0.3l23.5,23.5l0,0c0.2,0.2,0.3,0.4,0.3,0.7c0,0.3-0.1,0.5-0.3,0.7l-0.1,0.1L19.7,52 c-0.1,0.1-0.3,0.2-0.5,0.2c-0.4,0-0.8-0.3-0.8-0.8C18.4,51.2,18.5,51,18.6,50.8z",prevIcon:"path://M43,52.8L20.4,30.3c-0.2-0.2-0.3-0.4-0.3-0.7c0-0.3,0.1-0.5,0.3-0.7L42.9,6.4c0.1-0.1,0.2-0.3,0.2-0.5 c0-0.4-0.3-0.8-0.8-0.8c-0.2,0-0.5,0.1-0.6,0.3L18.3,28.8l0,0c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.3,0.1,0.5,0.3,0.7l0.1,0.1L41.9,54 c0.1,0.1,0.3,0.2,0.5,0.2c0.4,0,0.8-0.3,0.8-0.8C43.2,53.2,43.1,53,43,52.8z",color:"#304654",borderColor:"#304654",borderWidth:1},emphasis:{label:{show:!0,color:"#c23531"},itemStyle:{color:"#c23531"},controlStyle:{color:"#c23531",borderColor:"#c23531",borderWidth:2}},data:[]}}),Xh);function cC(t,e,i,n){Gg.call(this,t,e,i),this.type=n||"value",this.model=null}var dC=gc.extend({type:"timeline"});cC.prototype={constructor:cC,getLabelModel:function(){return this.model.getModel("label")},isHorizontal:function(){return"horizontal"===this.model.get("orient")}},w(cC,Gg);var fC=A,pC=R,gC=Math.PI;function mC(t,e,i,n,o,a){var r=e.get("color");o?(o.setColor(r),i.add(o),a&&a.onUpdate(o)):((o=wg(t.get("symbol"),-1,-1,2,2,r)).setStyle("strokeNoScale",!0),i.add(o),a&&a.onCreate(o));var s=e.getItemStyle(["color","symbol","symbolSize"]);o.setStyle(s),n=m({rectHover:!0,z2:100},n,!0);var l=t.get("symbolSize");(l=l instanceof Array?l.slice():[+l,+l])[0]/=2,l[1]/=2,n.scale=l;var u=t.get("symbolOffset");if(u){var h=n.position=n.position||[0,0];h[0]+=El(u[0],l[0]),h[1]+=El(u[1],l[1])}var c=t.get("symbolRotate");return n.rotation=(c||0)*Math.PI/180||0,o.attr(n),o.updateTransform(),o}function vC(t,e,i,n,o){if(!t.dragging){var a=n.getModel("checkpointStyle"),r=i.dataToCoord(n.getData().get(["value"],e));o||!a.get("animation",!0)?t.attr({position:[r,0]}):(t.stopAnimation(!0),t.animateTo({position:[r,0]},a.get("animationDuration",!0),a.get("animationEasing",!0)))}}dC.extend({type:"timeline.slider",init:function(t,e){this.api=e,this._axis,this._viewRect,this._timer,this._currentPointer,this._mainGroup,this._labelGroup},render:function(e,t,i,n){if(this.model=e,this.api=i,this.ecModel=t,this.group.removeAll(),e.get("show",!0)){var o=this._layout(e,i),a=this._createGroup("mainGroup"),r=this._createGroup("labelGroup"),s=this._axis=this._createAxis(o,e);e.formatTooltip=function(t){return au(s.scale.getLabel(t))},pC(["AxisLine","AxisTick","Control","CurrentPointer"],function(t){this["_render"+t](o,a,s,e)},this),this._renderAxisLabel(o,r,s,e),this._position(o,e)}this._doPlayStop()},remove:function(){this._clearTimer(),this.group.removeAll()},dispose:function(){this._clearTimer()},_layout:function(t,e){var i=t.get("label.position"),n=t.get("orient"),o=function(t,e){return bu(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()},t.get("padding"))}(t,e);null==i||"auto"===i?i="horizontal"===n?o.y+o.height/2n[1]&&(i=n[1]),i":"\n"),s&&(l+=xC(s),null!=a&&(l+=" : ")),null!=a&&(l+=xC(r)),l},getData:function(){return this._data},setData:function(t){this._data=t}});b(wC,Xh),wC.extend({type:"markPoint",defaultOption:{zlevel:0,z:5,symbol:"pin",symbolSize:50,tooltip:{trigger:"item"},label:{show:!0,position:"inside"},itemStyle:{borderWidth:2},emphasis:{label:{show:!0}}}});var bC=_;function SC(t,e,i,n,o,a){var r=[],s=fp(e,n)?e.getCalculationInfo("stackResultDimension"):n,l=LC(e,s,t),u=e.indicesOfNearest(s,l)[0];r[o]=e.get(i,u),r[a]=e.get(s,u);var h=e.get(n,u),c=Vl(e.get(n,u));return 0<=(c=Math.min(c,20))&&(r[a]=+r[a].toFixed(c)),[r,h]}var MC=T,IC={min:MC(SC,"min"),max:MC(SC,"max"),average:MC(SC,"average")};function TC(t,e){var i=t.getData(),n=t.coordinateSystem;if(e&&!function(t){return!isNaN(parseFloat(t.x))&&!isNaN(parseFloat(t.y))}(e)&&!L(e.coord)&&n){var o=n.dimensions,a=AC(e,i,n,t);if((e=k(e)).type&&IC[e.type]&&a.baseAxis&&a.valueAxis){var r=bC(o,a.baseAxis.dim),s=bC(o,a.valueAxis.dim),l=IC[e.type](i,a.baseDataDim,a.valueDataDim,r,s);e.coord=l[0],e.value=l[1]}else{for(var u=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis],h=0;h<2;h++)IC[u[h]]&&(u[h]=LC(i,i.mapDimension(o[h]),u[h]));e.coord=u}}return e}function AC(t,e,i,n){var o={};return null!=t.valueIndex||null!=t.valueDim?(o.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,o.valueAxis=i.getAxis(function(t,e){var i=t.getData(),n=i.dimensions;e=i.getDimension(e);for(var o=0;oi[o],f=[-h.x,-h.y];e||(f[n]=s.position[n]);var p=[0,0],g=[-c.x,-c.y],m=H(t.get("pageButtonGap",!0),t.get("itemGap",!0));d&&("end"===t.get("pageButtonPosition",!0)?g[n]+=i[o]-c[o]:p[n]+=c[o]+m);g[1-n]+=h[a]/2-c[a]/2,s.attr("position",f),l.attr("position",p),u.attr("position",g);var v={x:0,y:0};if(v[o]=d?i[o]:h[o],v[a]=Math.max(h[a],c[a]),v[r]=Math.min(0,c[r]+g[1-n]),l.__rectSize=i[o],d){var y={x:0,y:0};y[o]=Math.max(i[o]-c[o]-m,0),y[a]=v[a],l.setClipPath(new rs({shape:y})),l.__rectSize=y[o]}else u.eachChild(function(t){t.attr({invisible:!0,silent:!0})});var x=this._getPageInfo(t);return null!=x.pageIndex&&cl(s,{position:x.contentPosition},d&&t),this._updatePageInfoView(t,x),v},_pageGo:function(t,e,i){var n=this._getPageInfo(e)[t];null!=n&&i.dispatchAction({type:"legendScroll",scrollDataIndex:n,legendId:e.id})},_updatePageInfoView:function(n,o){var a=this._controllerGroup;R(["pagePrev","pageNext"],function(t){var e=null!=o[t+"DataIndex"],i=a.childOfName(t);i&&(i.setStyle("fill",e?n.get("pageIconColor",!0):n.get("pageIconInactiveColor",!0)),i.cursor=e?"pointer":"default")});var t=a.childOfName("pageText"),e=n.get("pageFormatter"),i=o.pageIndex,r=null!=i?i+1:0,s=o.pageCount;t&&e&&t.setStyle("text",E(e)?e.replace("{current}",r).replace("{total}",s):e({current:r,total:s}))},_getPageInfo:function(t){var e=t.get("scrollDataIndex",!0),i=this.getContentGroup(),n=this._containerGroup.__rectSize,o=t.getOrient().index,a=aL[o],r=rL[o],s=this._findTargetItemIndex(e),l=i.children(),u=l[s],h=l.length,c=h?1:0,d={contentPosition:i.position.slice(),pageCount:c,pageIndex:c-1,pagePrevDataIndex:null,pageNextDataIndex:null};if(!u)return d;var f=y(u);d.contentPosition[o]=-f.s;for(var p=s+1,g=f,m=f,v=null;p<=h;++p)(!(v=y(l[p]))&&m.e>g.s+n||v&&!x(v,g.s))&&(g=m.i>g.i?m:v)&&(null==d.pageNextDataIndex&&(d.pageNextDataIndex=g.i),++d.pageCount),m=v;for(p=s-1,g=f,m=f,v=null;-1<=p;--p)(v=y(l[p]))&&x(m,v.s)||!(g.i=e&&t.s<=e+n}},_findTargetItemIndex:function(n){return this._showController?(this.getContentGroup().eachChild(function(t,e){var i=t.__legendDataIndex;null==a&&null!=i&&(a=e),i===n&&(o=e)}),null!=o?o:a):0;var o,a}});_f("legendScroll","legendscroll",function(t,e){var i=t.scrollDataIndex;null!=i&&e.eachComponent({mainType:"legend",subType:"scroll",query:t},function(t){t.setScrollDataIndex(i)})});cD.extend({type:"dataZoom.slider",layoutMode:"box",defaultOption:{show:!0,right:"ph",top:"ph",width:"ph",height:"ph",left:null,bottom:null,backgroundColor:"rgba(47,69,84,0)",dataBackground:{lineStyle:{color:"#2f4554",width:.5,opacity:.3},areaStyle:{color:"rgba(47,69,84,0.3)",opacity:.3}},borderColor:"#ddd",fillerColor:"rgba(167,183,204,0.4)",handleIcon:"M8.2,13.6V3.9H6.3v9.7H3.1v14.9h3.3v9.7h1.8v-9.7h3.3V13.6H8.2z M9.7,24.4H4.8v-1.4h4.9V24.4z M9.7,19.1H4.8v-1.4h4.9V19.1z",handleSize:"100%",handleStyle:{color:"#a7b7cc"},labelPrecision:null,labelFormatter:null,showDetail:!0,showDataShadow:"auto",realtime:!0,zoomLock:!1,textStyle:{color:"#333"}}});var lL=rs,uL=Rl,hL=Bl,cL=A,dL=R,fL="horizontal",pL="vertical",gL=["line","bar","candlestick","scatter"],mL=pD.extend({type:"dataZoom.slider",init:function(t,e){this._displayables={},this._orient,this._range,this._handleEnds,this._size,this._handleWidth,this._handleHeight,this._location,this._dragging,this._dataShadowInfo,this.api=e},render:function(t,e,i,n){mL.superApply(this,"render",arguments),kc(this,"_dispatchZoomAction",this.dataZoomModel.get("throttle"),"fixRate"),this._orient=t.get("orient"),!1!==this.dataZoomModel.get("show")?(n&&"dataZoom"===n.type&&n.from===this.uid||this._buildView(),this._updateView()):this.group.removeAll()},remove:function(){mL.superApply(this,"remove",arguments),Pc(this,"_dispatchZoomAction")},dispose:function(){mL.superApply(this,"dispose",arguments),Pc(this,"_dispatchZoomAction")},_buildView:function(){var t=this.group;t.removeAll(),this._resetLocation(),this._resetInterval();var e=this._displayables.barGroup=new Ci;this._renderBackground(),this._renderHandle(),this._renderDataShadow(),t.add(e),this._positionGroup()},_resetLocation:function(){var t=this.dataZoomModel,e=this.api,i=this._findCoordRect(),n={width:e.getWidth(),height:e.getHeight()},o=this._orient===fL?{right:n.width-i.x-i.width,top:n.height-30-7,width:i.width,height:30}:{right:7,top:i.y,width:30,height:i.height},a=Iu(t.option);R(["right","top","width","height"],function(t){"ph"===a[t]&&(a[t]=o[t])});var r=bu(a,n,t.padding);this._location={x:r.x,y:r.y},this._size=[r.width,r.height],this._orient===pL&&this._size.reverse()},_positionGroup:function(){var t=this.group,e=this._location,i=this._orient,n=this.dataZoomModel.getFirstTargetAxisModel(),o=n&&n.get("inverse"),a=this._displayables.barGroup,r=(this._dataShadowInfo||{}).otherAxisInverse;a.attr(i!==fL||o?i===fL&&o?{scale:r?[-1,1]:[-1,-1]}:i!==pL||o?{scale:r?[-1,-1]:[-1,1],rotation:Math.PI/2}:{scale:r?[1,-1]:[1,1],rotation:Math.PI/2}:{scale:r?[1,1]:[1,-1]});var s=t.getBoundingRect([a]);t.attr("position",[e.x-s.x,e.y-s.y])},_getViewExtent:function(){return[0,this._size[0]]},_renderBackground:function(){var t=this.dataZoomModel,e=this._size,i=this._displayables.barGroup;i.add(new lL({silent:!0,shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:t.get("backgroundColor")},z2:-40})),i.add(new lL({shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:"transparent"},z2:0,onclick:A(this._onClickPanelClick,this)}))},_renderDataShadow:function(){var t=this._dataShadowInfo=this._prepareDataShadowInfo();if(t){var e=this._size,i=t.series,n=i.getRawData(),o=i.getShadowDim?i.getShadowDim():t.otherDim;if(null!=o){var a=n.getDataExtent(o),r=.3*(a[1]-a[0]);a=[a[0]-r,a[1]+r];var s,l=[0,e[1]],u=[0,e[0]],h=[[e[0],0],[0,0]],c=[],d=u[1]/(n.count()-1),f=0,p=Math.round(n.count()/e[0]);n.each([o],function(t,e){if(0e[0]||i[1]<0||i[1]>e[1])){var n=this._handleEnds,o=(n[0]+n[1])/2,a=this._updateInterval("all",i[0]-o);this._updateView(),a&&this._dispatchZoomAction()}},_dispatchZoomAction:function(){var t=this._range;this.api.dispatchAction({type:"dataZoom",from:this.uid,dataZoomId:this.dataZoomModel.id,start:t[0],end:t[1]})},_findCoordRect:function(){var i;if(dL(this.getTargetCoordInfo(),function(t){if(!i&&t.length){var e=t[0].model.coordinateSystem;i=e.getRect&&e.getRect()}}),!i){var t=this.api.getWidth(),e=this.api.getHeight();i={x:.2*t,y:.2*e,width:.6*t,height:.6*e}}return i}});function vL(t){return"vertical"===t?"ns-resize":"ew-resize"}cD.extend({type:"dataZoom.inside",defaultOption:{disabled:!1,zoomLock:!1,zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!1,preventDefaultMouseMove:!0}});var yL="\0_ec_dataZoom_roams";function xL(t,n){var e=wL(t),o=n.dataZoomId,a=n.coordId;R(e,function(t,e){var i=t.dataZoomInfos;i[o]&&_(n.allCoordIds,a)<0&&(delete i[o],t.count--)}),bL(e);var i=e[a];i||((i=e[a]={coordId:a,dataZoomInfos:{},count:0}).controller=function(t,r){var e=new Vy(t.getZr());return R(["pan","zoom","scrollMove"],function(a){e.on(a,function(n){var o=[];R(r.dataZoomInfos,function(t){if(n.isAvailableBehavior(t.dataZoomModel.option)){var e=(t.getRange||{})[a],i=e&&e(r.controller,n);!t.dataZoomModel.get("disabled",!0)&&i&&o.push({dataZoomId:t.dataZoomId,start:i[0],end:i[1]})}}),o.length&&r.dispatchAction(o)})}),e}(t,i),i.dispatchAction=T(SL,t)),i.dataZoomInfos[o]||i.count++,i.dataZoomInfos[o]=n;var r=function(t){var n,o={type_true:2,type_move:1,type_false:0,type_undefined:-1},a=!0;return R(t,function(t){var e=t.dataZoomModel,i=!e.get("disabled",!0)&&(!e.get("zoomLock",!0)||"move");o["type_"+n]"],L(t)&&(t=t.slice(),n=!0),o=e?t:n?[u(t[0]),u(t[1])]:u(t),E(l)?l.replace("{value}",n?o[0]:o).replace("{value2}",n?o[1]:o):C(l)?n?l(t[0],t[1]):l(t):n?t[0]===s[0]?i[0]+" "+o[1]:t[1]===s[1]?i[1]+" "+o[0]:o[0]+" - "+o[1]:o;function u(t){return t===s[0]?"min":t===s[1]?"max":(+t).toFixed(Math.min(r,20))}},resetExtent:function(){var t=this.option,e=GL([t.min,t.max]);this._dataExtent=e},getDataDimension:function(t){var e=this.option.dimension,i=t.dimensions;if(null!=e||i.length){if(null!=e)return t.getDimension(e);for(var n=t.dimensions,o=n.length-1;0<=o;o--){var a=n[o];if(!t.getDimensionInfo(a).isCalculationCoord)return a}}},getExtent:function(){return this._dataExtent.slice()},completeVisualOption:function(){var t=this.ecModel,e=this.option,i={inRange:e.inRange,outOfRange:e.outOfRange},n=e.target||(e.target={}),o=e.controller||(e.controller={});m(n,i),m(o,i);var u=this.isCategory();function a(n){BL(e.color)&&!n.inRange&&(n.inRange={color:e.color.slice().reverse()}),n.inRange=n.inRange||{color:t.get("gradientColor")},VL(this.stateList,function(t){var e=n[t];if(E(e)){var i=OL(e,"active",u);i?(n[t]={},n[t][e]=i):delete n[t]}},this)}a.call(this,n),a.call(this,o),function(t,e,i){var n=t[e],o=t[i];n&&!o&&(o=t[i]={},VL(n,function(t,e){if(g_.isValidType(e)){var i=OL(e,"inactive",u);null!=i&&(o[e]=i,"color"!==e||o.hasOwnProperty("opacity")||o.hasOwnProperty("colorAlpha")||(o.opacity=[0,0]))}}))}.call(this,n,"inRange","outOfRange"),function(a){var r=(a.inRange||{}).symbol||(a.outOfRange||{}).symbol,s=(a.inRange||{}).symbolSize||(a.outOfRange||{}).symbolSize,l=this.get("inactiveColor");VL(this.stateList,function(t){var e=this.itemSize,i=a[t];null==(i=i||(a[t]={color:u?l:[l]})).symbol&&(i.symbol=r&&k(r)||(u?"roundRect":["roundRect"])),null==i.symbolSize&&(i.symbolSize=s&&k(s)||(u?e[0]:[e[0],e[0]])),i.symbol=EL(i.symbol,function(t){return"none"===t||"square"===t?"roundRect":t});var n=i.symbolSize;if(null!=n){var o=-1/0;zL(n,function(t){oe[1]&&e.reverse(),e[0]=Math.max(e[0],t[0]),e[1]=Math.min(e[1],t[1]))},completeVisualOption:function(){WL.prototype.completeVisualOption.apply(this,arguments),R(this.stateList,function(t){var e=this.option.controller[t].symbolSize;e&&e[0]!==e[1]&&(e[0]=0)},this)},setSelected:function(t){this.option.range=t.slice(),this._resetRange()},getSelected:function(){var t=this.getExtent(),e=Bl((this.get("range")||[]).slice());return e[0]>t[1]&&(e[0]=t[1]),e[1]>t[1]&&(e[1]=t[1]),e[0]=i[1]||t<=e[1])?"inRange":"outOfRange"},findTargetDataIndices:function(n){var o=[];return this.eachTargetSeries(function(t){var i=[],e=t.getData();e.each(this.getDataDimension(e),function(t,e){n[0]<=t&&t<=n[1]&&i.push(e)},this),o.push({seriesId:t.id,dataIndex:i})},this),o},getVisualMeta:function(i){var t=UL(this,"outOfRange",this.getExtent()),e=UL(this,"inRange",this.option.range.slice()),n=[];function o(t,e){n.push({value:t,color:i(t,e)})}for(var a=0,r=0,s=e.length,l=t.length;rt[1])break;i.push({color:this.getControllerVisual(a,"color",e),offset:o/100})}return i.push({color:this.getControllerVisual(t[1],"color",e),offset:1}),i},_createBarPoints:function(t,e){var i=this.visualMapModel.itemSize;return[[i[0]-e[0],t[0]],[i[0],t[0]],[i[0],t[1]],[i[0]-e[1],t[1]]]},_createBarGroup:function(t){var e=this._orient,i=this.visualMapModel.get("inverse");return new Ci("horizontal"!==e||i?"horizontal"===e&&i?{scale:"bottom"===t?[-1,1]:[1,1],rotation:-Math.PI/2}:"vertical"!==e||i?{scale:"left"===t?[1,1]:[-1,1]}:{scale:"left"===t?[1,-1]:[-1,-1]}:{scale:"bottom"===t?[1,1]:[-1,1],rotation:Math.PI/2})},_updateHandle:function(n,o){if(this._useHandle){var a=this._shapes,r=this.visualMapModel,s=a.handleThumbs,l=a.handleLabels;KL([0,1],function(t){var e=s[t];e.setStyle("fill",o.handlesColor[t]),e.position[1]=n[t];var i=pl(a.handleLabelPoints[t],fl(e,this.group));l[t].setStyle({x:i[0],y:i[1],text:r.formatValueText(this._dataInterval[t]),textVerticalAlign:"middle",textAlign:this._applyTransform("horizontal"===this._orient?0===t?"bottom":"top":"left",a.barGroup)})},this)}},_showIndicator:function(t,e,i,n){var o=this.visualMapModel,a=o.getExtent(),r=o.itemSize,s=[0,r[1]],l=qL(t,a,s,!0),u=this._shapes,h=u.indicator;if(h){h.position[1]=l,h.attr("invisible",!1),h.setShape("points",function(t,e,i,n){return t?[[0,-$L(e,JL(i,0))],[6,0],[0,$L(e,JL(n-i,0))]]:[[0,0],[5,-5],[5,5]]}(!!i,n,l,r[1]));var c=this.getControllerVisual(t,"color",{convertOpacityToAlpha:!0});h.setStyle("fill",c);var d=pl(u.indicatorLabelPoint,fl(h,this.group)),f=u.indicatorLabel;f.attr("invisible",!1);var p=this._applyTransform("left",u.barGroup),g=this._orient;f.setStyle({text:(i||"")+o.formatValueText(e),textVerticalAlign:"horizontal"===g?p:"middle",textAlign:"horizontal"===g?"center":p,x:d[0],y:d[1]})}},_enableHoverLinkToSeries:function(){var n=this;this._shapes.barGroup.on("mousemove",function(t){if(n._hovering=!0,!n._dragging){var e=n.visualMapModel.itemSize,i=n._applyTransform([t.offsetX,t.offsetY],n._shapes.barGroup,!0,!0);i[1]=$L(JL(0,i[1]),e[1]),n._doHoverLinkToSeries(i[1],0<=i[0]&&i[0]<=e[0])}}).on("mouseout",function(){n._hovering=!1,n._dragging||n._clearHoverLinkToSeries()})},_enableHoverLinkFromSeries:function(){var t=this.api.getZr();this.visualMapModel.option.hoverLink?(t.on("mouseover",this._hoverLinkFromSeriesMouseOver,this),t.on("mouseout",this._hideIndicator,this)):this._clearHoverLinkFromSeries()},_doHoverLinkToSeries:function(t,e){var i=this.visualMapModel,n=i.itemSize;if(i.option.hoverLink){var o=[0,n[1]],a=i.getExtent();t=$L(JL(o[0],t),o[1]);var r=function(t,e,i){var n=6,o=t.get("hoverLinkDataSize");o&&(n=qL(o,e,i,!0)/2);return n}(i,a,o),s=[t-r,t+r],l=qL(t,o,a,!0),u=[qL(s[0],o,a,!0),qL(s[1],o,a,!0)];s[0] ",r):this._showIndicator(l,l,"≈ ",r));var h=this._hoverLinkDataIndices,c=[];(e||ek(i))&&(c=this._hoverLinkDataIndices=i.findTargetDataIndices(u));var d=function(t,e){var i={},n={};return o(t||[],i),o(e||[],n,i),[a(i),a(n)];function o(t,e,i){for(var n=0,o=t.length;ni&&n([i,e[0]],"outOfRange"),n(e.slice()),i=e[1])},this),{stops:a,outerColors:r}}function n(t,e){var i=s.getRepresentValue({interval:t});e=e||s.getValueState(i);var n=o(i,e);t[0]===-1/0?r[0]=n:t[1]===1/0?r[1]=n:a.push({value:t[0],color:n},{value:t[1],color:n})}}}),ok={splitNumber:function(){var t=this.option,e=this._pieceList,i=Math.min(t.precision,20),n=this.getExtent(),o=t.splitNumber;o=Math.max(parseInt(o,10),1),t.splitNumber=o;for(var a=(n[1]-n[0])/o;+a.toFixed(i)!==a&&i<5;)i++;t.precision=i,a=+a.toFixed(i),t.minOpen&&e.push({interval:[-1/0,n[0]],close:[0,0]});for(var r=0,s=n[0];r","≥"][e[0]]];t.text=t.text||this.formatValueText(null!=t.value?t.value:t.interval,!1,i)},this)}};function ak(t,e){var i=t.inverse;("vertical"===t.orient?!i:i)&&e.reverse()}XL.extend({type:"visualMap.piecewise",doRender:function(){var a=this.group;a.removeAll();var r=this.visualMapModel,s=r.get("textGap"),t=r.textStyleModel,l=t.getFont(),u=t.getTextColor(),h=this._getItemAlign(),c=r.itemSize,e=this._getViewData(),i=e.endsText,d=W(r.get("showLabel",!0),!i);i&&this._renderEndsText(a,i[0],c,d,h),R(e.viewPieceList,function(t){var e=t.piece,i=new Ci;i.onclick=A(this._onItemClick,this,e),this._enableHoverLink(i,t.indexInModelPieceList);var n=r.getRepresentValue(e);if(this._createItemSymbol(i,n,[0,0,c[0],c[1]]),d){var o=this.visualMapModel.getValueState(n);i.add(new Ur({style:{x:"right"===h?-s:c[0]+s,y:c[1]/2,text:e.text,textVerticalAlign:"middle",textAlign:h,textFont:l,textFill:u,opacity:"outOfRange"===o?.5:1}}))}a.add(i)},this),i&&this._renderEndsText(a,i[1],c,d,h),wu(r.get("orient"),a,r.get("itemGap")),this.renderBackground(a),this.positionGroup(a)},_enableHoverLink:function(t,i){function e(t){var e=this.visualMapModel;e.option.hoverLink&&this.api.dispatchAction({type:t,batch:jL(e.findTargetDataIndices(i),e)})}t.on("mouseover",A(e,this,"highlight")).on("mouseout",A(e,this,"downplay"))},_getItemAlign:function(){var t=this.visualMapModel,e=t.option;if("vertical"===e.orient)return YL(t,this.api,t.itemSize);var i=e.align;return i&&"auto"!==i||(i="left"),i},_renderEndsText:function(t,e,i,n,o){if(e){var a=new Ci,r=this.visualMapModel.textStyleModel;a.add(new Ur({style:{x:n?"right"===o?i[0]:0:i[0]/2,y:i[1]/2,textVerticalAlign:"middle",textAlign:n?o:"center",text:e,textFont:r.getFont(),textFill:r.getTextColor()}})),t.add(a)}},_getViewData:function(){var t=this.visualMapModel,e=O(t.getPieceList(),function(t,e){return{piece:t,indexInModelPieceList:e}}),i=t.get("text"),n=t.get("orient"),o=t.get("inverse");return("horizontal"===n?o:!o)?e.reverse():i=i&&i.slice().reverse(),{viewPieceList:e,endsText:i}},_createItemSymbol:function(t,e,i){t.add(wg(this.getControllerVisual(e,"symbol"),i[0],i[1],i[2],i[3],this.getControllerVisual(e,"color")))},_onItemClick:function(t){var e=this.visualMapModel,i=e.option,n=k(i.selected),o=e.getSelectedMapKey(t);"single"===i.selectedMode?(n[o]=!0,R(n,function(t,e){n[e]=e===o})):n[o]=!n[o],this.api.dispatchAction({type:"selectDataRange",from:this.uid,visualMapId:this.visualMapModel.id,selected:n})}});yf(DL);var rk,sk="urn:schemas-microsoft-com:vml",lk="undefined"==typeof window?null:window,uk=!1,hk=lk&&lk.document;function ck(t){return rk(t)}if(hk&&!v.canvasSupported)try{hk.namespaces.zrvml||hk.namespaces.add("zrvml",sk),rk=function(t){return hk.createElement("')}}catch(t){rk=function(t){return hk.createElement("<"+t+' xmlns="'+sk+'" class="zrvml">')}}var dk,fk=rr.CMD,pk=Math.round,gk=Math.sqrt,mk=Math.abs,vk=Math.cos,yk=Math.sin,xk=Math.max;if(!v.canvasSupported){var _k=",",wk="progid:DXImageTransform.Microsoft",bk=21600,Sk=bk/2,Mk=function(t){t.style.cssText="position:absolute;left:0;top:0;width:1px;height:1px;",t.coordsize=bk+","+bk,t.coordorigin="0,0"},Ik=function(t,e,i){return"rgb("+[t,e,i].join(",")+")"},Tk=function(t,e){e&&t&&e.parentNode!==t&&t.appendChild(e)},Ak=function(t,e){e&&t&&e.parentNode===t&&t.removeChild(e)},Dk=function(t,e,i){return 1e5*(parseFloat(t)||0)+1e3*(parseFloat(e)||0)+i},Ck=Yn,Lk=function(t,e,i){var n=Fe(e);i=+i,isNaN(i)&&(i=1),n&&(t.color=Ik(n[0],n[1],n[2]),t.opacity=i*n[3])},kk=function(t,e,i,n){var o="fill"===e,a=t.getElementsByTagName(e)[0];null!=i[e]&&"none"!==i[e]&&(o||!o&&i.lineWidth)?(t[o?"filled":"stroked"]="true",i[e]instanceof cs&&Ak(t,a),a=a||ck(e),o?function(t,e,i){var n,o,a=e.fill;if(null!=a)if(a instanceof cs){var r,s=0,l=[0,0],u=0,h=1,c=i.getBoundingRect(),d=c.width,f=c.height;if("linear"===a.type){r="gradient";var p=i.transform,g=[a.x*d,a.y*f],m=[a.x2*d,a.y2*f];p&&(bt(g,g,p),bt(m,m,p));var v=m[0]-g[0],y=m[1]-g[1];(s=180*Math.atan2(v,y)/Math.PI)<0&&(s+=360),s<1e-6&&(s=0)}else{r="gradientradial";g=[a.x*d,a.y*f],p=i.transform;var x=i.scale,_=d,w=f;l=[(g[0]-c.x)/_,(g[1]-c.y)/w],p&&bt(g,g,p),_/=x[0]*bk,w/=x[1]*bk;var b=xk(_,w);u=0/b,h=2*a.r/b-u}var S=a.colorStops.slice();S.sort(function(t,e){return t.offset-e.offset});for(var M=S.length,I=[],T=[],A=0;A=c&&d<=i+1){for(var n=[],o=0;o=c&&d<=o+1)return _P(h,e.components,u,l);p[t]=e}else p[t]=void 0}var s;f++}for(;f<=e;){var r=a();if(r)return r}},pushComponent:function(t,e,i){var n=t[t.length-1];n&&n.added===e&&n.removed===i?t[t.length-1]={count:n.count+1,added:e,removed:i}:t.push({count:1,added:e,removed:i})},extractCommon:function(t,e,i,n){for(var o=e.length,a=i.length,r=t.newPos,s=r-n,l=0;r+1\n\r<"))}},R(["getLayer","insertLayer","eachLayer","eachBuiltinLayer","eachOtherLayer","getLayers","modLayer","delLayer","clearLayer","pathToImage"],function(t){OP.prototype[t]=function(t){return function(){vi('In SVG mode painter not support method "'+t+'"')}}(t)}),Po("svg",OP),t.version="4.9.0",t.dependencies={zrender:"4.3.2"},t.PRIORITY=Ld,t.init=function(t,e,i){var n=mf(t);if(n)return n;var o=new Ed(t,e,i);return o.id="ec_"+cf++,uf[o.id]=o,Jo(t,ff,o.id),function(n){var o="__connectUpdateStatus";function a(t,e){for(var i=0;i3?0:(e-e%10!=10)*e%10]}};var g={D:function(e){return e.getDay()},DD:function(e){return d(e.getDay())},Do:function(e,t){return t.DoFn(e.getDate())},d:function(e){return e.getDate()},dd:function(e){return d(e.getDate())},ddd:function(e,t){return t.dayNamesShort[e.getDay()]},dddd:function(e,t){return t.dayNames[e.getDay()]},M:function(e){return e.getMonth()+1},MM:function(e){return d(e.getMonth()+1)},MMM:function(e,t){return t.monthNamesShort[e.getMonth()]},MMMM:function(e,t){return t.monthNames[e.getMonth()]},yy:function(e){return d(String(e.getFullYear()),4).substr(2)},yyyy:function(e){return d(e.getFullYear(),4)},h:function(e){return e.getHours()%12||12},hh:function(e){return d(e.getHours()%12||12)},H:function(e){return e.getHours()},HH:function(e){return d(e.getHours())},m:function(e){return e.getMinutes()},mm:function(e){return d(e.getMinutes())},s:function(e){return e.getSeconds()},ss:function(e){return d(e.getSeconds())},S:function(e){return Math.round(e.getMilliseconds()/100)},SS:function(e){return d(Math.round(e.getMilliseconds()/10),2)},SSS:function(e){return d(e.getMilliseconds(),3)},a:function(e,t){return e.getHours()<12?t.amPm[0]:t.amPm[1]},A:function(e,t){return e.getHours()<12?t.amPm[0].toUpperCase():t.amPm[1].toUpperCase()},ZZ:function(e){var t=e.getTimezoneOffset();return(t>0?"-":"+")+d(100*Math.floor(Math.abs(t)/60)+Math.abs(t)%60,4)}},b={d:["\\d\\d?",function(e,t){e.day=t}],Do:["\\d\\d?"+o,function(e,t){e.day=parseInt(t,10)}],M:["\\d\\d?",function(e,t){e.month=t-1}],yy:["\\d\\d?",function(e,t){var i=+(""+(new Date).getFullYear()).substr(0,2);e.year=""+(t>68?i-1:i)+t}],h:["\\d\\d?",function(e,t){e.hour=t}],m:["\\d\\d?",function(e,t){e.minute=t}],s:["\\d\\d?",function(e,t){e.second=t}],yyyy:["\\d{4}",function(e,t){e.year=t}],S:["\\d",function(e,t){e.millisecond=100*t}],SS:["\\d{2}",function(e,t){e.millisecond=10*t}],SSS:["\\d{3}",function(e,t){e.millisecond=t}],D:["\\d\\d?",u],ddd:[o,u],MMM:[o,h("monthNamesShort")],MMMM:[o,h("monthNames")],a:[o,function(e,t,i){var n=t.toLowerCase();n===i.amPm[0]?e.isPm=!1:n===i.amPm[1]&&(e.isPm=!0)}],ZZ:["[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z",function(e,t){var i,n=(t+"").match(/([+-]|\d\d)/gi);n&&(i=60*n[1]+parseInt(n[2],10),e.timezoneOffset="+"===n[0]?i:-i)}]};b.dd=b.d,b.dddd=b.ddd,b.DD=b.D,b.mm=b.m,b.hh=b.H=b.HH=b.h,b.MM=b.M,b.ss=b.s,b.A=b.a,s.masks={default:"ddd MMM dd yyyy HH:mm:ss",shortDate:"M/D/yy",mediumDate:"MMM d, yyyy",longDate:"MMMM d, yyyy",fullDate:"dddd, MMMM d, yyyy",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},s.format=function(e,t,i){var n=i||s.i18n;if("number"==typeof e&&(e=new Date(e)),"[object Date]"!==Object.prototype.toString.call(e)||isNaN(e.getTime()))throw new Error("Invalid Date in fecha.format");t=s.masks[t]||t||s.masks.default;var r=[];return(t=(t=t.replace(l,function(e,t){return r.push(t),"@@@"})).replace(a,function(t){return t in g?g[t](e,n):t.slice(1,t.length-1)})).replace(/@@@/g,function(){return r.shift()})},s.parse=function(e,t,i){var n=i||s.i18n;if("string"!=typeof t)throw new Error("Invalid format in fecha.parse");if(t=s.masks[t]||t,e.length>1e3)return null;var r={},o=[],u=[];t=t.replace(l,function(e,t){return u.push(t),"@@@"});var c,h=(c=t,c.replace(/[|\\{()[^$+*?.-]/g,"\\$&")).replace(a,function(e){if(b[e]){var t=b[e];return o.push(t[1]),"("+t[0]+")"}return e});h=h.replace(/@@@/g,function(){return u.shift()});var d=e.match(new RegExp(h,"i"));if(!d)return null;for(var p=1;pe?u():!0!==t&&(r=setTimeout(n?function(){r=void 0}:u,void 0===n?e-o:e))}}},function(e,t){var i=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=i)},function(e,t){var i=/^(attrs|props|on|nativeOn|class|style|hook)$/;function n(e,t){return function(){e&&e.apply(this,arguments),t&&t.apply(this,arguments)}}e.exports=function(e){return e.reduce(function(e,t){var r,s,a,o,l;for(a in t)if(r=e[a],s=t[a],r&&i.test(a))if("class"===a&&("string"==typeof r&&(l=r,e[a]=r={},r[l]=!0),"string"==typeof s&&(l=s,t[a]=s={},s[l]=!0)),"on"===a||"nativeOn"===a||"hook"===a)for(o in s)r[o]=n(r[o],s[o]);else if(Array.isArray(r))e[a]=r.concat(s);else if(Array.isArray(s))e[a]=[r].concat(s);else for(o in s)r[o]=s[o];else e[a]=t[a];return e},{})}},function(e,t){var i={}.hasOwnProperty;e.exports=function(e,t){return i.call(e,t)}},function(e,t,i){"use strict";t.__esModule=!0;var n,r=i(56),s=(n=r)&&n.__esModule?n:{default:n};t.default=s.default||function(e){for(var t=1;t0?n:i)(e)}},function(e,t,i){var n=i(28)("keys"),r=i(21);e.exports=function(e){return n[e]||(n[e]=r(e))}},function(e,t,i){var n=i(14),r=i(5),s=r["__core-js_shared__"]||(r["__core-js_shared__"]={});(e.exports=function(e,t){return s[e]||(s[e]=void 0!==t?t:{})})("versions",[]).push({version:n.version,mode:i(20)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t){e.exports={}},function(e,t,i){var n=i(10).f,r=i(7),s=i(13)("toStringTag");e.exports=function(e,t,i){e&&!r(e=i?e:e.prototype,s)&&n(e,s,{configurable:!0,value:t})}},function(e,t,i){t.f=i(13)},function(e,t,i){var n=i(5),r=i(14),s=i(20),a=i(33),o=i(10).f;e.exports=function(e){var t=r.Symbol||(r.Symbol=s?{}:n.Symbol||{});"_"==e.charAt(0)||e in t||o(t,e,{value:a.f(e)})}},function(e,t,i){var n=i(4),r=i(1);e.exports={throttle:n,debounce:r}},function(e,t,i){e.exports=!i(11)&&!i(16)(function(){return 7!=Object.defineProperty(i(37)("div"),"a",{get:function(){return 7}}).a})},function(e,t,i){var n=i(15),r=i(5).document,s=n(r)&&n(r.createElement);e.exports=function(e){return s?r.createElement(e):{}}},function(e,t,i){var n=i(7),r=i(12),s=i(62)(!1),a=i(27)("IE_PROTO");e.exports=function(e,t){var i,o=r(e),l=0,u=[];for(i in o)i!=a&&n(o,i)&&u.push(i);for(;t.length>l;)n(o,i=t[l++])&&(~s(u,i)||u.push(i));return u}},function(e,t,i){var n=i(40);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==n(e)?e.split(""):Object(e)}},function(e,t){var i={}.toString;e.exports=function(e){return i.call(e).slice(8,-1)}},function(e,t,i){var n=i(25);e.exports=function(e){return Object(n(e))}},function(e,t,i){"use strict";var n=i(20),r=i(23),s=i(43),a=i(9),o=i(31),l=i(69),u=i(32),c=i(72),h=i(13)("iterator"),d=!([].keys&&"next"in[].keys()),p=function(){return this};e.exports=function(e,t,i,f,m,v,g){l(i,t,f);var b,y,w,_=function(e){if(!d&&e in S)return S[e];switch(e){case"keys":case"values":return function(){return new i(this,e)}}return function(){return new i(this,e)}},x=t+" Iterator",C="values"==m,k=!1,S=e.prototype,D=S[h]||S["@@iterator"]||m&&S[m],$=D||_(m),E=m?C?_("entries"):$:void 0,T="Array"==t&&S.entries||D;if(T&&(w=c(T.call(new e)))!==Object.prototype&&w.next&&(u(w,x,!0),n||"function"==typeof w[h]||a(w,h,p)),C&&D&&"values"!==D.name&&(k=!0,$=function(){return D.call(this)}),n&&!g||!d&&!k&&S[h]||a(S,h,$),o[t]=$,o[x]=p,m)if(b={values:C?$:_("values"),keys:v?$:_("keys"),entries:E},g)for(y in b)y in S||s(S,y,b[y]);else r(r.P+r.F*(d||k),t,b);return b}},function(e,t,i){e.exports=i(9)},function(e,t,i){var n=i(17),r=i(70),s=i(29),a=i(27)("IE_PROTO"),o=function(){},l=function(){var e,t=i(37)("iframe"),n=s.length;for(t.style.display="none",i(71).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" \ No newline at end of file diff --git a/src/main/resources/templates/layout/default.ftl b/src/main/resources/templates/layout/default.ftl index fa93dd2..ac31e87 100644 --- a/src/main/resources/templates/layout/default.ftl +++ b/src/main/resources/templates/layout/default.ftl @@ -1,7 +1,7 @@ - + ${title?default("管理系统")} diff --git a/src/main/resources/templates/nginx.conf.ftl b/src/main/resources/templates/nginx.conf.ftl deleted file mode 100644 index 461fab3..0000000 --- a/src/main/resources/templates/nginx.conf.ftl +++ /dev/null @@ -1,66 +0,0 @@ - -#user nobody; -worker_processes 1; - -#error_log logs/error.log; -#error_log logs/error.log notice; -#error_log logs/error.log info; - -#pid logs/nginx.pid; - - -events { - worker_connections 1024; -} - - -http { - include mime.types; - default_type application/octet-stream; - - #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - # '$status $body_bytes_sent "$http_referer" ' - # '"$http_user_agent" "$http_x_forwarded_for"'; - - #access_log logs/access.log main; - - sendfile on; - #tcp_nopush on; - - #keepalive_timeout 0; - keepalive_timeout 65; - - #gzip on; -<#list services?keys as key> - - server { - listen ${key}; - server_name localhost; - -<#list services[key] as mapping> -<#if mapping.type="HTTP"> - location ${mapping.path} { - proxy_pass ${mapping.location}; - proxy_set_header Host $remote_addr:$server_port; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header request_uri $scheme://$remote_addr:$server_port$request_uri; - proxy_set_header proxy_context ${mapping.path}; - index index.html index.htm index.jsp index.do; - } -<#elseif mapping.type="FILE"> - location ${mapping.path} { - root ${mapping.location}; - index index.html index.htm; - autoindex on; - } - - - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root html; - } - } - -} diff --git a/src/main/resources/templates/screen/admin/config.ftl b/src/main/resources/templates/screen/admin/config.ftl new file mode 100644 index 0000000..94a2dfe --- /dev/null +++ b/src/main/resources/templates/screen/admin/config.ftl @@ -0,0 +1,289 @@ +
+ + +
+ + + <#if token.hasRes("/ajax/admin/config/create")> + 新增 + + <#if token.hasRes("/ajax/admin/config/delete")> + 删除 + + + + + <#if token.hasRes("/ajax/admin/config/template")> + + + + + + <#if token.hasRes("/ajax/admin/config/imports")> + + + + + + <#if token.hasRes("/ajax/admin/config/exports")> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + 取消 + 保存 + + +
+ diff --git a/src/main/resources/templates/screen/admin/locations.ftl b/src/main/resources/templates/screen/admin/locations.ftl new file mode 100644 index 0000000..7b4f8d7 --- /dev/null +++ b/src/main/resources/templates/screen/admin/locations.ftl @@ -0,0 +1,355 @@ +
+ + +
+ + + <#if token.hasRes("/ajax/admin/locations/create")> + 新增 + + <#if token.hasRes("/ajax/admin/locations/delete")> + 删除 + + + + + <#if token.hasRes("/ajax/admin/locations/template")> + + + + + + <#if token.hasRes("/ajax/admin/locations/imports")> + + + + + + <#if token.hasRes("/ajax/admin/locations/exports")> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 取消 + 保存 + + +
+ diff --git a/src/main/resources/templates/screen/helpDev.ftl b/src/main/resources/templates/screen/helpDev.ftl new file mode 100644 index 0000000..f2e31fd --- /dev/null +++ b/src/main/resources/templates/screen/helpDev.ftl @@ -0,0 +1,1591 @@ +
+ + + +
+ 主要颜色 +
+ + +
Success +
#409EFF
+
+
+ +
Success +
#67C23A
+
+
+ +
Warning +
#E6A23C
+
+
+ +
Danger +
#F56C6C
+
+
+ +
Info +
#909399
+
+
+
+
+ +
+ 中性色 +
+ + +
+
+ 主要文字 +
#303133
+
+
+ 常规文字 +
#606266
+
+
+ 次要文字 +
#909399
+
+
+ 占位文字 +
#C0C4CC
+
+
+
+ +
+
+ +
+
一级边框 +
#DCDFE6
+
+
二级边框 +
#E4E7ED
+
+
三级边框 +
#EBEEF5
+
+
四级边框 +
#F2F6FC
+
+
+
+
+
+
+ + + +

主要框架

+ +
    +
  1. + SpringBoot v2.1.2.RELEASE +
  2. +
  3. + Ehcache v-2.6.11 缓存框架 +
  4. +
  5. + Freemarker v2.1.2.RELEASE + Html模板引擎 +
  6. +
  7. + pagehelper v1.2.5 + 分页插件、提供便捷的分页功能 +
  8. +
  9. + dozer v5.5.1 + 对象复制拷贝 +
  10. +
  11. + logback v1.2.3 + 日志框架 +
  12. +
  13. + easyexcel 2.2.6 + EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。 +
  14. +
  15. + jQuery v3.2.1 + 前端JavaScript框架(保留),打包进base.min.js,但请尽量勿使用jQuery直接操作Dom +
  16. +
  17. + Vue v2.5.17 + DOM渲染引擎 +
  18. +
  19. + ElementUI v2.8.2 + 前端UI框架,提供统一风格控件 +
  20. +
  21. + Maven + 后端构建管理工具 +
  22. +
  23. + JDK 8+ + SpringBoot2.x开始不再支持JDK 7及以下,所以请将JDk升级到8+ +
  24. +
+ +

+
+ + + + +
+ 占位输出 +
+ +

正常输出 + ${r'${hello}'} +

+ +

输出带默认值 + ${r'${hello?default("默认")}'} +

+ +

HTML输出 + ${r"${'<a>a标签</a>'?html}"} +

+ +

$表达式 + ${r"${r'${hello}'}"} +

+ +

布尔值输出 + ${r"${true?c}"} +

+ +

三元表达式 + ${r"${true?string('yes','no')}"} +

+ +

输出当前日期 + ${r'${.now?string["yyyy-MM-dd HH:mm:ss"]}'} +

+ +
+ + + +
+ 条件输出 +
+ +

${'<#if status == 0>'}

+ +

status is 0

+ +

${'<#elseif status ==1>'}

+ +

status = 1

+ +

${'<#else>'}

+ +

status != 0 && status !=1

+ +

${'</#if>'}

+ +
+ + + + +
+ 遍历集合 +
+ +

${'<#list citys as city>'}

+ +

${r' ${city_index} --> ${city}'}

+ +

${'</#list>'}

+ +
+ +
+ + + +
+

1、表单控件集合及验证

+
+ + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 立即创建 + 重置 + + + +
+ +
+

2、表格数据

+
+ + + + + + + + + + + + + + + + +
+ + +
+

3、分页

+
+ + + + +
+ + +
+

4、按钮

+
+ + + 默认按钮 + 主要按钮 + 成功按钮 + 信息按钮 + 警告按钮 + 危险按钮 + + + + 朴素按钮 + 主要按钮 + 成功按钮 + 信息按钮 + 警告按钮 + 危险按钮 + + + + 圆角按钮 + 主要按钮 + 成功按钮 + 信息按钮 + 警告按钮 + + + + 危险按钮 + 加载中 + + + + + + + + + + 默认按钮 + 主要按钮 + 成功按钮 + 信息按钮 + 警告按钮 + 危险按钮 + + + + 朴素按钮 + 主要按钮 + 成功按钮 + 信息按钮 + 警告按钮 + 危险按钮 + + + 文字按钮 + 文字按钮 + + + + + + 搜索 + 上传 + + + + + 上一页 + 下一页 + + + + + + + + + + 默认按钮 + 中等按钮 + 小型按钮 + 超小按钮 + + + 默认按钮 + 中等按钮 + 小型按钮 + 超小按钮 + + +
+ +
+

5、Link 文字链接

+
+ + + 默认链接 + 主要链接 + 成功链接 + 警告链接 + 危险链接 + 信息链接 + + + + 默认链接 + 主要链接 + 成功链接 + 警告链接 + 危险链接 + 信息链接 + + + + 无下划线 + 有下划线 + 编辑 + 查看 + + +
+ +
+

6、Tabs 标签页

+
+ + + 用户管理 + 配置管理 + 角色管理 + 定时任务补偿 + + +

+ Tabs位置共有4个位置分别为: + + top + + right + + bottom + + left + +

+
+ +
+

7、弹框、对话框、通知

+
+ + + + 消息 + + + 通知 + + + 消息Box + + + 消息确认Box + + + + hover 激活 + + + + + 对话框Dialog + + + 这是一段信息 + + 取 消 + 确 定 + + + + + +
+ + +
+

6、其他小控件

+
+ + + + + + + + + + + + + 标签一 + 标签二 + 标签三 + 标签四 + 标签五 + + + + 标签一 + 标签二 + 标签三 + 标签四 + 标签五 + + + + 默认标签 + 中等标签 + 小型标签 + 超小标签 + + + + + 评论 + + + 回复 + + + 评论 + + + 回复 + + + 数据查询 + + + + + + + + 评论(最大值) + + + 回复(最大值) + + + + 评论 + + + 回复 + + + + + + + + + + + + + + + + + + 首页 + 活动管理 + 活动列表 + 活动详情 + + + + + + 下拉菜单 + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + + + 默认尺寸 + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + + + 中等尺寸 + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + + + 小型尺寸 + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + + + 超小尺寸 + + 黄金糕 + 狮子头 + 螺蛳粉 + 双皮奶 + 蚵仔煎 + + + + + 头上一片晴天,心中一个想念 + 少年包青天 + 饿了别叫妈, 叫饿了么 + + 为了无法计算的价值 + 阿里云 + + + + 雨纷纷 + + 旧故里 + + 草木深 + + +
+ +
+ + + + + +
+

Vue动画

+
+ +

淡入动画

+ +

${''?html}

+

${''?html}

+ +

zoom 缩放

+ +

${''?html}

+

${''?html}

+

${''?html}

+ +

折叠动画

+ +

${''?html}

+ +

左进右出动画

+ +

${''?html}

+ +

右进左出动画

+ +

${''?html}

+ +
+ + +
+

CSS动画

+
+ +

淡入动画

+ +

${'

'?html}

+ +

淡出动画

+ +

${'

'?html}

+ +

从底部淡入动画

+ +

${'

'?html}

+ +

从顶部淡出动画

+ +

${'

'?html}

+ +

震颤(抖动)动画

+ +

${'

'?html}

+ +

无限旋转动画

+ +

${'

'?html}

+ +
+
+ + + + + + 调用AJAX接口 + + + +
new Ajax("wadmin", "user", "find").post({}, function (response) {
+
    if (response.errors.length > 0) {
+
        nav.e(response.errors[0].message);
+
    } else {
+
        nav.i("Ajax调用成功!");
+
    }
+
}.bind(this))
+
+ + + + 点击上传 +
只能上传jpg/png文件,且不超过500kb
+
+ + + +
new Ajax("wadmin","file","upload").post(req.file,function (response) {
+
    if (response.errors.length > 0) {
+
        req.onError();
+
        nav.e(response.errors[0].message);
+
    } else {
+
        req.onSuccess();
+
        nav.i("文件上传成功!");
+
    }
+
}.bind(this))
+
+ +
+ + + + + + 开始推送 + + 停止推送 + + + +

var evtSource = new EventSource('http://localhost:8080/sse/1');

+ +

evtSource.addEventListener('message', function (e) {

+ +

console.log(e.data);

+ +

});

+ +
+
+ + + + 普通消息 + 错误消息 + 成功消息 + 警告消息 + + + +
 nav.i('消息')
+
 nav.e('错误')
+
 nav.s('成功')
+
 nav.w('警告')
+
+ + + 加载提示框 + 关闭提示框 + + + +
nav.tipShow('加载中')
+
nav.tipClose()
+
+ + + 请求进度条 + 成功 + 失败 +
1、最终调用index对象的barStart(),barFinish(),barError(); + + + +
nav.barShow()
+
nav.barFinish()
+
nav.barError()
+
+ + + 简单对话框(确认) + 示例 +
+ 简单对话框(确认取消) + 示例 +
+ 简单对话框(输入) + 示例 +
+ 简单对话框(HTML) + 示例 + + + +
nav.boxYes(title, message, callback)
+
nav.boxYesNo(title, message, callback)
+
nav.boxInput(title, message, callback)
+
nav.boxHtml(title, htmlMessage, callback)
+
+ + + 切换网页全屏,取消网页全屏 + 全屏 + 取消全屏 + + + +
nav.screenFull()
+
nav.screenNotFull()
+
+ + + 设置Cookie + + + +
nav.setCookie(name, value, expiretime)
+
nav.getCookie(name)
+
nav.clearCookie(name)
+
+
+ + + + 回到或打开HOME页 + + + +
index.onHome()
+
+ + + 请求进度条 + + + +
index.barStart()
+
index.barFinish()
+
index.barError()
+
+ + + 左侧菜单收缩切换方法 + + + +
index.collapseSwitch()
+
+ + + 网页全屏切换方法 +
1、最终调用nav对象的nav.screenFull()和nav.screenNotFull() + + + +
index.switchFullScreen()
+
+ + + 添加新Tab + + + +
var tab = {
+
    title: '首页',
+
    name: 'home',
+
    url: '/home.htm'
+
}
+
index.addTab(tab)
+
+ + + 移除Tab + + + +
index.removeTab(tabName)
+
+
+ + + 所有js相关基本方法皆以打包进lib.min.js文件 + + + 获取url参数 + + + +
$.getSearchParam('id')
+
+ + + 打开游览器新标签 + + + +
$w.openUrl('www.baidu.com')
+
+ + + 日期格式化 + + + +
new Date().format('yyyy-MM-dd hh:mm:ss')
+
+ + + 数组移除 + + + +
var arr = ['A', 'B'];
+
arr.remove('A')
+
+ + + 数组替换 + + + +
var arr = ['A', 'B'];
+
arr.replace('A', 'C')
+
+ + + 数组位置调整 + + + +
var arr = ['A', 'B'];
+
arr.exchange(0, 1)
+
+ + + 数组异步循环 + + + +
var arr = ['A', 'B'];
+
arr.forAsync(function (item, next) {
+
    setTimeout(function () {
+
        console.log(item);
+
        next();
+
    }, 1000)
+
})
+
+ + + 数组异步循环(完成通知) + + + +
var arr = ['A', 'B'];
+
arr.forAsync(function (item, next) {
+
    setTimeout(function () {
+
        console.log(item);
+
        next();
+
    }, 1000)
+
}, function () {
+
    nav.i("异步循环完成.");
+
})
+
+ + + 数组递归循环 +
1、forTree第二参数为子类属性,默认为[children] + + + +
var arr = [{
+
    name: 'A',
+
    children: [
+
        {name: 'AA'},
+
        {name: 'AB'},
+
    ]
+
}]
+
arr.forTree(function (item) {
+
    console.log(item.name)
+
})
+
+ + + 数组递归循环(处理函数可以知道当前循环深度) + + + +
var arr = [{
+
    name: 'A',
+
    children: [
+
        {name: 'AA'},
+
        {name: 'AB'},
+
    ]
+
}]
+
arr.forTreeDepth(function (item, depth) {
+
    console.log(item.name);
+
    console.log(depth);//[0],[0, 0],[0, 1]
+
})
+
+ + + 自定义Map对象 +
1、放置对象 map.put(key, value) +
2、获取对象 map.get(key) +
3、获取键集合 map.getKeys() +
4、获取对象集合 map.getValues() +
5、移除对象 map.remove(key) +
6、返回大小 map.size() +
7、判断是否为空 map.isEmpty() +
8、清空 map.clear() +
9、是否包含键 map.containsKey(key) +
10、是否包含值 map.containsValue(value) +
11、循环 map.forEach(callBack) // 函数接收两个参数(key, value) +
12、异步循环 map.forAsync(callBack, finish) // 函数接收两个参数(key, value),完成函数(可选) + + + +
var map = new Map();
+
map.put("name", "hello world!");
+
console.log(map.get("name"));
+
+ + + 文件选择 $w.selectFile(cb) + + + +
$w.selectFile(function (files) {
+
    new Ajax("wadmin","file","upload").post(files[0],function (response) {
+
        if (response.errors.length > 0) {
+
            nav.e(response.errors[0].message);
+
        } else {
+
            nav.i("文件上传成功!");
+
        }
+
    })
+
})
+
+ + + Blob二进制文件异步下载 + + + +
$w.blobtoDown(name, blob)
+
+ + + base64转为String + + + +
$w.base64toString(base64)
+
+ + + String转为base64 + + + +
$w.stringtoBase64(str)
+
+ + + base64转为字节数组 + + + +
$w.base64toBytes(base64)
+
+ + + base64字符转Blob对象 + + + +
$w.base64toBlob(base64)
+
+ + + 动态加载Js或css文件 + + + +
$w.loadJsCss(url)
+
+ + + 深拷贝对象 + + + +
$w.copy(obj)
+
+
+ + + +
+

1、页面初始化前闪现源代码

+
+ +

${''?html}

+ + +

${'

'?html}

+ +

${'...'?html}

+ +

${'

'?html}

+
+ + +
+

2、为什么Long类型返回json字符串变为String

+
+ +

因为Long可支持的长度比JavaScript中Number支持的位数更多,所以当Long数值很大时转为Json再转为Number就会丢失精度,造成难以发现的Bug,所以本系统默认处理了该问题。

+
+ + +
+

3、Date类型格式化问题

+
+ +

默认启用全局Date格式化 + yyyy-MM-dd HH:mm:ss + ,需要关闭请在 + application-* + 中关闭。 +

+ +

对于个别返回结果的Date格式化可以通过注解方式 + @JsonFormat(pattern = "yyyy-MM-dd") +

+ +
+ + +
+

4、权限问题

+
+ +

1、本系统启用自定义Token来控制权限,任何访问都会有一个全局Token,任何一处都可以通过 + LocalData.getToken() + 来获取 + 当前访问对象的Token。其中Token充当着访问对象的通行证,其中包含访问对象的 + 用户ID + 、 + 用户名 + 、 + 可访问资源 + 等信息。 +

+ +

2、对于未登录对象会提供临时(访客) + LocalData.getTempToken() + (有限的权限)来提供访问系统。 +

+ +

3、如果系统存在Task等定时任务时,是不存在访问对象,通过 + LocalData.getSystemToken() + 来获取系统层的Token来操作系统。 +

+ +
+ + +
+

5、Token配置

+
+ +

Springboot环境配置文件application-*中配置了系统中需要验证权限和不需要验证的url。而需要验证权限的URl会在 + SecurityConfig.getAuthorization() + 方法中通过Parameter或Cookies中获取当前访问对象的登录信息,从而为当前访问对象组装Token对象。 + +

+ +
+
+
+
+ + diff --git a/src/main/resources/templates/screen/login.ftl b/src/main/resources/templates/screen/login.ftl index fea5e3f..dd000a2 100644 --- a/src/main/resources/templates/screen/login.ftl +++ b/src/main/resources/templates/screen/login.ftl @@ -1,18 +1,39 @@ -
+
+ + +
diff --git a/src/test/java/xyz/wbsite/admin/ConfigDataTest.java b/src/test/java/xyz/wbsite/admin/ConfigDataTest.java new file mode 100644 index 0000000..2eae83e --- /dev/null +++ b/src/test/java/xyz/wbsite/admin/ConfigDataTest.java @@ -0,0 +1,116 @@ +package xyz.wbsite.admin; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.module.admin.mgr.ConfigDataManager; +import xyz.wbsite.module.admin.req.ConfigDataCreateRequest; +import xyz.wbsite.module.admin.req.ConfigDataDeleteRequest; +import xyz.wbsite.module.admin.req.ConfigDataFindRequest; +import xyz.wbsite.module.admin.req.ConfigDataUpdateRequest; +import xyz.wbsite.module.admin.rsp.ConfigDataCreateResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataDeleteResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataFindResponse; +import xyz.wbsite.module.admin.rsp.ConfigDataUpdateResponse; + +import static junit.framework.TestCase.assertTrue; + +/** + * ConfigDataTest - - 配置数据测试用例 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@Transactional +public class ConfigDataTest { + + @Autowired + private Token token; + + @Autowired + private ConfigDataManager configDataManager; + + @Test + public void testCreate() { + ConfigDataCreateRequest request = new ConfigDataCreateRequest(); + request.setTargetId(1L); + request.setConfName("配置名称"); + request.setConfType("value"); + request.setConfValue("配置属值"); + request.setConfNote("配置备注"); + + ConfigDataCreateResponse response = configDataManager.create(request,token); + + assertTrue(!response.hasError()); + } + + @Test + public void testDelete() { + + //创建数据 + ConfigDataCreateRequest createRequest = new ConfigDataCreateRequest(); + createRequest.setTargetId(1L); + createRequest.setConfName("配置名称"); + createRequest.setConfType("value"); + createRequest.setConfValue("配置属值"); + createRequest.setConfNote("配置备注"); + + ConfigDataCreateResponse createResponse = configDataManager.create(createRequest,token); + + assertTrue(!createResponse.hasError() && createResponse.getId() > 0); + //删除数据 + ConfigDataDeleteRequest request = new ConfigDataDeleteRequest(); + request.setId(createResponse.getId()); + + ConfigDataDeleteResponse response = configDataManager.delete(request,token); + + assertTrue(!response.hasError() && response.getResult() == 1L); + } + + @Test + public void testUpdate() { + //创建数据 + ConfigDataCreateRequest createRequest = new ConfigDataCreateRequest(); + createRequest.setTargetId(1L); + createRequest.setConfName("配置名称"); + createRequest.setConfType("value"); + createRequest.setConfValue("配置属值"); + createRequest.setConfNote("配置备注"); + + ConfigDataCreateResponse createResponse = configDataManager.create(createRequest, token); + + assertTrue(!createResponse.hasError()); + + //更新数据 + ConfigDataUpdateRequest request = new ConfigDataUpdateRequest(); + request.setId(createResponse.getId()); + request.setTargetId(1L); + request.setConfName("配置名称"); + request.setConfType("value"); + request.setConfValue("配置属值"); + request.setConfNote("配置备注"); + + ConfigDataUpdateResponse response = configDataManager.update(request,token); + + assertTrue(!response.hasError() && response.getResult() == 1L); + } + + @Test + public void testFind() { + ConfigDataFindRequest request = new ConfigDataFindRequest(); + request.setTargetId(1L); + request.setConfName("配置名称"); + request.setConfType("value"); + + ConfigDataFindResponse response = configDataManager.find(request,token); + + assertTrue(!response.hasError()); + } +} diff --git a/src/test/java/xyz/wbsite/admin/ConfigTest.java b/src/test/java/xyz/wbsite/admin/ConfigTest.java new file mode 100644 index 0000000..c2cd94d --- /dev/null +++ b/src/test/java/xyz/wbsite/admin/ConfigTest.java @@ -0,0 +1,111 @@ +package xyz.wbsite.admin; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.module.admin.mgr.ConfigManager; +import xyz.wbsite.module.admin.req.ConfigCreateRequest; +import xyz.wbsite.module.admin.req.ConfigDeleteRequest; +import xyz.wbsite.module.admin.req.ConfigFindRequest; +import xyz.wbsite.module.admin.req.ConfigUpdateRequest; +import xyz.wbsite.module.admin.rsp.ConfigCreateResponse; +import xyz.wbsite.module.admin.rsp.ConfigDeleteResponse; +import xyz.wbsite.module.admin.rsp.ConfigFindResponse; +import xyz.wbsite.module.admin.rsp.ConfigUpdateResponse; + +import static junit.framework.TestCase.assertTrue; + +/** + * ConfigTest - - 配置预设测试用例 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@Transactional +public class ConfigTest { + + @Autowired + private Token token; + + @Autowired + private ConfigManager configManager; + + @Test + public void testCreate() { + ConfigCreateRequest request = new ConfigCreateRequest(); + request.setConfName("配置名称"); + request.setConfType("value"); + request.setConfValue("配置属值"); + request.setConfNote("配置备注"); + + ConfigCreateResponse response = configManager.create(request,token); + + assertTrue(!response.hasError()); + } + + @Test + public void testDelete() { + + //创建数据 + ConfigCreateRequest createRequest = new ConfigCreateRequest(); + createRequest.setConfName("配置名称"); + createRequest.setConfType("value"); + createRequest.setConfValue("配置属值"); + createRequest.setConfNote("配置备注"); + + ConfigCreateResponse createResponse = configManager.create(createRequest,token); + + assertTrue(!createResponse.hasError() && createResponse.getId() > 0); + //删除数据 + ConfigDeleteRequest request = new ConfigDeleteRequest(); + request.setId(createResponse.getId()); + + ConfigDeleteResponse response = configManager.delete(request,token); + + assertTrue(!response.hasError() && response.getResult() == 1L); + } + + @Test + public void testUpdate() { + //创建数据 + ConfigCreateRequest createRequest = new ConfigCreateRequest(); + createRequest.setConfName("配置名称"); + createRequest.setConfType("value"); + createRequest.setConfValue("配置属值"); + createRequest.setConfNote("配置备注"); + + ConfigCreateResponse createResponse = configManager.create(createRequest, token); + + assertTrue(!createResponse.hasError()); + + //更新数据 + ConfigUpdateRequest request = new ConfigUpdateRequest(); + request.setId(createResponse.getId()); + request.setConfName("配置名称"); + request.setConfType("value"); + request.setConfValue("配置属值"); + request.setConfNote("配置备注"); + + ConfigUpdateResponse response = configManager.update(request,token); + + assertTrue(!response.hasError() && response.getResult() == 1L); + } + + @Test + public void testFind() { + ConfigFindRequest request = new ConfigFindRequest(); + request.setConfName("配置名称"); + request.setConfType("value"); + + ConfigFindResponse response = configManager.find(request,token); + + assertTrue(!response.hasError()); + } +} diff --git a/src/test/java/xyz/wbsite/admin/ServicesTest.java b/src/test/java/xyz/wbsite/admin/ServicesTest.java new file mode 100644 index 0000000..876de5c --- /dev/null +++ b/src/test/java/xyz/wbsite/admin/ServicesTest.java @@ -0,0 +1,127 @@ +package xyz.wbsite.admin; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; +import xyz.wbsite.frame.base.Token; +import xyz.wbsite.module.admin.mgr.ServicesManager; +import xyz.wbsite.module.admin.req.ServicesCreateRequest; +import xyz.wbsite.module.admin.req.ServicesDeleteRequest; +import xyz.wbsite.module.admin.req.ServicesFindRequest; +import xyz.wbsite.module.admin.req.ServicesUpdateRequest; +import xyz.wbsite.module.admin.rsp.ServicesCreateResponse; +import xyz.wbsite.module.admin.rsp.ServicesDeleteResponse; +import xyz.wbsite.module.admin.rsp.ServicesFindResponse; +import xyz.wbsite.module.admin.rsp.ServicesUpdateResponse; + +import static junit.framework.TestCase.assertTrue; + +/** + * ServicesTest - - 虚拟主机测试用例 + * + * @author wangbing + * @version 0.0.1 + * @since 2021-02-07 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@Transactional +public class ServicesTest { + + @Autowired + private Token token; + + @Autowired + private ServicesManager servicesManager; + + @Test + public void testCreate() { + ServicesCreateRequest request = new ServicesCreateRequest(); + request.setTitle("主机标题"); + request.setDomain("主机域名"); + request.setType("value"); + request.setPort(1); + request.setValid(true); + request.setFilter(true); + request.setFilterConf("过滤配置"); + + ServicesCreateResponse response = servicesManager.create(request,token); + + assertTrue(!response.hasError()); + } + + @Test + public void testDelete() { + + //创建数据 + ServicesCreateRequest createRequest = new ServicesCreateRequest(); + createRequest.setTitle("主机标题"); + createRequest.setDomain("主机域名"); + createRequest.setType("value"); + createRequest.setPort(1); + createRequest.setValid(true); + createRequest.setFilter(true); + createRequest.setFilterConf("过滤配置"); + + ServicesCreateResponse createResponse = servicesManager.create(createRequest,token); + + assertTrue(!createResponse.hasError() && createResponse.getId() > 0); + //删除数据 + ServicesDeleteRequest request = new ServicesDeleteRequest(); + request.setId(createResponse.getId()); + + ServicesDeleteResponse response = servicesManager.delete(request,token); + + assertTrue(!response.hasError() && response.getResult() == 1L); + } + + @Test + public void testUpdate() { + //创建数据 + ServicesCreateRequest createRequest = new ServicesCreateRequest(); + createRequest.setTitle("主机标题"); + createRequest.setDomain("主机域名"); + createRequest.setType("value"); + createRequest.setPort(1); + createRequest.setValid(true); + createRequest.setFilter(true); + createRequest.setFilterConf("过滤配置"); + + ServicesCreateResponse createResponse = servicesManager.create(createRequest, token); + + assertTrue(!createResponse.hasError()); + + //更新数据 + ServicesUpdateRequest request = new ServicesUpdateRequest(); + request.setId(createResponse.getId()); + request.setTitle("主机标题"); + request.setDomain("主机域名"); + request.setType("value"); + request.setPort(1); + request.setValid(true); + request.setFilter(true); + request.setFilterConf("过滤配置"); + + ServicesUpdateResponse response = servicesManager.update(request,token); + + assertTrue(!response.hasError() && response.getResult() == 1L); + } + + @Test + public void testFind() { + ServicesFindRequest request = new ServicesFindRequest(); + request.setTitle("主机标题"); + request.setDomain("主机域名"); + request.setType("value"); + request.setPort(1); + request.setValid(true); + request.setFilter(true); + + ServicesFindResponse response = servicesManager.find(request,token); + + assertTrue(!response.hasError()); + } +} diff --git a/src/test/java/xyz/wbsite/config/TestConfig.java b/src/test/java/xyz/wbsite/config/TestConfig.java index e9222ce..8397358 100644 --- a/src/test/java/xyz/wbsite/config/TestConfig.java +++ b/src/test/java/xyz/wbsite/config/TestConfig.java @@ -1,11 +1,25 @@ package xyz.wbsite.config; -import xyz.wbsite.frame.auth.Token; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import xyz.wbsite.frame.base.LocalData; +import xyz.wbsite.frame.base.Token; + +import javax.annotation.PostConstruct; + @Configuration public class TestConfig { + @Autowired + private ApplicationContext applicationContext; + + @PostConstruct + public void initLocalData() { + LocalData.setContext(applicationContext); + } + @Bean public Token getTestToken() { Token token = new Token(); diff --git a/src/test/java/xyz/wbsite/wframe/ExcelTest.java b/src/test/java/xyz/wbsite/wframe/ExcelTest.java new file mode 100644 index 0000000..e940f31 --- /dev/null +++ b/src/test/java/xyz/wbsite/wframe/ExcelTest.java @@ -0,0 +1,74 @@ +package xyz.wbsite.wframe; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; +import xyz.wbsite.frame.excel.DemoData; +import xyz.wbsite.frame.excel.WExcel; +import xyz.wbsite.frame.excel.exception.TemplateNotMatchException; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * ExcelTest - - 测试用例 + * + * @author wangbing + * @version 0.0.1 + * @since 2017-01-01 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@Transactional +public class ExcelTest { + + @Test + public void testExcel() throws IOException, TemplateNotMatchException { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + System.out.println("数据创建开始:" + dateFormat.format(new Date())); + // 写 + List visitors = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + DemoData demoData = new DemoData(); + demoData.setStr1("我是标题Str1" + i); + demoData.setStr2("我是标题Str2" + i); + demoData.setStr3("我是标题Str3" + i); + demoData.setStr4("我是标题Str4" + i); + demoData.setSint((short) 1); + demoData.setMint(1); + demoData.setLint(1L); + demoData.setDbn(0.01); + demoData.setFln(0.01f); + demoData.setDate(new Date()); + demoData.setValid(i % 5 == 0); + visitors.add(demoData); + } + System.out.println("数据创建完成:" + dateFormat.format(new Date())); + new WExcel<>(DemoData.class).addDatas(visitors, null).toFile(new File("D:\\xx.xlsx")); + System.out.println("数据导出完成:" + dateFormat.format(new Date())); + + System.out.println(); + + // 读 + System.out.println("数据导入开始:" + dateFormat.format(new Date())); + WExcel wExcel = new WExcel<>(DemoData.class).read(new File("D:\\xx.xlsx"), (demoData, index) -> { + if (index % 50 == 0) { + return Arrays.asList("测试,第" + index + "条有错误"); + } + return null; + }); + System.out.println("数据导入完成:" + dateFormat.format(new Date())); + System.out.println(); + System.out.println("错误导出开始:" + dateFormat.format(new Date())); + wExcel.toFile(new File("D:\\xx-err.xlsx")); + System.out.println("错误导出结束:" + dateFormat.format(new Date())); + System.out.println(); + } +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index f07e94a..6420997 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -14,9 +14,9 @@ server.tomcat.uri-encoding=UTF-8 # 日志配置 logging.path=D:// logging.levels=DEBUG -# SQLite spring.datasource.url=jdbc:sqlite::resource:example.db +# SQLite spring.datasource.url=jdbc:sqlite::resource:example.db3 spring.datasource.driver-class-name=org.sqlite.JDBC -spring.datasource.url=jdbc:sqlite:nginx-admin.db?date_string_format=yyyy-MM-dd HH:mm:ss +spring.datasource.url=jdbc:sqlite:nginx-admin.db3?date_string_format=yyyy-MM-dd HH:mm:ss spring.datasource.username=test spring.datasource.password=123456 # mybatis @@ -33,6 +33,11 @@ spring.jackson.time-zone=GMT+8 spring.jackson.default-property-inclusion=non_null spring.jackson.mapper.sort-properties-alphabetically=true spring.jackson.deserialization.fail-on-unknown-properties=false +# 文件上传配置 +spring.servlet.multipart.resolveLazily=false +spring.servlet.multipart.max-file-size=100MB +spring.servlet.multipart.max-request-size=100MB +server.tomcat.max-http-post-size=-1 # freemarker spring.freemarker.enabled=true spring.freemarker.allow-request-override=false @@ -51,24 +56,16 @@ spring.freemarker.settings.number_format=#.## spring.freemarker.settings.classic_compatible=true spring.freemarker.settings.whitespace_stripping=true spring.freemarker.settings.url_escaping_charset=utf-8 -# 文件上传配置 -spring.servlet.multipart.resolveLazily=false -spring.servlet.multipart.max-file-size=100MB -spring.servlet.multipart.max-request-size=100MB -server.tomcat.max-http-post-size=-1 # 自定义配置 # 根路径默认页,'/'跳转至该页 -web.home.page=/index.htm +web.url.index=/index.htm # 登录页 -web.login.page=/login.htm +web.url.login=/login.htm # 拦截验证 web.url.auth.included=/,/**/*.htm,/ajax/**,/api/** # 直接放行 -web.url.auth.excluded=/login.htm,/ajax/system/User/login +web.url.auth.excluded=/login.htm,/ajax/wsys/User/login # 超级管理员 web.url.auth.admin=admin -web.url.auth.pwd=17fac3376f76d65943d1d26d1f7cb1e5 - -nginx-path= -mapping.default.port=80 \ No newline at end of file +web.url.auth.pwd=17fac3376f76d65943d1d26d1f7cb1e5 \ No newline at end of file diff --git a/wsqlite/src/main/java/xyz/wbsite/wsqlite/Client.java b/wsqlite/src/main/java/xyz/wbsite/wsqlite/Client.java deleted file mode 100644 index 0cfe64d..0000000 --- a/wsqlite/src/main/java/xyz/wbsite/wsqlite/Client.java +++ /dev/null @@ -1,144 +0,0 @@ -package xyz.wbsite.wsqlite; - -import java.io.File; -import java.sql.*; - -/** - * xyz.wbsite.wsqlite.Client - * - * @author wangbing - */ -public class Client { - - Connection connection; - ResultSet resultSet; - String dbFilePath; - - /** - * 构造函数 - * - * @param dbFile 文件 - * @throws ClassNotFoundException - * @throws SQLException - */ - public Client(File dbFile) throws ClassNotFoundException, SQLException { - this.dbFilePath = dbFile.getAbsolutePath(); - if (!dbFile.exists()) { - connection = getConnection(); - } - } - - /** - * 执行sql语句 - * - * @param sql - * @throws SQLException - * @throws ClassNotFoundException - */ - public void execute(String sql) throws SQLException, ClassNotFoundException { - try { - executeUpdate(sql); - } finally { - destroyed(); - } - } - - /** - * 执行sql查询语句 - * - * @param sql - * @throws SQLException - * @throws ClassNotFoundException - */ - public ResultSet executeQuery(String sql, Object... args) throws SQLException, ClassNotFoundException { - PreparedStatement preparedStatement = getConnection().prepareStatement(sql); - setArg(preparedStatement, args); - return preparedStatement.executeQuery(); - } - - /** - * 执行sql语句 - * - * @param sql - * @throws SQLException - * @throws ClassNotFoundException - */ - public int executeUpdate(String sql, Object... args) throws SQLException, ClassNotFoundException { - try { - PreparedStatement preparedStatement = getConnection().prepareStatement(sql); - setArg(preparedStatement, args); - return preparedStatement.executeUpdate(); - } finally { - destroyed(); - } - } - - private void setArg(PreparedStatement ps, Object... args) throws SQLException { - for (int i = 0; i < args.length; i++) { - Object arg = args[i]; - - if (arg == null) { - ps.setNull(i + 1, Types.NULL); - } else if (arg instanceof String) { - ps.setString(i + 1, (String) arg); - } else if (arg instanceof Date) { - ps.setDate(i + 1, (Date) arg); - } else if (arg instanceof Time) { - ps.setTime(i + 1, (Time) arg); - } else if (arg instanceof java.util.Date) { - ps.setLong(i + 1, ((java.util.Date) arg).getTime()); - } else if (arg instanceof Boolean) { - ps.setBoolean(i + 1, (Boolean) arg); - } else if (arg instanceof Byte) { - ps.setByte(i + 1, (Byte) arg); - } else if (arg instanceof Short) { - ps.setShort(i + 1, (Short) arg); - } else if (arg instanceof Integer) { - ps.setInt(i + 1, (int) arg); - } else if (arg instanceof Long) { - ps.setLong(i + 1, (long) arg); - } else if (arg instanceof Float) { - ps.setFloat(i + 1, (float) arg); - } else if (arg instanceof Double) { - ps.setDouble(i + 1, (double) arg); - } else if (arg instanceof byte[]) { - ps.setBytes(i + 1, (byte[]) arg); - } - } - } - - /** - * 获取数据库连接 - * - * @return 数据库连接 - * @throws ClassNotFoundException - * @throws SQLException - */ - Connection getConnection() throws ClassNotFoundException, SQLException { - if (null == connection) { - Class.forName("org.sqlite.JDBC"); - connection = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath); - } - return connection; - } - - /** - * 数据库资源关闭和释放 - */ - public void destroyed() { -// try { -// if (null != resultSet) { -// resultSet.close(); -// resultSet = null; -// } -// -// if (null != connection) { -// connection.close(); -// connection = null; -// } -// -// } catch (SQLException e) { -// e.printStackTrace(); -// } - } -} \ No newline at end of file diff --git a/wsqlite/src/main/java/xyz/wbsite/wsqlite/ObjectClient.java b/wsqlite/src/main/java/xyz/wbsite/wsqlite/ObjectClient.java deleted file mode 100644 index 6d643cf..0000000 --- a/wsqlite/src/main/java/xyz/wbsite/wsqlite/ObjectClient.java +++ /dev/null @@ -1,319 +0,0 @@ -package xyz.wbsite.wsqlite; - -import xyz.wbsite.wsqlite.anonation.TableField; - -import java.io.File; -import java.lang.reflect.Field; -import java.sql.SQLException; -import java.text.SimpleDateFormat; -import java.util.*; - -/** - * xyz.wbsite.wsqlite.Client - * - * @author wangbing - */ -public class ObjectClient extends Client { - - private Map classMap = new HashMap<>(); - - /** - * 构造函数 - * - * @param dbFile 文件 - * @param classList 注册对象 - * @throws ClassNotFoundException - * @throws SQLException - */ - public ObjectClient(File dbFile, List classList) throws ClassNotFoundException, SQLException { - super(dbFile); - for (Class aClass : classList) { - classMap.put(aClass.getName(), aClass); - } - for (String key : classMap.keySet()) { - Class object = classMap.get(key); - StringBuffer sql = new StringBuffer(); - String name = object.getSimpleName(); - - sql.append("CREATE TABLE IF NOT EXISTS "); - sql.append(name); - sql.append(" ("); - - Field[] fields = object.getDeclaredFields(); - for (Field f : fields) { - if (f.isAnnotationPresent(TableField.class)) { - TableField bind = f.getAnnotation(TableField.class); - int length = bind.value(); - - if (f.getType() == String.class) { - sql.append(f.getName().toUpperCase()); - sql.append(" VARCHAR(" + length + "),"); - } else if (f.getType() == Boolean.class || f.getType() == boolean.class) { - sql.append(f.getName().toUpperCase()); - sql.append(" BOOLEAN,"); - } else if (f.getType() == Byte.class || f.getType() == byte.class || - f.getType() == Short.class || f.getType() == short.class || - f.getType() == Character.class || f.getType() == char.class || - f.getType() == Integer.class || f.getType() == int.class || - f.getType() == Long.class || f.getType() == long.class) { - sql.append(f.getName().toUpperCase()); - sql.append(" INTEGER,"); - } else if (f.getType() == Float.class || f.getType() == float.class || - f.getType() == Double.class || f.getType() == double.class) { - sql.append(f.getName().toUpperCase()); - sql.append(" REAL,"); - } else if (f.getType() == Byte[].class || f.getType() == byte[].class) { - sql.append(f.getName().toUpperCase()); - sql.append(" BLOB,"); - } else if (f.getType() == Date.class) { - sql.append(f.getName().toUpperCase()); - sql.append(" TIMESTAMP,"); - } - } - } - - sql.replace(sql.length() - 1, sql.length(), ""); - sql.append(")"); - System.out.println("SQL ==> " + sql.toString()); - execute(sql.toString()); - } - } - - public int insert(Class poClass, T po) throws SQLException, ClassNotFoundException { - try { - Class aClass = classMap.get(poClass.getName()); - if (aClass == null) { - System.err.println(poClass.getName() + " not found."); - } else { - StringBuffer sql = new StringBuffer(); - sql.append("INSERT INTO "); - sql.append(aClass.getSimpleName()); - sql.append("("); - - //获取字段列表 - List fs = getFields(poClass); - - StringBuffer fieldsSql = new StringBuffer(); - StringBuffer valueSql = new StringBuffer(); - Object[] values = new Object[fs.size()]; - - for (int i = 0; i < fs.size(); i++) { - Field f = fs.get(i); - f.setAccessible(true); - fieldsSql.append(f.getName().toUpperCase()); - valueSql.append("?"); - Object o = f.get(po); - values[i] = o; - if (i != fs.size() - 1) { - fieldsSql.append(","); - valueSql.append(","); - } - } - - sql.append(fieldsSql); - sql.append(") VALUES ("); - sql.append(valueSql); - sql.append(")"); - System.out.println("SQL ==> " + sql.toString()); - return executeUpdate(sql.toString(), values); - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } finally { - destroyed(); - } - return 0; - } - - public int delete(Class poClass, Where where) throws SQLException, ClassNotFoundException { - try { - Class aClass = classMap.get(poClass.getName()); - if (aClass == null) { - System.err.println(poClass.getName() + " not found."); - } else { - StringBuffer sql = new StringBuffer(); - sql.append("DELETE FROM "); - sql.append(aClass.getSimpleName()); - sql.append(where.getSql()); - System.out.println("SQL ==> " + sql.toString()); - return executeUpdate(sql.toString(), where.getArgs()); - } - } finally { - destroyed(); - } - return 0; - } - - public int update(Class poClass, T po, Where where) throws SQLException, ClassNotFoundException { - try { - Class aClass = classMap.get(poClass.getName()); - if (aClass == null) { - System.err.println(poClass.getName() + " not found."); - } else { - //获取字段列表 - List fs = getFields(poClass); - - StringBuffer sql = new StringBuffer(); - Object[] values = new Object[fs.size()]; - sql.append("UPDATE "); - sql.append(aClass.getSimpleName()); - sql.append(" SET "); - - for (int i = 0; i < fs.size(); i++) { - Field f = fs.get(i); - f.setAccessible(true); - sql.append(f.getName()); - sql.append(" = ?"); - values[i] = f.get(po); - if (i != fs.size() - 1) { - sql.append(","); - } - } - - // 条件 - sql.append(where.getSql()); - - System.out.println("SQL ==> " + sql.toString()); - return executeUpdate(sql.toString(), concat(values, where.getArgs())); - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } finally { - destroyed(); - } - return 0; - } - - public List select(Class poClass, Where where, int pageNumber, int pageSize) throws SQLException, ClassNotFoundException { - ArrayList list = new ArrayList<>(); - try { - Class aClass = classMap.get(poClass.getName()); - if (aClass == null) { - System.err.println(poClass.getName() + " not found."); - } else { - StringBuffer sql = new StringBuffer(); - sql.append("SELECT "); - - //获取字段列表 - List fs = getFields(poClass); - - for (int i = 0; i < fs.size(); i++) { - Field f = fs.get(i); - sql.append(f.getName().toUpperCase()); - if (i != fs.size() - 1) { - sql.append(","); - } - } - - sql.append(" FROM "); - sql.append(aClass.getSimpleName()); - - // 条件 - sql.append(where.getSql()); - - //分页参数 - if (pageSize > 0) { - sql.append(" LIMIT " + (pageNumber - 1) + "," + pageSize); - } - - System.out.println("SQL ==> " + sql.toString()); - list.addAll(executeQuery(poClass, sql.toString(), where.getArgs())); - } - } finally { - destroyed(); - } - return list; - } - - /** - * 执行select查询,返回结果列表 - * - * @param sql sql select 语句 - * @param poClass 结果集的行数据处理类对象 - * @return - * @throws SQLException - * @throws ClassNotFoundException - */ - public List executeQuery(Class poClass, String sql, Object... args) throws SQLException, ClassNotFoundException { - List rsList = new ArrayList(); - try { - resultSet = executeQuery(sql, args); - - //获取字段列表 - List fs = getFields(poClass); - - while (resultSet.next()) { - try { - T o = poClass.newInstance(); - for (int i = 0; i < fs.size(); i++) { - Field f = fs.get(i); - f.setAccessible(true); - - if (f.getType() == String.class) { - String v = resultSet.getString(f.getName()); - f.set(o, v); - } else if (f.getType() == Boolean.class || f.getType() == boolean.class) { - boolean v = resultSet.getBoolean(f.getName()); - f.set(o, v); - } else if (f.getType() == Byte.class || f.getType() == byte.class) { - byte v = resultSet.getByte(f.getName()); - f.set(o, v); - } else if (f.getType() == Short.class || f.getType() == short.class) { - short v = resultSet.getShort(f.getName()); - f.set(o, v); - } else if (f.getType() == Character.class || f.getType() == char.class) { - short v = resultSet.getShort(f.getName()); - f.set(o, (char) v); - } else if (f.getType() == Integer.class || f.getType() == int.class) { - int v = resultSet.getInt(f.getName()); - f.set(o, v); - } else if (f.getType() == Long.class || f.getType() == long.class) { - long v = resultSet.getLong(f.getName()); - f.set(o, v); - } else if (f.getType() == Float.class || f.getType() == float.class) { - float v = resultSet.getFloat(f.getName()); - f.set(o, v); - } else if (f.getType() == Double.class || f.getType() == double.class) { - double v = resultSet.getDouble(f.getName()); - f.set(o, v); - } else if (f.getType() == Byte[].class || f.getType() == byte[].class) { - byte[] v = resultSet.getBytes(f.getName()); - f.set(o, v); - } else if (f.getType() == Date.class) { - Date v = resultSet.getTimestamp(f.getName()); - f.set(o, v); - } else { - String v = resultSet.getString(f.getName()); - f.set(o, v); - } - } - rsList.add(o); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } finally { - destroyed(); - } - return rsList; - } - - private List getFields(Class aClass) { - List fs = new ArrayList<>(); - for (Field f : aClass.getDeclaredFields()) { - if (f.isAnnotationPresent(TableField.class)) { - fs.add(f); - } - } - return fs; - } - - private T[] concat(T[] arr1, T[] arr2) { - List temp = new ArrayList<>(); - temp.addAll(Arrays.asList(arr1)); - temp.addAll(Arrays.asList(arr2)); - return (T[]) temp.toArray(); - } -} \ No newline at end of file diff --git a/wsqlite/src/main/java/xyz/wbsite/wsqlite/Where.java b/wsqlite/src/main/java/xyz/wbsite/wsqlite/Where.java deleted file mode 100644 index bb46f8b..0000000 --- a/wsqlite/src/main/java/xyz/wbsite/wsqlite/Where.java +++ /dev/null @@ -1,94 +0,0 @@ -package xyz.wbsite.wsqlite; - -import java.util.ArrayList; -import java.util.List; - -public class Where { - private String sql; - private Object[] args; - - private Where() { - } - - public String getSql() { - return sql; - } - - public void setSql(String sql) { - this.sql = sql; - } - - public Object[] getArgs() { - return args; - } - - public void setArgs(Object[] args) { - this.args = args; - } - - public Where(String sql, Object[] args) { - this.sql = sql; - this.args = args; - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private StringBuilder sb = new StringBuilder(); - private List argsList = new ArrayList<>(); - - public Builder eq(String name, Object value) { - return eq(true, name, value); - } - - public Builder like(String name, Object value) { - return like(true, name, value); - } - - public Builder isNull(String name, Object value) { - return isNull(true, name, value); - } - - public Builder isNotNull(String name, Object value) { - return isNotNull(true, name, value); - } - - public Builder eq(boolean condition, String name, Object value) { - if (condition) { - sb.append(sb.length() > 0 ? " and " : " where ").append(name).append(" = ? "); - argsList.add(value); - } - return this; - } - - public Builder like(boolean condition, String name, Object value) { - if (condition) { - sb.append(sb.length() > 0 ? " and " : " where ").append(name).append(" like ?"); - argsList.add(value); - } - return this; - } - - public Builder isNull(boolean condition, String name, Object value) { - if (condition) { - sb.append(sb.length() > 0 ? " and " : " where ").append(name).append(" is null"); - argsList.add(value); - } - return this; - } - - public Builder isNotNull(boolean condition, String name, Object value) { - if (condition) { - sb.append(sb.length() > 0 ? " and " : " where ").append(name).append(" is not null"); - argsList.add(value); - } - return this; - } - - public Where build() { - return new Where(sb.toString(), argsList.toArray()); - } - } -} diff --git a/wsqlite/src/main/java/xyz/wbsite/wsqlite/anonation/TableField.java b/wsqlite/src/main/java/xyz/wbsite/wsqlite/anonation/TableField.java deleted file mode 100644 index 838c286..0000000 --- a/wsqlite/src/main/java/xyz/wbsite/wsqlite/anonation/TableField.java +++ /dev/null @@ -1,13 +0,0 @@ -package xyz.wbsite.wsqlite.anonation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface TableField { - - int value() default 20; -}