diff --git a/.idea/encodings.xml b/.idea/encodings.xml index c67b1e9fc7d11822bd4cd84e81c65bfcacc59d5c..412e4bf5ee843d13c63412c51f1dd5e495eb36d8 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -3,9 +3,12 @@ + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__ch_ethz_ganymed_ganymed_ssh2_build210.xml b/.idea/libraries/Maven__ch_ethz_ganymed_ganymed_ssh2_build210.xml new file mode 100644 index 0000000000000000000000000000000000000000..c87bb42caa2c290fe6ea526316f9f8d8594ffe2d --- /dev/null +++ b/.idea/libraries/Maven__ch_ethz_ganymed_ganymed_ssh2_build210.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_11_3.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_10_5.xml similarity index 60% rename from .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_11_3.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_10_5.xml index 1c342c8e5b5afe7245b422b90e749695a2013e9f..dfab350811ef12d55e3b64f9199faa35ec11e847 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_11_3.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_10_5.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_11_3.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_10_5.xml similarity index 67% rename from .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_11_3.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_10_5.xml index 0883060fb5de488e6047693fcffaa951386f3130..03f49be7a73a5708e5058334da9cdc917b6f4f52 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_11_3.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_10_5.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_11_3.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_10_5.xml similarity index 68% rename from .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_11_3.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_10_5.xml index eb49e684cf2a1ad962ca6973ceafd6189f81cf66..f103dd5422ee4aae7b5cd937c5ea55a5bebfce8a 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_11_3.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_10_5.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_11_3.xml b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_10_5.xml similarity index 57% rename from .idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_11_3.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_10_5.xml index ad75c155b18f57cff67bd7b450beb7a36f9550ad..5f0bf03afdc603d97c5723a2395952813b5df8b0 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_11_3.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_10_5.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_11_3.xml b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_10_5.xml similarity index 56% rename from .idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_11_3.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_10_5.xml index 61cd1763121c856b55076f2a231a90be1eb8f9a3..09ef2dc58c20909e89a9d3c5c393079d885d74cd 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_11_3.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_10_5.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_11_3.xml b/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_10_5.xml similarity index 53% rename from .idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_11_3.xml rename to .idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_10_5.xml index 4ceaf5b00c0e2ff9c3ceb2aeabe02c47873ff890..a6b27bdf02de92ace359bc2b99d66001042f1383 100644 --- a/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_11_3.xml +++ b/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_10_5.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_github_oshi_oshi_core_5_7_1.xml b/.idea/libraries/Maven__com_github_oshi_oshi_core_5_7_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..42a7ec91f9d89af66ca09943350bce38b7e392bb --- /dev/null +++ b/.idea/libraries/Maven__com_github_oshi_oshi_core_5_7_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_github_virtuald_curvesapi_1_04.xml b/.idea/libraries/Maven__com_github_virtuald_curvesapi_1_04.xml new file mode 100644 index 0000000000000000000000000000000000000000..3aa2e4c241a58be12f67d024822c2a5081ad950e --- /dev/null +++ b/.idea/libraries/Maven__com_github_virtuald_curvesapi_1_04.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_github_whvcse_easy_captcha_1_6_2.xml b/.idea/libraries/Maven__com_github_whvcse_easy_captcha_1_6_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..e70bf83d04114dca1777f821a1232e0f01601374 --- /dev/null +++ b/.idea/libraries/Maven__com_github_whvcse_easy_captcha_1_6_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_jcraft_jsch_0_1_55.xml b/.idea/libraries/Maven__com_jcraft_jsch_0_1_55.xml new file mode 100644 index 0000000000000000000000000000000000000000..b8a2b4c89c1d746aedfb185e596297456c7efc83 --- /dev/null +++ b/.idea/libraries/Maven__com_jcraft_jsch_0_1_55.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_mchange_mchange_commons_java_0_2_15.xml b/.idea/libraries/Maven__com_mchange_mchange_commons_java_0_2_15.xml new file mode 100644 index 0000000000000000000000000000000000000000..84e0c93ec4a6e450e7e796bd078625c7e43245d0 --- /dev/null +++ b/.idea/libraries/Maven__com_mchange_mchange_commons_java_0_2_15.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__commons_codec_commons_codec_1_15.xml b/.idea/libraries/Maven__commons_codec_commons_codec_1_13.xml similarity index 60% rename from .idea/libraries/Maven__commons_codec_commons_codec_1_15.xml rename to .idea/libraries/Maven__commons_codec_commons_codec_1_13.xml index 7b02399a780d9f7cea0de9ea39f3fc73edabe889..46e60ff7d177e942caa1cd7f68b1997f68abf037 100644 --- a/.idea/libraries/Maven__commons_codec_commons_codec_1_15.xml +++ b/.idea/libraries/Maven__commons_codec_commons_codec_1_13.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_jsonwebtoken_jjwt_api_0_11_1.xml b/.idea/libraries/Maven__io_jsonwebtoken_jjwt_api_0_11_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..c41f74fced7cdff2f7c5016cb7128e8bf6b4b408 --- /dev/null +++ b/.idea/libraries/Maven__io_jsonwebtoken_jjwt_api_0_11_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_jsonwebtoken_jjwt_impl_0_11_1.xml b/.idea/libraries/Maven__io_jsonwebtoken_jjwt_impl_0_11_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..49ac75b5a36d0cb1f5de30ba86efbc4e98ee36eb --- /dev/null +++ b/.idea/libraries/Maven__io_jsonwebtoken_jjwt_impl_0_11_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_jsonwebtoken_jjwt_jackson_0_11_1.xml b/.idea/libraries/Maven__io_jsonwebtoken_jjwt_jackson_0_11_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..8261605ff54a56778d6550938a4388b3a1849684 --- /dev/null +++ b/.idea/libraries/Maven__io_jsonwebtoken_jjwt_jackson_0_11_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_lettuce_lettuce_core_6_0_1_RELEASE.xml b/.idea/libraries/Maven__io_lettuce_lettuce_core_5_2_2_RELEASE.xml similarity index 57% rename from .idea/libraries/Maven__io_lettuce_lettuce_core_6_0_1_RELEASE.xml rename to .idea/libraries/Maven__io_lettuce_lettuce_core_5_2_2_RELEASE.xml index c9725e182ed52e901acdf632f200d8b641b01c4c..443f6208bfb02d3bd325481bf21f3d7f64e00777 100644 --- a/.idea/libraries/Maven__io_lettuce_lettuce_core_6_0_1_RELEASE.xml +++ b/.idea/libraries/Maven__io_lettuce_lettuce_core_5_2_2_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_netty_netty_common_4_1_54_Final.xml b/.idea/libraries/Maven__io_netty_netty_buffer_4_1_52_Final.xml similarity index 57% rename from .idea/libraries/Maven__io_netty_netty_common_4_1_54_Final.xml rename to .idea/libraries/Maven__io_netty_netty_buffer_4_1_52_Final.xml index 6b7c5b2f0e64863993edb4bc3525d6e1edbfb3a8..8d9e53044fedd59e1a342d4d9909576d33cf067c 100644 --- a/.idea/libraries/Maven__io_netty_netty_common_4_1_54_Final.xml +++ b/.idea/libraries/Maven__io_netty_netty_buffer_4_1_52_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_netty_netty_codec_4_1_54_Final.xml b/.idea/libraries/Maven__io_netty_netty_codec_4_1_52_Final.xml similarity index 58% rename from .idea/libraries/Maven__io_netty_netty_codec_4_1_54_Final.xml rename to .idea/libraries/Maven__io_netty_netty_codec_4_1_52_Final.xml index 0cb934d34bc0656f14fa8b1b2826e57876954d1e..529b6c9416c7db11c3ec59258f53095896af1075 100644 --- a/.idea/libraries/Maven__io_netty_netty_codec_4_1_54_Final.xml +++ b/.idea/libraries/Maven__io_netty_netty_codec_4_1_52_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_netty_netty_buffer_4_1_54_Final.xml b/.idea/libraries/Maven__io_netty_netty_common_4_1_52_Final.xml similarity index 57% rename from .idea/libraries/Maven__io_netty_netty_buffer_4_1_54_Final.xml rename to .idea/libraries/Maven__io_netty_netty_common_4_1_52_Final.xml index 93e9b7d3bb63a53f5c1a364f0f963e6e58613e4d..a97701e0651fb3733c4ff59b899b9d315ab08602 100644 --- a/.idea/libraries/Maven__io_netty_netty_buffer_4_1_54_Final.xml +++ b/.idea/libraries/Maven__io_netty_netty_common_4_1_52_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_netty_netty_handler_4_1_54_Final.xml b/.idea/libraries/Maven__io_netty_netty_handler_4_1_52_Final.xml similarity index 57% rename from .idea/libraries/Maven__io_netty_netty_handler_4_1_54_Final.xml rename to .idea/libraries/Maven__io_netty_netty_handler_4_1_52_Final.xml index ebb31d93680a089fef7e36007e71d3bcff0e1f75..1fe008db3ef8eacb9c2e5b10a6cf6d732296e122 100644 --- a/.idea/libraries/Maven__io_netty_netty_handler_4_1_54_Final.xml +++ b/.idea/libraries/Maven__io_netty_netty_handler_4_1_52_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_netty_netty_resolver_4_1_54_Final.xml b/.idea/libraries/Maven__io_netty_netty_resolver_4_1_52_Final.xml similarity index 57% rename from .idea/libraries/Maven__io_netty_netty_resolver_4_1_54_Final.xml rename to .idea/libraries/Maven__io_netty_netty_resolver_4_1_52_Final.xml index bac6d02135101f26ec85dcba1361ee948471f76a..23faefe0a7781c6aeea0d8289cf23be2d2b16be8 100644 --- a/.idea/libraries/Maven__io_netty_netty_resolver_4_1_54_Final.xml +++ b/.idea/libraries/Maven__io_netty_netty_resolver_4_1_52_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_netty_netty_transport_4_1_54_Final.xml b/.idea/libraries/Maven__io_netty_netty_transport_4_1_52_Final.xml similarity index 57% rename from .idea/libraries/Maven__io_netty_netty_transport_4_1_54_Final.xml rename to .idea/libraries/Maven__io_netty_netty_transport_4_1_52_Final.xml index 12fe0d1c30b0b890f7e95e652fe7453f73412c79..1dda760fa896d6bc27ff389ed038669b587d395d 100644 --- a/.idea/libraries/Maven__io_netty_netty_transport_4_1_54_Final.xml +++ b/.idea/libraries/Maven__io_netty_netty_transport_4_1_52_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_projectreactor_reactor_core_3_4_0.xml b/.idea/libraries/Maven__io_projectreactor_reactor_core_3_3_10_RELEASE.xml similarity index 52% rename from .idea/libraries/Maven__io_projectreactor_reactor_core_3_4_0.xml rename to .idea/libraries/Maven__io_projectreactor_reactor_core_3_3_10_RELEASE.xml index a5f655ec3edd1395e90ed20d6d9cfcab25e062c8..58a984898380038155cd176a6eb1b85e417ddd86 100644 --- a/.idea/libraries/Maven__io_projectreactor_reactor_core_3_4_0.xml +++ b/.idea/libraries/Maven__io_projectreactor_reactor_core_3_3_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_12.xml b/.idea/libraries/Maven__junit_junit_4_12.xml new file mode 100644 index 0000000000000000000000000000000000000000..8f338b43803e9b205dd96e6def14a56e7dc1e05b --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_22.xml b/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_21.xml similarity index 58% rename from .idea/libraries/Maven__mysql_mysql_connector_java_8_0_22.xml rename to .idea/libraries/Maven__mysql_mysql_connector_java_8_0_21.xml index 8881d10b0a277062e32ec25c125f8de6476b53f7..2cba992156011086bc06671d09095883499c3bd5 100644 --- a/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_22.xml +++ b/.idea/libraries/Maven__mysql_mysql_connector_java_8_0_21.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_18.xml b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_14.xml similarity index 60% rename from .idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_18.xml rename to .idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_14.xml index fbc301e08cd2cbef0cbd4dfd6e8df4b72062a096..21fffadc9c63cb482e1eb06f23cda11b6dded6a8 100644 --- a/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_18.xml +++ b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_10_14.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_18.xml b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_14.xml similarity index 57% rename from .idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_18.xml rename to .idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_14.xml index 303a3cce95bd9a6f8e80d69874f796545025b553..27387cb65965d4ead5520a73deeec5b9f9326b83 100644 --- a/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_18.xml +++ b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_10_14.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_java_dev_jna_jna_5_8_0.xml b/.idea/libraries/Maven__net_java_dev_jna_jna_5_8_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..d080679308b678f530a6b31b57ad297ad01e0f73 --- /dev/null +++ b/.idea/libraries/Maven__net_java_dev_jna_jna_5_8_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_java_dev_jna_jna_platform_5_8_0.xml b/.idea/libraries/Maven__net_java_dev_jna_jna_platform_5_8_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..c5c986b5c1d35383b2a5ea1b1ca9049210b62b2b --- /dev/null +++ b/.idea/libraries/Maven__net_java_dev_jna_jna_platform_5_8_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_4.xml b/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_1.xml similarity index 67% rename from .idea/libraries/Maven__org_apache_commons_commons_collections4_4_4.xml rename to .idea/libraries/Maven__org_apache_commons_commons_collections4_4_1.xml index c45293b054c425478d45e646360bca4653ebc807..0ca0d261df816b7b1c9ac5c636101640d93bdff6 100644 --- a/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_4.xml +++ b/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_1.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_11.xml b/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml similarity index 58% rename from .idea/libraries/Maven__org_apache_commons_commons_lang3_3_11.xml rename to .idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml index 2587f3c05eda9a6ed42798bf9de50340b227b788..2952290b536e4c18fd17766672866aabc4616b0c 100644 --- a/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_11.xml +++ b/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_13_3.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml similarity index 57% rename from .idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_13_3.xml rename to .idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml index e76401e427ee17094669816350fb44293fd756ff..80b55238c34ecc156a15a79d1b5324dcbf05da43 100644 --- a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_13_3.xml +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_12_1.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_13_3.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_12_1.xml similarity index 67% rename from .idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_13_3.xml rename to .idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_12_1.xml index 5a269095ff313a2bf74196dfe0999aa77cf79901..bcd46b682a70337e43e6e6ec9aae575aead317df 100644 --- a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_13_3.xml +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_12_1.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_poi_poi_3_17.xml b/.idea/libraries/Maven__org_apache_poi_poi_3_17.xml new file mode 100644 index 0000000000000000000000000000000000000000..839ded5777996b0832aedc28d7f3aa4b32c90b54 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_poi_poi_3_17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_poi_poi_ooxml_3_17.xml b/.idea/libraries/Maven__org_apache_poi_poi_ooxml_3_17.xml new file mode 100644 index 0000000000000000000000000000000000000000..4fc547e93ad4766f2c1c406a2f5c3e383d57b814 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_poi_poi_ooxml_3_17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_poi_poi_ooxml_schemas_3_17.xml b/.idea/libraries/Maven__org_apache_poi_poi_ooxml_schemas_3_17.xml new file mode 100644 index 0000000000000000000000000000000000000000..ba926275b79dce6069b7a11c5b8d0f060585ac3e --- /dev/null +++ b/.idea/libraries/Maven__org_apache_poi_poi_ooxml_schemas_3_17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_39.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_38.xml similarity index 68% rename from .idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_39.xml rename to .idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_38.xml index 81834b9bf0694ed53dd41ce8631e3cd27030f56e..c88882859c950921e2dcf44e865701b0d868c06c 100644 --- a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_39.xml +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_38.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_38.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_38.xml new file mode 100644 index 0000000000000000000000000000000000000000..8ee1a249db27ebaa93fc069332776a88ef59d6f8 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_38.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_39.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_38.xml similarity index 59% rename from .idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_39.xml rename to .idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_38.xml index ed05eadae0390a15c94251d7204dabb516ab339c..887261ad742e0ad51fb27a631d563ae2e140fee3 100644 --- a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_39.xml +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_38.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_xmlbeans_xmlbeans_2_6_0.xml b/.idea/libraries/Maven__org_apache_xmlbeans_xmlbeans_2_6_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..f9855e0a29049b131a23b66c4a75f9edbda1d275 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_xmlbeans_xmlbeans_2_6_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_assertj_assertj_core_3_18_1.xml b/.idea/libraries/Maven__org_assertj_assertj_core_3_13_2.xml similarity index 60% rename from .idea/libraries/Maven__org_assertj_assertj_core_3_18_1.xml rename to .idea/libraries/Maven__org_assertj_assertj_core_3_13_2.xml index de0668cfc2212df683ed43fd4377b7219af11db0..df04acc09f1749aa728761607e272795aeec2a39 100644 --- a/.idea/libraries/Maven__org_assertj_assertj_core_3_18_1.xml +++ b/.idea/libraries/Maven__org_assertj_assertj_core_3_13_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml b/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml deleted file mode 100644 index ca13fead326f7484ef36f196f9b5ae841f81eac4..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_codehaus_jackson_jackson_core_asl_1_9_13.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml b/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml deleted file mode 100644 index 7beddd0b0faea8446ab69ec1db67e3a43349b2b7..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_codehaus_jackson_jackson_mapper_asl_1_9_13.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_glassfish_jakarta_el_3_0_3.xml b/.idea/libraries/Maven__org_glassfish_jakarta_el_3_0_3.xml deleted file mode 100644 index 6bd5ebff352451694fca3892d58bbd587e4a0cad..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_glassfish_jakarta_el_3_0_3.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_2_2.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_2_1.xml similarity index 66% rename from .idea/libraries/Maven__org_hamcrest_hamcrest_2_2.xml rename to .idea/libraries/Maven__org_hamcrest_hamcrest_2_1.xml index ae33eaf23b956babfe768e19e88129322e5c479e..a8d822657bbf5125a5f0e840eed4a901c53bb1d9 100644 --- a/.idea/libraries/Maven__org_hamcrest_hamcrest_2_2.xml +++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_2_1.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_2_Final.xml b/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_0_Final.xml similarity index 53% rename from .idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_2_Final.xml rename to .idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_0_Final.xml index b17d24b3ea352d3083fc6f5e26e7b32df444d9af..4a03454052e12559fc40844b60e2044442d8c568 100644 --- a/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_2_Final.xml +++ b/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_1_0_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hibernate_hibernate_core_5_4_23_Final.xml b/.idea/libraries/Maven__org_hibernate_hibernate_core_5_4_21_Final.xml similarity index 58% rename from .idea/libraries/Maven__org_hibernate_hibernate_core_5_4_23_Final.xml rename to .idea/libraries/Maven__org_hibernate_hibernate_core_5_4_21_Final.xml index 8aa465831abd7a5e7f9efc9696b9edb969b4ebd9..83dcc08d0acaec8fca8d6bc2f8243ebc723b0436 100644 --- a/.idea/libraries/Maven__org_hibernate_hibernate_core_5_4_23_Final.xml +++ b/.idea/libraries/Maven__org_hibernate_hibernate_core_5_4_21_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_1_6_Final.xml b/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_20_Final.xml similarity index 57% rename from .idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_1_6_Final.xml rename to .idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_20_Final.xml index 82f229160d0f011c3d1bd7f33b12d0585221fe09..717087f49e0f01a324e0f5a57d2074855acdc622 100644 --- a/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_1_6_Final.xml +++ b/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_20_Final.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_0.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_5_2.xml similarity index 58% rename from .idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_0.xml rename to .idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_5_2.xml index b95dbe1beb686a3986b9175f00c816218a93fad9..50cc6d520fcfe5fa955291d74a5ec9b981c692aa 100644 --- a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_0.xml +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_5_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_0.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_5_2.xml similarity index 57% rename from .idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_0.xml rename to .idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_5_2.xml index 531ff880d4b52bcd2a58569830c0f448343b422e..bdc0f0ff503a718f8e3f68431e0cd0b28aae8a9f 100644 --- a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_0.xml +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_5_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_0.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_5_2.xml similarity index 68% rename from .idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_0.xml rename to .idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_5_2.xml index 37b52f5227db712297ab6e7dbf735bb055291e4b..460bde1d54b02570e6f2bf9816a96bd2911c2373 100644 --- a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_0.xml +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_5_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_0.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_5_2.xml similarity index 68% rename from .idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_0.xml rename to .idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_5_2.xml index 8e77de2165c0d203a3b22acf467f584742a1827e..6b99a43a2ec7eaedc22f1b15fc0805a07bfa2dab 100644 --- a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_0.xml +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_5_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_0.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_5_2.xml similarity index 68% rename from .idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_0.xml rename to .idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_5_2.xml index c7415d61de41fea1fe661d3ae9be848161fca83b..e0b24f04b6dc01694218518d729534211e5adcec 100644 --- a/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_0.xml +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_5_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_0.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_5_2.xml similarity index 68% rename from .idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_0.xml rename to .idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_5_2.xml index 2669850966d27272e9b400c1191b04282a0315bc..d62bdf0d27074f19884a5ec210080740c1d22377 100644 --- a/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_0.xml +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_5_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_vintage_junit_vintage_engine_5_5_2.xml b/.idea/libraries/Maven__org_junit_vintage_junit_vintage_engine_5_5_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..7bc8373fffcdc4e1f010ea694d7f122895a73f31 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_vintage_junit_vintage_engine_5_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_mockito_mockito_core_3_6_0.xml b/.idea/libraries/Maven__org_mockito_mockito_core_3_1_0.xml similarity index 61% rename from .idea/libraries/Maven__org_mockito_mockito_core_3_6_0.xml rename to .idea/libraries/Maven__org_mockito_mockito_core_3_1_0.xml index 5ca71b8cf2fa3eb3126fc90026a42c0a57ac3466..46b788b984564855ebe634a6b5707d789a459444 100644 --- a/.idea/libraries/Maven__org_mockito_mockito_core_3_6_0.xml +++ b/.idea/libraries/Maven__org_mockito_mockito_core_3_1_0.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_6_0.xml b/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_1_0.xml similarity index 58% rename from .idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_6_0.xml rename to .idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_1_0.xml index 840e12e501e6c26b734cefb5bf74aa7e17d91b07..c142597840673bb334b61cc05c913090abf19b53 100644 --- a/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_6_0.xml +++ b/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_3_1_0.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_objenesis_objenesis_3_1.xml b/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml similarity index 64% rename from .idea/libraries/Maven__org_objenesis_objenesis_3_1.xml rename to .idea/libraries/Maven__org_objenesis_objenesis_2_6.xml index 77836c304655a0f1a5de74863d80391c2cb0d2a2..71dd51943e9cade77c8063b0cae6386b34390946 100644 --- a/.idea/libraries/Maven__org_objenesis_objenesis_3_1.xml +++ b/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_projectlombok_lombok_1_18_16.xml b/.idea/libraries/Maven__org_projectlombok_lombok_1_18_12.xml similarity index 61% rename from .idea/libraries/Maven__org_projectlombok_lombok_1_18_16.xml rename to .idea/libraries/Maven__org_projectlombok_lombok_1_18_12.xml index 8a3823efd6257a7e7801e7dea23c8b1b92950817..52bfa37e0b9ac887679aed5eff39aefb6f7d0b97 100644 --- a/.idea/libraries/Maven__org_projectlombok_lombok_1_18_16.xml +++ b/.idea/libraries/Maven__org_projectlombok_lombok_1_18_12.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_quartz_scheduler_quartz_2_3_2.xml b/.idea/libraries/Maven__org_quartz_scheduler_quartz_2_3_2.xml new file mode 100644 index 0000000000000000000000000000000000000000..3c19b440a80d75fd41823d5e6ed2d1e12b67db10 --- /dev/null +++ b/.idea/libraries/Maven__org_quartz_scheduler_quartz_2_3_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_2_4_1.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_2_10_RELEASE.xml similarity index 58% rename from .idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_2_4_1.xml rename to .idea/libraries/Maven__org_springframework_boot_spring_boot_2_2_10_RELEASE.xml index 941cb0a051e167ae053e0a55d51603c1951f8a46..92dd43d780ae47ca5fef0ac9409a8ce3b01cce9e 100644 --- a/.idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_2_4_1.xml +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_2_10_RELEASE.xml similarity index 53% rename from .idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_4_0.xml rename to .idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_2_10_RELEASE.xml index d7dba4ffabf19fd86e76870dce16ad0b8547861c..a5fc9f574c1cd20926ce17242df1a92e2d6ad96c 100644 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_4_0.xml +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_2_10_RELEASE.xml similarity index 56% rename from .idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_4_0.xml rename to .idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_2_10_RELEASE.xml index 0c28b7d52309cbcf2359a1db180a9fb1dc172e29..77c49096612a603a81510197ec6c258f243490e9 100644 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_4_0.xml +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_2_10_RELEASE.xml similarity index 54% rename from .idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_4_0.xml rename to .idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_2_10_RELEASE.xml index c87e562dcd3b9c1079580c61707833cea1434b80..89b950990774b0c577c13356fa17cf43ff4802fc 100644 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_4_0.xml +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..0e37a8905d8f818324ed7ae7e72634ec375793c9 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_cache_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f58dd4166b8adb3966e1a3fff0cc7377eb01f420 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_redis_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_redis_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..fc8dd9213dc2ddbb5a33a5426612bb832af51ec6 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_redis_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_redis_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_redis_2_4_0.xml deleted file mode 100644 index 85d2e62d2467571a23caca5b9ad59d112c713c5a..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_redis_2_4_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..ff0376803c0012e11043f1af436bfe09fef6ee0c --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_4_0.xml deleted file mode 100644 index 9ba202ddcd686cd4efed3696e7467bb6422ee382..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_freemarker_2_4_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_2_10_RELEASE.xml similarity index 53% rename from .idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_4_0.xml rename to .idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_2_10_RELEASE.xml index 86133db15d07c60221873b7814822f7364acd517..f2282105dc349249d6ffbe22c4780963e775337c 100644 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_4_0.xml +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_4_0.xml deleted file mode 100644 index e9b7853961bfe34290f0bd903032a0e5ec2688ac..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_4_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..63cc3325b2605ffff799b079003bb37d7d523b6b --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_4_0.xml deleted file mode 100644 index 199fefdf415dee8d8b6393e0382b53786fe8e9cd..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_4_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..0b484ad14930107a3145bfb001b31e17ad18b559 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_4_0.xml deleted file mode 100644 index 96d25eaa2026fd2936bfe0b5c89fe62b513e3de1..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_4_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_security_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_security_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..612b99654d3656180280266d3b17363ffbc19a4e --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_security_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..e5d81798fd8eaa32f5d8d418c951ebabc143b2ee --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_4_0.xml deleted file mode 100644 index f357783e70d3403f6ee2f2fe50947d4cfd573ebe..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_4_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..143cf24acd2e2d18a1d62be37640e273148e2f9a --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_4_0.xml deleted file mode 100644 index 17b33c5175fad04bb83915788a7c35f51df12f5c..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_4_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_2_10_RELEASE.xml similarity index 54% rename from .idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_4_0.xml rename to .idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_2_10_RELEASE.xml index b6fa5cce65213fbd9cb24d85feda88904da16a22..db47d4ece7668715fe4634e9474403cd13cebc3a 100644 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_4_0.xml +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_4_0.xml deleted file mode 100644 index 717d7632b70e88fe12d353eb9144c1c200efd8da..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_4_0.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_websocket_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_websocket_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..1ffa3ee3d65acf28f1d01539db49e4ca7508c9b7 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_websocket_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_2_10_RELEASE.xml similarity index 57% rename from .idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_4_0.xml rename to .idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_2_10_RELEASE.xml index 1b555045d4552b87a904fdd3593eab1a0e2286e4..5b2fa86507c7988af95ad5545e97eaf59594d15b 100644 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_4_0.xml +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_4_0.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_2_10_RELEASE.xml similarity index 50% rename from .idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_4_0.xml rename to .idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_2_10_RELEASE.xml index 5d6517d2b65d490bc22c6f21a0372049fa57dea6..9076628794589adbb4e9dd3b875ca9df35f97111 100644 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_4_0.xml +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_4_1.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_2_10_RELEASE.xml similarity index 56% rename from .idea/libraries/Maven__org_springframework_data_spring_data_commons_2_4_1.xml rename to .idea/libraries/Maven__org_springframework_data_spring_data_commons_2_2_10_RELEASE.xml index 2fedbfbbcd52f43a714831f88b1d4b2d2140e3aa..ea4d5ce997f9123e02af806994ec03307ac9a751 100644 --- a/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_4_1.xml +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_4_1.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_2_10_RELEASE.xml similarity index 58% rename from .idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_4_1.xml rename to .idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_2_10_RELEASE.xml index 7e68b66f4fce32ce56cb68e250516e142a0e3c63..eec9b9b7b51f40568a166b2bdfd0265cf69d01ac 100644 --- a/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_4_1.xml +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_2_2_10_RELEASE.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_2_2_10_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..39570dfeac340d08b1aa977a18a3c013dc0fe432 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_keyvalue_2_2_10_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_redis_2_4_1.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_redis_2_2_10_RELEASE.xml similarity index 57% rename from .idea/libraries/Maven__org_springframework_data_spring_data_redis_2_4_1.xml rename to .idea/libraries/Maven__org_springframework_data_spring_data_redis_2_2_10_RELEASE.xml index 68e29737a880b92d9a70339d728900ad033bd984..54578fb0c47f20b409b6c02a92c1208a68ae20d7 100644 --- a/.idea/libraries/Maven__org_springframework_data_spring_data_redis_2_4_1.xml +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_redis_2_2_10_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_security_oauth_spring_security_oauth2_2_3_4_RELEASE.xml b/.idea/libraries/Maven__org_springframework_security_oauth_spring_security_oauth2_2_3_4_RELEASE.xml deleted file mode 100644 index a537b5aad840cd55bf8cf52cc208cc76465b1282..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_security_oauth_spring_security_oauth2_2_3_4_RELEASE.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_security_spring_security_web_5_4_1.xml b/.idea/libraries/Maven__org_springframework_security_spring_security_config_5_2_6_RELEASE.xml similarity index 53% rename from .idea/libraries/Maven__org_springframework_security_spring_security_web_5_4_1.xml rename to .idea/libraries/Maven__org_springframework_security_spring_security_config_5_2_6_RELEASE.xml index cbc05c363b0b4b37264c104c1fdfa05da2841107..b7118770a3085a70e6033689e6824d65971c7102 100644 --- a/.idea/libraries/Maven__org_springframework_security_spring_security_web_5_4_1.xml +++ b/.idea/libraries/Maven__org_springframework_security_spring_security_config_5_2_6_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_security_spring_security_core_5_4_1.xml b/.idea/libraries/Maven__org_springframework_security_spring_security_core_5_2_6_RELEASE.xml similarity index 55% rename from .idea/libraries/Maven__org_springframework_security_spring_security_core_5_4_1.xml rename to .idea/libraries/Maven__org_springframework_security_spring_security_core_5_2_6_RELEASE.xml index 72302328f95a1c8fdabfb917804a25924c496efb..5d052021688609eeef05df09ef4111648db16924 100644 --- a/.idea/libraries/Maven__org_springframework_security_spring_security_core_5_4_1.xml +++ b/.idea/libraries/Maven__org_springframework_security_spring_security_core_5_2_6_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_security_spring_security_config_5_4_1.xml b/.idea/libraries/Maven__org_springframework_security_spring_security_web_5_2_6_RELEASE.xml similarity index 55% rename from .idea/libraries/Maven__org_springframework_security_spring_security_config_5_4_1.xml rename to .idea/libraries/Maven__org_springframework_security_spring_security_web_5_2_6_RELEASE.xml index 3418156ff72aab33c1ce2353e2d804e5d5273e3d..1b898667d394316b5d465b5898ad37e96bdb4322 100644 --- a/.idea/libraries/Maven__org_springframework_security_spring_security_config_5_4_1.xml +++ b/.idea/libraries/Maven__org_springframework_security_spring_security_web_5_2_6_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_aspects_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_aop_5_2_9_RELEASE.xml similarity index 54% rename from .idea/libraries/Maven__org_springframework_spring_aspects_5_3_1.xml rename to .idea/libraries/Maven__org_springframework_spring_aop_5_2_9_RELEASE.xml index ed89c28720fc3b8da3010130281d60771441024a..1074ecebb7e13b5b3cd75df0d54c666c50e30c1c 100644 --- a/.idea/libraries/Maven__org_springframework_spring_aspects_5_3_1.xml +++ b/.idea/libraries/Maven__org_springframework_spring_aop_5_2_9_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_context_support_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_aspects_5_2_9_RELEASE.xml similarity index 58% rename from .idea/libraries/Maven__org_springframework_spring_context_support_5_3_1.xml rename to .idea/libraries/Maven__org_springframework_spring_aspects_5_2_9_RELEASE.xml index ae1e976e018ff3942b5c27ae4a2356b3f0aa5fcd..192762d86d2561a6d5a668fe75fe773d864ed0bb 100644 --- a/.idea/libraries/Maven__org_springframework_spring_context_support_5_3_1.xml +++ b/.idea/libraries/Maven__org_springframework_spring_aspects_5_2_9_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_beans_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_beans_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..85cdb81f9b29bc93d17c1a8f9848d059d5905d2e --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_beans_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_beans_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_beans_5_3_1.xml deleted file mode 100644 index a9990dec9993288761f0a262292817e01d7d5cb3..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_beans_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_context_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_context_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..20be8a4c5464f92e538e515240cb67c536177c08 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_context_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_context_support_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_context_support_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..24f8077740d42eba777c1562cc7d7009e2e1b6ad --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_context_support_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_aop_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_core_5_2_9_RELEASE.xml similarity index 53% rename from .idea/libraries/Maven__org_springframework_spring_aop_5_3_1.xml rename to .idea/libraries/Maven__org_springframework_spring_core_5_2_9_RELEASE.xml index 5f0900e18692ea42a7f33d4d6fbe97bacafd6d5f..246c544a188f21b82144592449da807e1e03a994 100644 --- a/.idea/libraries/Maven__org_springframework_spring_aop_5_3_1.xml +++ b/.idea/libraries/Maven__org_springframework_spring_core_5_2_9_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_core_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_core_5_3_1.xml deleted file mode 100644 index fbc1452e4c62e11db3ddf70baac48bd957acf15f..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_core_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_expression_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_expression_5_2_9_RELEASE.xml similarity index 59% rename from .idea/libraries/Maven__org_springframework_spring_expression_5_3_1.xml rename to .idea/libraries/Maven__org_springframework_spring_expression_5_2_9_RELEASE.xml index 929148f74a8c41924653d698fe8029a7d296f57d..dcdfac61182ecba1515b1ff89578e4db426ec9d2 100644 --- a/.idea/libraries/Maven__org_springframework_spring_expression_5_3_1.xml +++ b/.idea/libraries/Maven__org_springframework_spring_expression_5_2_9_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_context_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_jcl_5_2_9_RELEASE.xml similarity index 54% rename from .idea/libraries/Maven__org_springframework_spring_context_5_3_1.xml rename to .idea/libraries/Maven__org_springframework_spring_jcl_5_2_9_RELEASE.xml index 8d5abb4904d2cca98483b41ee473ca9168c45b8e..4b1ca451160f5caf73e0791de24eb590e39c21d3 100644 --- a/.idea/libraries/Maven__org_springframework_spring_context_5_3_1.xml +++ b/.idea/libraries/Maven__org_springframework_spring_jcl_5_2_9_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_1.xml deleted file mode 100644 index 9cab0aa0f87a9a10809771d2645ec334c682425f..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jdbc_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_jdbc_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..348c4b7da95aa1b92652c587519430a3bd1c65cf --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_jdbc_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jdbc_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_jdbc_5_3_1.xml deleted file mode 100644 index 8b84df04efff9f0c394018e94d02e7888078b8dd..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_jdbc_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_messaging_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_messaging_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..90f882e0eafc2891df6cdab73017d6b8282ebe53 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_messaging_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_orm_5_2_9_RELEASE.xml similarity index 54% rename from .idea/libraries/Maven__org_springframework_spring_webmvc_5_3_1.xml rename to .idea/libraries/Maven__org_springframework_spring_orm_5_2_9_RELEASE.xml index 4712e689a7bdfadeb7342c73aca3dbdc7e55e18e..3905c8668773e10b77e06a21a67c0570a0eed1d5 100644 --- a/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_1.xml +++ b/.idea/libraries/Maven__org_springframework_spring_orm_5_2_9_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_orm_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_orm_5_3_1.xml deleted file mode 100644 index 4a4194521b045dec18416ff17be53841b41e9811..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_orm_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_oxm_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_oxm_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..f22ee54d2198db9ed40bd8f3fdc7d03aa9503b46 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_oxm_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_oxm_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_oxm_5_3_1.xml deleted file mode 100644 index 3f06a93838575d78fce565066feab03d882c5c10..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_oxm_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_test_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_test_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..c6b047ca97661fd3582460b74e3cfb579e015cd3 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_test_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_test_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_test_5_3_1.xml deleted file mode 100644 index 37d9256e72a5a7680d6cc8580bceca21063aa8d7..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_test_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_4_0.xml b/.idea/libraries/Maven__org_springframework_spring_tx_5_2_9_RELEASE.xml similarity index 54% rename from .idea/libraries/Maven__org_springframework_boot_spring_boot_2_4_0.xml rename to .idea/libraries/Maven__org_springframework_spring_tx_5_2_9_RELEASE.xml index 6003c645e8d671fa50d57041fad8a49a12cb6cb0..487c8e8cb132c9878f78d58bf94b1680428eb4e8 100644 --- a/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_4_0.xml +++ b/.idea/libraries/Maven__org_springframework_spring_tx_5_2_9_RELEASE.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_tx_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_tx_5_3_1.xml deleted file mode 100644 index 6e1a6278f134502bbb820e6b3e702d26d0847d55..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_tx_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_web_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_web_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..e0ac44af55213bc4f366535b84a705dfdec539e2 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_web_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_web_5_3_1.xml b/.idea/libraries/Maven__org_springframework_spring_web_5_3_1.xml deleted file mode 100644 index eda6935f1853b06102f2dab11e5dd6f72cc50277..0000000000000000000000000000000000000000 --- a/.idea/libraries/Maven__org_springframework_spring_web_5_3_1.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_webmvc_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_webmvc_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..eeb639d40ccfd6db32fa86e8e8c147edc00b6aa3 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_webmvc_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_websocket_5_2_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_websocket_5_2_9_RELEASE.xml new file mode 100644 index 0000000000000000000000000000000000000000..e9c0a1ef5a093f2db4164fdf6785ef8da7306164 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_websocket_5_2_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_7_0.xml b/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_4.xml similarity index 61% rename from .idea/libraries/Maven__org_xmlunit_xmlunit_core_2_7_0.xml rename to .idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_4.xml index e557e7d2f9d92304c5b8e09426811c675bdbb235..c9762c004decaafc41116e7ff056e44cb59742e7 100644 --- a/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_7_0.xml +++ b/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_4.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_yaml_snakeyaml_1_27.xml b/.idea/libraries/Maven__org_yaml_snakeyaml_1_25.xml similarity index 66% rename from .idea/libraries/Maven__org_yaml_snakeyaml_1_27.xml rename to .idea/libraries/Maven__org_yaml_snakeyaml_1_25.xml index eb89ee7fbe00c0966802c6deafe778e19700dec9..06aea1bcac064983279317d528b4bf1367db81c9 100644 --- a/.idea/libraries/Maven__org_yaml_snakeyaml_1_27.xml +++ b/.idea/libraries/Maven__org_yaml_snakeyaml_1_25.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__stax_stax_api_1_0_1.xml b/.idea/libraries/Maven__stax_stax_api_1_0_1.xml new file mode 100644 index 0000000000000000000000000000000000000000..5f2c60b1ea5b6dfd7d7a4316b5dc25cc2f32a163 --- /dev/null +++ b/.idea/libraries/Maven__stax_stax_api_1_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__xerces_xercesImpl_2_12_0.xml b/.idea/libraries/Maven__xerces_xercesImpl_2_12_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..edc89fd1abb9d3b201ea090d99c546f6f9ace987 --- /dev/null +++ b/.idea/libraries/Maven__xerces_xercesImpl_2_12_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__xiong_copy_eladmin_tools_1_0.xml b/.idea/libraries/Maven__xiong_copy_eladmin_tools_1_0.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8eb0879ab7b7ffda45a0225f4fe0217e8b07d14 --- /dev/null +++ b/.idea/libraries/Maven__xiong_copy_eladmin_tools_1_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__xml_apis_xml_apis_1_4_01.xml b/.idea/libraries/Maven__xml_apis_xml_apis_1_4_01.xml new file mode 100644 index 0000000000000000000000000000000000000000..ea3ba7cd357da292cb3b7cc9ca660e67736f4ad0 --- /dev/null +++ b/.idea/libraries/Maven__xml_apis_xml_apis_1_4_01.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/javax_annotation.xml b/.idea/libraries/javax_annotation.xml new file mode 100644 index 0000000000000000000000000000000000000000..b94328b9bc6ed543c3f0f116b54a6e82d516b4b5 --- /dev/null +++ b/.idea/libraries/javax_annotation.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 0b726b85ce92bb8972e1ce275cd6ec13c11e1ca8..cc292f6f52611ae0bb63db533ff42b9f6f22002b 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,41 +2,244 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + @@ -86,107 +289,14 @@ + + + - + @@ -822,13 +504,16 @@ - - - + + + + + + @@ -851,9 +536,9 @@ - - + @@ -873,14 +558,6 @@ - - - - - - @@ -913,11 +590,6 @@ - - - - - @@ -966,6 +638,8 @@ + + 1651587095566 @@ -995,11 +669,25 @@ - - @@ -1012,14 +700,13 @@ - - + - + @@ -1028,30 +715,69 @@ - + - - + + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/eladmin-common/src/main/java/xiong/copy/utils/SpringContextHolder.java + 17 + + + + file://$PROJECT_DIR$/eladmin-system/src/main/java/xiong/copy/modules/system/rest/MenuController.java + 64 + + + + + file://$PROJECT_DIR$/eladmin-common/src/main/java/xiong/copy/utils/SpringContextHolder.java + 93 + + + + + file://$PROJECT_DIR$/eladmin-common/src/main/java/xiong/copy/utils/SpringContextHolder.java + 115 + + + + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - - + + + + + + - + - - + + - - + + + + + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + + + + - - + + - + - - + + - - - - + + + + - + - - - - - + + - + - - + + - + - - - - + - - - - - + + - + - - + + - + - - + + - + - - - - - - - + + - + - - - - - - + + - + - + + + - - - - - + + + + + + - - + + + + + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + + + + - + - - + + - + - - + + - + - - + + + + + + + - + - - + + + + + - + - - + + - + - - + + + + - + - - + + + + + + - + - - + + + + - + - - + + + + - + - - + - + - + - - + + + + + - + - - + + + + - + - - + + + + + - + - - + + + + + - + - - + + + + + - + - - + + - + - - + + - + - - + + + + + diff --git a/eladmin-common/eladmin-common.iml b/eladmin-common/eladmin-common.iml index 6d291128119a7cc93d045dd6e6eecd55c9898dec..94f8f219e20c1d1cd9dbaf43930ac2fe6b031f7b 100644 --- a/eladmin-common/eladmin-common.iml +++ b/eladmin-common/eladmin-common.iml @@ -20,123 +20,114 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + - - - - - + + - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -145,21 +136,39 @@ + - - - + + + + + + + + + + + + + + + + + + + + + + - - \ No newline at end of file diff --git a/eladmin-common/src/main/java/xiong/copy/config/AuditorConfig.java b/eladmin-common/src/main/java/xiong/copy/config/AuditorConfig.java index ad7ecfa9c2d081aedd53a61daaab2f5133793308..8c3fe26fd7df2bb4324ca735a0cae11935ca0d26 100644 --- a/eladmin-common/src/main/java/xiong/copy/config/AuditorConfig.java +++ b/eladmin-common/src/main/java/xiong/copy/config/AuditorConfig.java @@ -1,10 +1,12 @@ package xiong.copy.config; import org.springframework.data.domain.AuditorAware; +import org.springframework.stereotype.Component; import xiong.copy.utils.SecurityUtils; import java.util.Optional; - +//这里是 jpa 给启动类 传参使用@EnableJpaAuditing(auditorAwareRef = "") +@Component("auditorAware") public class AuditorConfig implements AuditorAware { @Override public Optional getCurrentAuditor() { diff --git a/eladmin-common/src/main/java/xiong/copy/config/SwaggerConfig.java b/eladmin-common/src/main/java/xiong/copy/config/SwaggerConfig.java index 37c8eb04ee1cbaec1c6902f1db4c09145bac6016..f9ce54c9a42c529d1acb2eac3e4442c4a5269fc1 100644 --- a/eladmin-common/src/main/java/xiong/copy/config/SwaggerConfig.java +++ b/eladmin-common/src/main/java/xiong/copy/config/SwaggerConfig.java @@ -57,7 +57,7 @@ public class SwaggerConfig { private ApiInfo apiInfo() { return new ApiInfoBuilder() .description("一个简单且易上手的 Spring boot 后台管理框架") - .title("EL-ADMIN 接口文档") + .title("XIONG_COPY 接口文档") .version("2.6") .build(); } diff --git a/eladmin-common/src/main/java/xiong/copy/utils/FileUtil.java b/eladmin-common/src/main/java/xiong/copy/utils/FileUtil.java index 93bb187343877d2748ff4ed0e6bc1e23fb026c1f..181721167b4cbaafad8175abd03fc9e2b074ad98 100644 --- a/eladmin-common/src/main/java/xiong/copy/utils/FileUtil.java +++ b/eladmin-common/src/main/java/xiong/copy/utils/FileUtil.java @@ -1,17 +1,28 @@ package xiong.copy.utils; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.poi.excel.BigExcelWriter; +import cn.hutool.poi.excel.ExcelUtil; import com.sun.org.apache.bcel.internal.generic.NEW; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.tomcat.util.http.fileupload.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; +import xiong.copy.exception.BadRequestException; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; +import java.security.MessageDigest; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; +import java.util.Map; /** * File工具类,扩展 hutool 工具包 @@ -19,8 +30,10 @@ import java.util.Date; * @date 2022年4月1日 02点04分 * @see cn.hutool.core.io.FileUtil */ -@Slf4j + public class FileUtil extends cn.hutool.core.io.FileUtil { + private static final Logger log = LoggerFactory.getLogger(FileUtil.class); + /** * 系统临时目录 *
@@ -33,10 +46,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { * linux: /temp * */ - - // public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator; - /** * 定义GB的计算常量 */ @@ -53,8 +63,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { /** * 格式化小数 */ - public static final DecimalFormat DF= new DecimalFormat("0.00"); - + private static final DecimalFormat DF = new DecimalFormat("0.00"); public static final String IMAGE = "图片"; public static final String TXT = "文档"; @@ -62,43 +71,40 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { public static final String VIDEO = "视频"; public static final String OTHER = "其他"; + /** * MultipartFile转File */ - public static File toFile(MultipartFile multipartFile) { // 获取文件名 -// String fileName = multipartFile.getOriginalFilename(); - String fileName = multipartFile.getOriginalFilename(); // 获取文件后缀 String prefix = "." + getExtensionName(fileName); File file = null; try { -// 用uuid作为文件名,防止生成的临时文件重复 - file = new File(SYS_TEM_DIR+IdUtil.fastSimpleUUID()+prefix); - multipartFile.transferTo(file);//MultipartFile to File + // 用uuid作为文件名,防止生成的临时文件重复 + file = new File(SYS_TEM_DIR + IdUtil.simpleUUID() + prefix); + // MultipartFile to File + multipartFile.transferTo(file); } catch (IOException e) { log.error(e.getMessage(), e); } - - return file; } - private static String getExtensionName(String fileName) { - //获取后缀名 ‘.’ 后的字符串 - if ((fileName != null) && (fileName.length() > 0)){ - int dot = fileName.lastIndexOf("."); - if ((dot>0) && (dot < fileName.length()-1)){ - return fileName.substring(dot+1);//截取最后一个点之后的字符串 + /** + * 获取文件扩展名,不带 . + */ + public static String getExtensionName(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length() - 1))) { + return filename.substring(dot + 1); } } - - return fileName; + return filename; } - /** * Java文件操作 获取不带扩展名的文件名 */ @@ -106,38 +112,32 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { if ((filename != null) && (filename.length() > 0)) { int dot = filename.lastIndexOf('.'); if ((dot > -1) && (dot < (filename.length()))) { - return filename.substring(0, dot);//截取最后一个点之前的字符串 + return filename.substring(0, dot); } } - return filename; } - /** * 文件大小转换 - * @param size - * @return resultSize */ - - public static String getSize(long size){ + public static String getSize(long size) { String resultSize; - if (size/GB >= 1){ - resultSize = DF.format(size/(double)GB) + "GB "; - }else if (size / MB >= 1) { + if (size / GB >= 1) { + //如果当前Byte的值大于等于1GB + resultSize = DF.format(size / (float) GB) + "GB "; + } else if (size / MB >= 1) { //如果当前Byte的值大于等于1MB - resultSize = DF.format(size / (double) MB) + "MB "; + resultSize = DF.format(size / (float) MB) + "MB "; } else if (size / KB >= 1) { //如果当前Byte的值大于等于1KB - resultSize = DF.format(size / (double) KB) + "KB "; + resultSize = DF.format(size / (float) KB) + "KB "; } else { resultSize = size + "B "; } - return resultSize; } - /** * inputStream 转 File */ @@ -164,8 +164,6 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { return file; } - - /** * 将文件名解析成文件的上传路径 */ @@ -195,7 +193,118 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { return null; } + /** + * 导出excel + */ + public static void downloadExcel(List> list, HttpServletResponse response) throws IOException { + String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx"; + File file = new File(tempPath); + BigExcelWriter writer = ExcelUtil.getBigWriter(file); + // 一次性写出内容,使用默认样式,强制输出标题 + writer.write(list, true); + SXSSFSheet sheet = (SXSSFSheet)writer.getSheet(); + //上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法 + sheet.trackAllColumnsForAutoSizing(); + //列宽自适应 + writer.autoSizeColumnAll(); + //response为HttpServletResponse对象 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); + //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码 + response.setHeader("Content-Disposition", "attachment;filename=file.xlsx"); + ServletOutputStream out = response.getOutputStream(); + // 终止后删除临时文件 + file.deleteOnExit(); + writer.flush(out, true); + //此处记得关闭输出Servlet流 + IoUtil.close(out); + } + + public static String getFileType(String type) { + String documents = "txt doc pdf ppt pps xlsx xls docx"; + String music = "mp3 wav wma mpa ram ra aac aif m4a"; + String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg"; + String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg"; + if (image.contains(type)) { + return IMAGE; + } else if (documents.contains(type)) { + return TXT; + } else if (music.contains(type)) { + return MUSIC; + } else if (video.contains(type)) { + return VIDEO; + } else { + return OTHER; + } + } + + public static void checkSize(long maxSize, long size) { + // 1M + int len = 1024 * 1024; + if (size > (maxSize * len)) { + throw new BadRequestException("文件超出规定大小"); + } + } + + /** + * 判断两个文件是否相同 + */ + public static boolean check(File file1, File file2) { + String img1Md5 = getMd5(file1); + String img2Md5 = getMd5(file2); + if(img1Md5 != null){ + return img1Md5.equals(img2Md5); + } + return false; + } + + /** + * 判断两个文件是否相同 + */ + public static boolean check(String file1Md5, String file2Md5) { + return file1Md5.equals(file2Md5); + } + + private static byte[] getByte(File file) { + // 得到文件长度 + byte[] b = new byte[(int) file.length()]; + InputStream in = null; + try { + in = new FileInputStream(file); + try { + System.out.println(in.read(b)); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } finally { + CloseUtil.close(in); + } + return b; + } + private static String getMd5(byte[] bytes) { + // 16进制字符 + char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(bytes); + byte[] md = mdTemp.digest(); + int j = md.length; + char[] str = new char[j * 2]; + int k = 0; + // 移位 输出字符串 + for (byte byte0 : md) { + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } /** * 下载文件 @@ -229,5 +338,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { } } - + public static String getMd5(File file) { + return getMd5(getByte(file)); + } } diff --git a/eladmin-common/src/main/java/xiong/copy/utils/QueryHelp.java b/eladmin-common/src/main/java/xiong/copy/utils/QueryHelp.java new file mode 100644 index 0000000000000000000000000000000000000000..455caca5d9e2434c79885bb02bbbfced9240e23c --- /dev/null +++ b/eladmin-common/src/main/java/xiong/copy/utils/QueryHelp.java @@ -0,0 +1,213 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.utils; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; + +import xiong.copy.annotation.DataPermission; +import xiong.copy.annotation.Query; + +import javax.persistence.criteria.*; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * @author Zheng Jie + * @date 2019-6-4 14:59:48 + */ +@Slf4j +@SuppressWarnings({"unchecked","all"}) +public class QueryHelp { + + public static Predicate getPredicate(Root root, Q query, CriteriaBuilder cb) { + List list = new ArrayList<>(); + if(query == null){ + return cb.and(list.toArray(new Predicate[0])); + } + // 数据权限验证 + DataPermission permission = query.getClass().getAnnotation(DataPermission.class); + if(permission != null){ + // 获取数据权限 + List dataScopes = SecurityUtils.getCurrentUserDataScope(); + if(CollectionUtil.isNotEmpty(dataScopes)){ + if(StringUtils.isNotBlank(permission.joinName()) && StringUtils.isNotBlank(permission.fieldName())) { + Join join = root.join(permission.joinName(), JoinType.LEFT); + list.add(getExpression(permission.fieldName(),join, root).in(dataScopes)); + } else if (StringUtils.isBlank(permission.joinName()) && StringUtils.isNotBlank(permission.fieldName())) { + list.add(getExpression(permission.fieldName(),null, root).in(dataScopes)); + } + } + } + try { + List fields = getAllFields(query.getClass(), new ArrayList<>()); + for (Field field : fields) { + boolean accessible = field.isAccessible(); + // 设置对象的访问权限,保证对private的属性的访 + field.setAccessible(true); + Query q = field.getAnnotation(Query.class); + if (q != null) { + String propName = q.propName(); + String joinName = q.jionName(); + String blurry = q.blurry(); + String attributeName = isBlank(propName) ? field.getName() : propName; + Class fieldType = field.getType(); + Object val = field.get(query); + if (ObjectUtil.isNull(val) || "".equals(val)) { + continue; + } + Join join = null; + // 模糊多字段 + if (ObjectUtil.isNotEmpty(blurry)) { + String[] blurrys = blurry.split(","); + List orPredicate = new ArrayList<>(); + for (String s : blurrys) { + orPredicate.add(cb.like(root.get(s) + .as(String.class), "%" + val.toString() + "%")); + } + Predicate[] p = new Predicate[orPredicate.size()]; + list.add(cb.or(orPredicate.toArray(p))); + continue; + } + if (ObjectUtil.isNotEmpty(joinName)) { + String[] joinNames = joinName.split(">"); + for (String name : joinNames) { + switch (q.jion()) { + case LEFT: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.LEFT); + } else { + join = root.join(name, JoinType.LEFT); + } + break; + case RIGHT: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.RIGHT); + } else { + join = root.join(name, JoinType.RIGHT); + } + break; + case INNER: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.INNER); + } else { + join = root.join(name, JoinType.INNER); + } + break; + default: break; + } + } + } + switch (q.type()) { + case EQUAL: + list.add(cb.equal(getExpression(attributeName,join,root) + .as((Class) fieldType),val)); + break; + case GREATER_THAN: + list.add(cb.greaterThanOrEqualTo(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case LESS_THAN: + list.add(cb.lessThanOrEqualTo(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case LESS_THAN_NQ: + list.add(cb.lessThan(getExpression(attributeName,join,root) + .as((Class) fieldType), (Comparable) val)); + break; + case INNER_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), "%" + val.toString() + "%")); + break; + case LEFT_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), "%" + val.toString())); + break; + case RIGHT_LIKE: + list.add(cb.like(getExpression(attributeName,join,root) + .as(String.class), val.toString() + "%")); + break; + case IN: + if (CollUtil.isNotEmpty((Collection)val)) { + list.add(getExpression(attributeName,join,root).in((Collection) val)); + } + break; + case NOT_IN: + if (CollUtil.isNotEmpty((Collection)val)) { + list.add(getExpression(attributeName,join,root).in((Collection) val).not()); + } + break; + case NOT_EQUAL: + list.add(cb.notEqual(getExpression(attributeName,join,root), val)); + break; + case NOT_NULL: + list.add(cb.isNotNull(getExpression(attributeName,join,root))); + break; + case IS_NULL: + list.add(cb.isNull(getExpression(attributeName,join,root))); + break; + case BETWEEN: + List between = new ArrayList<>((List)val); + list.add(cb.between(getExpression(attributeName, join, root).as((Class) between.get(0).getClass()), + (Comparable) between.get(0), (Comparable) between.get(1))); + break; + default: break; + } + } + field.setAccessible(accessible); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + int size = list.size(); + return cb.and(list.toArray(new Predicate[size])); + } + + @SuppressWarnings("unchecked") + private static Expression getExpression(String attributeName, Join join, Root root) { + if (ObjectUtil.isNotEmpty(join)) { + return join.get(attributeName); + } else { + return root.get(attributeName); + } + } + + private static boolean isBlank(final CharSequence cs) { + int strLen; + if (cs == null || (strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; + } + + public static List getAllFields(Class clazz, List fields) { + if (clazz != null) { + fields.addAll(Arrays.asList(clazz.getDeclaredFields())); + getAllFields(clazz.getSuperclass(), fields); + } + return fields; + } +} diff --git a/eladmin-common/src/main/java/xiong/copy/utils/RedisUtils.java b/eladmin-common/src/main/java/xiong/copy/utils/RedisUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..1f75bcd966a00788e377dbd9dfe74a386dccced7 --- /dev/null +++ b/eladmin-common/src/main/java/xiong/copy/utils/RedisUtils.java @@ -0,0 +1,715 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.utils; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.Cursor; +import org.springframework.data.redis.core.RedisConnectionUtils; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ScanOptions; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * @author / + */ +@Component +@SuppressWarnings({"unchecked", "all"}) +public class RedisUtils { + private static final Logger log = LoggerFactory.getLogger(RedisUtils.class); + private RedisTemplate redisTemplate; + @Value("${jwt.online-key}") + private String onlineKey; + + public RedisUtils(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + +// @Autowired +// private RedisTemplate redisTemplate; + + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + return true; + } + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @param timeUnit 单位 + */ + public boolean expire(String key, long time, TimeUnit timeUnit) { + try { + if (time > 0) { + redisTemplate.expire(key, time, timeUnit); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + return true; + } + + /** + * 根据 key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(Object key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 查找匹配key + * + * @param pattern key + * @return / + */ + public List scan(String pattern) { + ScanOptions options = ScanOptions.scanOptions().match(pattern).build(); + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection rc = Objects.requireNonNull(factory).getConnection(); + Cursor cursor = rc.scan(options); + List result = new ArrayList<>(); + while (cursor.hasNext()) { + result.add(new String(cursor.next())); + } + try { + RedisConnectionUtils.releaseConnection(rc, factory); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return result; + } + + /** + * 分页查询 key + * + * @param patternKey key + * @param page 页码 + * @param size 每页数目 + * @return / + */ + public List findKeysForPage(String patternKey, int page, int size) { + ScanOptions options = ScanOptions.scanOptions().match(patternKey).build(); + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection rc = Objects.requireNonNull(factory).getConnection(); + Cursor cursor = rc.scan(options); + List result = new ArrayList<>(size); + int tmpIndex = 0; + int fromIndex = page * size; + int toIndex = page * size + size; + while (cursor.hasNext()) { + if (tmpIndex >= fromIndex && tmpIndex < toIndex) { + result.add(new String(cursor.next())); + tmpIndex++; + continue; + } + // 获取到满足条件的数据后,就可以退出了 + if (tmpIndex >= toIndex) { + break; + } + tmpIndex++; + cursor.next(); + } + try { + RedisConnectionUtils.releaseConnection(rc, factory); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return result; + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + public void del(String... keys) { + if (keys != null && keys.length > 0) { + if (keys.length == 1) { + boolean result = redisTemplate.delete(keys[0]); + log.debug("--------------------------------------------"); + log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString()); + log.debug("--------------------------------------------"); + } else { + Set keySet = new HashSet<>(); + for (String key : keys) { + keySet.addAll(redisTemplate.keys(key)); + } + long count = redisTemplate.delete(keySet); + log.debug("--------------------------------------------"); + log.debug("成功删除缓存:" + keySet.toString()); + log.debug("缓存删除数量:" + count + "个"); + log.debug("--------------------------------------------"); + } + } + } + + // ============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 批量获取 + * + * @param keys + * @return + */ + public List multiGet(List keys) { + List list = redisTemplate.opsForValue().multiGet(Sets.newHashSet(keys)); + List resultList = Lists.newArrayList(); + Optional.ofNullable(list).ifPresent(e-> list.forEach(ele-> Optional.ofNullable(ele).ifPresent(resultList::add))); + return resultList; + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间 + * @param timeUnit 类型 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time, TimeUnit timeUnit) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, timeUnit); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + // ================================Map================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return / + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + return redisTemplate.opsForList().remove(key, count, value); + } catch (Exception e) { + log.error(e.getMessage(), e); + return 0; + } + } + + /** + * @param prefix 前缀 + * @param ids id + */ + public void delByKeys(String prefix, Set ids) { + Set keys = new HashSet<>(); + for (Long id : ids) { + keys.addAll(redisTemplate.keys(new StringBuffer(prefix).append(id).toString())); + } + long count = redisTemplate.delete(keys); + // 此处提示可自行删除 + log.debug("--------------------------------------------"); + log.debug("成功删除缓存:" + keys.toString()); + log.debug("缓存删除数量:" + count + "个"); + log.debug("--------------------------------------------"); + } +} diff --git a/eladmin-common/src/main/java/xiong/copy/utils/RsaUtils.java b/eladmin-common/src/main/java/xiong/copy/utils/RsaUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..5b222639a634e9400d119086c560793c31623de3 --- /dev/null +++ b/eladmin-common/src/main/java/xiong/copy/utils/RsaUtils.java @@ -0,0 +1,199 @@ +package xiong.copy.utils; + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import java.io.ByteArrayOutputStream; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * @author https://www.cnblogs.com/nihaorz/p/10690643.html + * @description Rsa 工具类,公钥私钥生成,加解密 + * @date 2020-05-18 + **/ +public class RsaUtils { + + private static final String SRC = "123456"; + + public static void main(String[] args) throws Exception { + System.out.println("\n"); + RsaKeyPair keyPair = generateKeyPair(); + System.out.println("公钥:" + keyPair.getPublicKey()); + System.out.println("私钥:" + keyPair.getPrivateKey()); + System.out.println("\n"); + test1(keyPair); + System.out.println("\n"); + test2(keyPair); + System.out.println("\n"); + } + + /** + * 公钥加密私钥解密 + */ + private static void test1(RsaKeyPair keyPair) throws Exception { + System.out.println("***************** 公钥加密私钥解密开始 *****************"); + String text1 = encryptByPublicKey(keyPair.getPublicKey(), RsaUtils.SRC); + String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1); + System.out.println("加密前:" + RsaUtils.SRC); + System.out.println("加密后:" + text1); + System.out.println("解密后:" + text2); + if (RsaUtils.SRC.equals(text2)) { + System.out.println("解密字符串和原始字符串一致,解密成功"); + } else { + System.out.println("解密字符串和原始字符串不一致,解密失败"); + } + System.out.println("***************** 公钥加密私钥解密结束 *****************"); + } + + /** + * 私钥加密公钥解密 + * @throws Exception / + */ + private static void test2(RsaKeyPair keyPair) throws Exception { + System.out.println("***************** 私钥加密公钥解密开始 *****************"); + String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), RsaUtils.SRC); + String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1); + System.out.println("加密前:" + RsaUtils.SRC); + System.out.println("加密后:" + text1); + System.out.println("解密后:" + text2); + if (RsaUtils.SRC.equals(text2)) { + System.out.println("解密字符串和原始字符串一致,解密成功"); + } else { + System.out.println("解密字符串和原始字符串不一致,解密失败"); + } + System.out.println("***************** 私钥加密公钥解密结束 *****************"); + } + + /** + * 公钥解密 + * + * @param publicKeyText 公钥 + * @param text 待解密的信息 + * @return / + * @throws Exception / + */ + public static String decryptByPublicKey(String publicKeyText, String text) throws Exception { + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + byte[] result = doLongerCipherFinal(Cipher.DECRYPT_MODE, cipher, Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 私钥加密 + * + * @param privateKeyText 私钥 + * @param text 待加密的信息 + * @return / + * @throws Exception / + */ + public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + byte[] result = doLongerCipherFinal(Cipher.ENCRYPT_MODE, cipher, text.getBytes()); + return Base64.encodeBase64String(result); + } + + /** + * 私钥解密 + * + * @param privateKeyText 私钥 + * @param text 待解密的文本 + * @return / + * @throws Exception / + */ + public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception { + PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] result = doLongerCipherFinal(Cipher.DECRYPT_MODE, cipher, Base64.decodeBase64(text)); + return new String(result); + } + + /** + * 公钥加密 + * + * @param publicKeyText 公钥 + * @param text 待加密的文本 + * @return / + */ + public static String encryptByPublicKey(String publicKeyText, String text) throws Exception { + X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] result = doLongerCipherFinal(Cipher.ENCRYPT_MODE, cipher, text.getBytes()); + return Base64.encodeBase64String(result); + } + + private static byte[] doLongerCipherFinal(int opMode,Cipher cipher, byte[] source) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + if (opMode == Cipher.DECRYPT_MODE) { + out.write(cipher.doFinal(source)); + } else { + int offset = 0; + int totalSize = source.length; + while (totalSize - offset > 0) { + int size = Math.min(cipher.getOutputSize(0) - 11, totalSize - offset); + out.write(cipher.doFinal(source, offset, size)); + offset += size; + } + } + out.close(); + return out.toByteArray(); + } + + /** + * 构建RSA密钥对 + * + * @return / + * @throws NoSuchAlgorithmException / + */ + public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(1024); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); + String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded()); + String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded()); + return new RsaKeyPair(publicKeyString, privateKeyString); + } + + + /** + * RSA密钥对对象 + */ + public static class RsaKeyPair { + + private final String publicKey; + private final String privateKey; + + public RsaKeyPair(String publicKey, String privateKey) { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + public String getPublicKey() { + return publicKey; + } + + public String getPrivateKey() { + return privateKey; + } + + } +} diff --git a/eladmin-common/src/main/java/xiong/copy/utils/SpringContextHolder.java b/eladmin-common/src/main/java/xiong/copy/utils/SpringContextHolder.java index c0d198b14482c2aaef1b4283a58c3cd059196e43..c5ece8bd0a95238e1d94b48b2416aa50facfb475 100644 --- a/eladmin-common/src/main/java/xiong/copy/utils/SpringContextHolder.java +++ b/eladmin-common/src/main/java/xiong/copy/utils/SpringContextHolder.java @@ -6,18 +6,18 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.env.Environment; - -import javax.naming.Name; -import javax.swing.*; -import javax.swing.text.StringContent; import java.util.ArrayList; import java.util.List; +/** + * @author Jie + * @date 2019-01-07 + */ @Slf4j public class SpringContextHolder implements ApplicationContextAware, DisposableBean { private static ApplicationContext applicationContext = null; private static final List CALL_BACKS = new ArrayList<>(); - private static boolean addCallback = true; //静态私有类属性 + private static boolean addCallback = true; /** * 针对 某些初始化方法,在SpringContextHolder 未初始化时 提交回调方法。 @@ -25,25 +25,13 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB * * @param callBack 回调函数 */ -// public synchronized static void addCallBacks(CallBack callBack) { -// if (addCallback) { -// SpringContextHolder.CALL_BACKS.add(callBack); -// } else { -// log.warn("CallBack:{} 已无法添加!立即执行", callBack.getCallBackName()); -// callBack.executor(); -// } -// } - - - - public static void addCallBacks(CallBack callBack){ - if (addCallback){ //经过 setApplicationContext addCallback =false + public synchronized static void addCallBacks(CallBack callBack) { + if (addCallback) { SpringContextHolder.CALL_BACKS.add(callBack); - }else { - log.warn("CallBack:{} 已无法添加!立即执行",callBack.getCallBackName()); + } else { + log.warn("CallBack:{} 已无法添加!立即执行", callBack.getCallBackName()); callBack.executor(); } - } /** @@ -58,13 +46,11 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB /** * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. */ - - public static T getBean(Class requiredType){ + public static T getBean(Class requiredType) { assertContextInjected(); return applicationContext.getBean(requiredType); } - /** * 获取SpringBoot 配置信息 * @@ -73,24 +59,13 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB * @param requiredType 返回类型 * @return / */ -// public static T getProperties(String property, T defaultValue, Class requiredType) { -// T result = defaultValue; -// try { -// result = getBean(Environment.class).getProperty(property, requiredType); -// } catch (Exception ignored) {} -// return result; -// } - public static T getProperties(String property,T defaultValue,Class requiredType){ - T result = defaultValue; - try { - result = getBean(Environment.class).getProperty(property,requiredType); - } catch (Exception e) { -// e.printStackTrace(); 为啥不用这个呢 - } - return result; - } - - + public static T getProperties(String property, T defaultValue, Class requiredType) { + T result = defaultValue; + try { + result = getBean(Environment.class).getProperty(property, requiredType); + } catch (Exception ignored) {} + return result; + } /** * 获取SpringBoot 配置信息 @@ -130,7 +105,6 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext); applicationContext = null; - } @Override @@ -140,31 +114,16 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { -// if (SpringContextHolder.applicationContext != null) { -// log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext); -// } -// SpringContextHolder.applicationContext = applicationContext; -// if (addCallback) { -// for (CallBack callBack : SpringContextHolder.CALL_BACKS) { -// callBack.executor(); -// } -// CALL_BACKS.clear(); -// } -// SpringContextHolder.addCallback = false; - - - if (SpringContextHolder.applicationContext != null){ + if (SpringContextHolder.applicationContext != null) { log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext); } - if (addCallback){ - for (CallBack callBack : SpringContextHolder.CALL_BACKS){ - callBack.executor(); //让每个都执行 + SpringContextHolder.applicationContext = applicationContext; + if (addCallback) { + for (CallBack callBack : SpringContextHolder.CALL_BACKS) { + callBack.executor(); } - CALL_BACKS.clear(); //list 结合类的clear + CALL_BACKS.clear(); } - SpringContextHolder.addCallback = false; //调用这个方法 以后Call_BACKS就没了 - //也添加不了 addCallback - + SpringContextHolder.addCallback = false; } - -}//主要 用getBean , getProperties +} diff --git a/eladmin-common/src/main/java/xiong/copy/utils/ValidationUtil.java b/eladmin-common/src/main/java/xiong/copy/utils/ValidationUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..b4a32bdd0bf379d2e542dc256d51bb52dde75923 --- /dev/null +++ b/eladmin-common/src/main/java/xiong/copy/utils/ValidationUtil.java @@ -0,0 +1,46 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.utils; + +import cn.hutool.core.util.ObjectUtil; + +import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator; +import xiong.copy.exception.BadRequestException; + +/** + * 验证工具 + * @author Zheng Jie + * @date 2018-11-23 + */ +public class ValidationUtil { + + /** + * 验证空 + */ + public static void isNull(Object obj, String entity, String parameter , Object value){ + if(ObjectUtil.isNull(obj)){ + String msg = entity + " 不存在: "+ parameter +" is "+ value; + throw new BadRequestException(msg); + } + } + + /** + * 验证是否为邮箱 + */ + public static boolean isEmail(String email) { + return new EmailValidator().isValid(email, null); + } +} diff --git a/eladmin-generator/eladmin-generator.iml b/eladmin-generator/eladmin-generator.iml index eabda43d9cab0e92d56c75cb5f4cf4b796b08692..b3f4840bf05f3117ee5172b5070f3c4d1120da51 100644 --- a/eladmin-generator/eladmin-generator.iml +++ b/eladmin-generator/eladmin-generator.iml @@ -21,128 +21,119 @@ - - - - + + + + - - + + - + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + - + + + + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + @@ -151,21 +142,39 @@ + - - - + + + + + + + + + + + + + + + + + + + + + + - - \ No newline at end of file diff --git a/eladmin-generator/src/main/java/xiong/copy/rest/GenConfigController.java b/eladmin-generator/src/main/java/xiong/copy/rest/GenConfigController.java index fa9a6f097aa3a30f455ed68a224a158e7151a19d..60936f27d690d799c31e983c016de53e579d0a4f 100644 --- a/eladmin-generator/src/main/java/xiong/copy/rest/GenConfigController.java +++ b/eladmin-generator/src/main/java/xiong/copy/rest/GenConfigController.java @@ -23,19 +23,12 @@ public class GenConfigController { @ApiOperation("查询") @GetMapping(value = "/{tableName}") public ResponseEntity query(@PathVariable String tableName){ - return new ResponseEntity(genConfigService.find(tableName),HttpStatus.OK); + return new ResponseEntity<>(genConfigService.find(tableName), HttpStatus.OK); } - /** - * 使用了@Validated @RequestBody - * */ - @ApiOperation("修改") @PutMapping public ResponseEntity update(@Validated @RequestBody GenConfig genConfig){ return new ResponseEntity<>(genConfigService.update(genConfig.getTableName(), genConfig),HttpStatus.OK); } - - - } diff --git a/eladmin-generator/src/main/java/xiong/copy/rest/GeneratorController.java b/eladmin-generator/src/main/java/xiong/copy/rest/GeneratorController.java index 22cfba52540e91b93732cce3db2392f18688746a..781dc2812c5beb5796f7677a2ade40fa900646c9 100644 --- a/eladmin-generator/src/main/java/xiong/copy/rest/GeneratorController.java +++ b/eladmin-generator/src/main/java/xiong/copy/rest/GeneratorController.java @@ -40,10 +40,10 @@ public class GeneratorController { * @result ResponseEntity */ - @ApiOperation("查询数据库") + @ApiOperation("查询数据库数据") @GetMapping(value = "/tables/all") - public ResponseEntity queryTables (){ - return new ResponseEntity<>(generatorService.getTables(),HttpStatus.OK); + public ResponseEntity queryTables(){ + return new ResponseEntity<>(generatorService.getTables(), HttpStatus.OK); } /** @@ -56,16 +56,14 @@ public class GeneratorController { * RequestParam(default="") 设置默认值 * ??? 这里默认值为"10" Integer 能接收吗 */ - @ApiOperation("查询数据库数据") @GetMapping(value = "/tables") - public ResponseEntity get1(@RequestParam(defaultValue = "",value = "name") String name , - @RequestParam(defaultValue = "0",value = "page") Integer page, - @RequestParam(defaultValue = "10",value = "size") Integer size){ + public ResponseEntity queryTables(@RequestParam(defaultValue = "") String name, + @RequestParam(defaultValue = "0")Integer page, + @RequestParam(defaultValue = "10")Integer size){ int[] startEnd = PageUtil.transToStartEnd(page, size); - return new ResponseEntity<>( generatorService.getTables(name,startEnd) ,HttpStatus.OK); + return new ResponseEntity<>(generatorService.getTables(name,startEnd), HttpStatus.OK); } - /** * * @@ -79,7 +77,6 @@ public class GeneratorController { return new ResponseEntity<>(PageUtil.toPage(columnInfos,columnInfos.size()), HttpStatus.OK); } - /** * putMapping * 只要返回状态码 @@ -88,7 +85,7 @@ public class GeneratorController { * */ @ApiOperation("保存字段数据") @PutMapping - public ResponseEntity save(@RequestBody List columnInfos ){ + public ResponseEntity save(@RequestBody List columnInfos){ generatorService.save(columnInfos); return new ResponseEntity<>(HttpStatus.OK); } @@ -103,6 +100,7 @@ public class GeneratorController { } + /** * 生成代码 pathVariable * type 值 @@ -112,33 +110,25 @@ public class GeneratorController { * 2 download 下载 * */ @ApiOperation("生成代码") - @RequestMapping(value = "/{tableName}/{type}") - public ResponseEntity genrator(@PathVariable("tableName") String tableName, - @PathVariable("type") Integer type, - HttpServletRequest request, HttpServletResponse response){ - - if (!generatorEnabled && type ==0){ + @PostMapping(value = "/{tableName}/{type}") + public ResponseEntity generator(@PathVariable String tableName, @PathVariable Integer type, HttpServletRequest request, HttpServletResponse response){ + if(!generatorEnabled && type == 0){ throw new BadRequestException("此环境不允许生成代码,请选择预览或者下载查看!"); } - - - switch (type) - { - //生产 - case 0: - generatorService.generator(genConfigService.find(tableName), generatorService.getColumns(tableName)); + switch (type){ + // 生成代码 + case 0: generatorService.generator(genConfigService.find(tableName), generatorService.getColumns(tableName)); break; - //预览 - case 1: - return generatorService.preview(genConfigService.find(tableName),generatorService.getColumns(tableName)); - case 2: - generatorService.download(genConfigService.find(tableName),generatorService.getColumns(tableName), request, response); + // 预览 + case 1: return generatorService.preview(genConfigService.find(tableName), generatorService.getColumns(tableName)); + // 打包 + case 2: generatorService.download(genConfigService.find(tableName), generatorService.getColumns(tableName), request, response); break; - default: throw new BadRequestException("生产代码generation 没有这个选项"); + default: throw new BadRequestException("没有这个选项"); } return new ResponseEntity<>(HttpStatus.OK); - } + } diff --git a/eladmin-generator/src/main/java/xiong/copy/service/impl/GenConfigServiceImpl.java b/eladmin-generator/src/main/java/xiong/copy/service/impl/GenConfigServiceImpl.java index 48f7a09f7f1eebe97953218f837b1bf240293a1b..575ff1d1b6679ce1f2f6ba94efe5ea6ef759980d 100644 --- a/eladmin-generator/src/main/java/xiong/copy/service/impl/GenConfigServiceImpl.java +++ b/eladmin-generator/src/main/java/xiong/copy/service/impl/GenConfigServiceImpl.java @@ -23,12 +23,9 @@ public class GenConfigServiceImpl implements GenConfigService { @Override public GenConfig find(String tableName) { - - GenConfig genConfig = genConfigRepository.findByTableName(tableName); - //没有表就创建 - if (genConfig!=null){ - return new GenConfig(tableName); + if(genConfig == null){ + return new GenConfig(tableName); } return genConfig; } @@ -43,32 +40,28 @@ public class GenConfigServiceImpl implements GenConfigService { @Override public GenConfig update(String tableName, GenConfig genConfig) { + String separator = File.separator; - String symbol ="\\"; String[] paths; - if (symbol.equals(separator)){//适配windows - paths = genConfig.getPath().split("\\\\"); - }else { - paths =genConfig.getPath().split(File.separator); + String symbol = "\\"; + if (symbol.equals(separator)) { + paths = genConfig.getPath().split("\\\\"); + } else { + paths = genConfig.getPath().split(File.separator); } - //找到src api将包添加其后 - StringBuffer api = new StringBuffer(); - for (String path : paths){ + + + StringBuilder api = new StringBuilder(); + for (String path : paths) { api.append(path); - api.append(File.separator); - // src\\api - if ("src".equals(path)){ + api.append(separator); + if ("src".equals(path)) { //目的是将src api.append("api"); break; } - } - - //前端路径 genConfig.setApiPath(api.toString()); - //数据库保存 genConfig return genConfigRepository.save(genConfig); - } } diff --git a/eladmin-generator/src/main/java/xiong/copy/service/impl/GeneratorServiceImpl.java b/eladmin-generator/src/main/java/xiong/copy/service/impl/GeneratorServiceImpl.java index f34a9d0df4ec3b49eba091d0069eded1ae940847..d55ee8b7993462b14c9f738ffda0416a21a79fb5 100644 --- a/eladmin-generator/src/main/java/xiong/copy/service/impl/GeneratorServiceImpl.java +++ b/eladmin-generator/src/main/java/xiong/copy/service/impl/GeneratorServiceImpl.java @@ -4,11 +4,11 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ZipUtil; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.w3c.dom.html.HTMLTableElement; import xiong.copy.domain.ColumnInfo; import xiong.copy.domain.GenConfig; import xiong.copy.domain.vo.TableInfo; @@ -33,170 +33,121 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; - @Service @RequiredArgsConstructor -@Slf4j public class GeneratorServiceImpl implements GeneratorService { - + private static final Logger log = LoggerFactory.getLogger(GeneratorServiceImpl.class); @PersistenceContext private EntityManager em; private final ColumnInfoRepository columnInfoRepository; - @Override public Object getTables() { - //information_schema.tables 系统库.表信息 - //select database()当前数库表 + // 使用预编译防止sql注入 String sql = "select table_name ,create_time , engine, table_collation, table_comment from information_schema.tables " + "where table_schema = (select database()) " + "order by create_time desc"; - Query query= em.createNativeQuery(sql); - return query.getResultList(); //这里不用List是为什么 - - + Query query = em.createNativeQuery(sql); + return query.getResultList(); } - /** - * 传入int数组 start 和 End 值 - * startEnd[0] 与 startEnd[1] - * */ @Override public Object getTables(String name, int[] startEnd) { + // 使用预编译防止sql注入 String sql = "select table_name ,create_time , engine, table_collation, table_comment from information_schema.tables " + "where table_schema = (select database()) " + "and table_name like :table order by create_time desc"; - Query query =em.createNativeQuery(sql); - - query.setFirstResult(startEnd[0]); - ////设置查询的起始下标 - query.setFirstResult(startEnd[0]); - //设置查询结果集的最大数量,返回Query实例 - query.setMaxResults(startEnd[1]-startEnd[0]); - //绑定Parameter对象的值 - //需name 是否为空值 - query.setParameter("table",StringUtils.isNotBlank(name) ? ("%" + name + "%") : "%%"); - - List result = query.getResultList(); - List tableInfos = new ArrayList<>(); - - //每条信息都是对象 - //但返回值是Object 不能直接让tableInfos接收 向下转型 - for (Object obj: tableInfos){ - Object[] arr = (Object[]) obj; - tableInfos.add(new TableInfo(arr[0],arr[1],arr[2],arr[3],ObjectUtil.isNotEmpty(arr[4]) ? arr[4] : "-")); - } - - - String countSql = "select count(1) from information_schema.tables " + - "where table_schema = (select database()) and table_name like :table"; - - Query queryCount = em.createNativeQuery(countSql); - - queryCount.setParameter("table",StringUtils.isBlank(name) ? ("%" + name + "%") : "%%" ); - - //获取单个结果集 是id为160105的记录的统计数据 - Object totalElements = queryCount.getSingleResult(); - - //分页工具 - //tableInfos 获取table信息的数组 - //getSingleResult getSingleResult - return PageUtil.toPage(tableInfos,totalElements); + Query query = em.createNativeQuery(sql); + query.setFirstResult(startEnd[0]); + query.setMaxResults(startEnd[1] - startEnd[0]); + query.setParameter("table", StringUtils.isNotBlank(name) ? ("%" + name + "%") : "%%"); + List result = query.getResultList(); + List tableInfos = new ArrayList<>(); + for (Object obj : result) { + Object[] arr = (Object[]) obj; + tableInfos.add(new TableInfo(arr[0], arr[1], arr[2], arr[3], ObjectUtil.isNotEmpty(arr[4]) ? arr[4] : "-")); + } + String countSql = "select count(1) from information_schema.tables " + + "where table_schema = (select database()) and table_name like :table"; + Query queryCount = em.createNativeQuery(countSql); + queryCount.setParameter("table", StringUtils.isNotBlank(name) ? ("%" + name + "%") : "%%"); + Object totalElements = queryCount.getSingleResult(); + return PageUtil.toPage(tableInfos, totalElements); } @Override - public List getColumns(String name) { - //查找数据库中ColumnInfo 表的信息 - List columnInfos = columnInfoRepository.findByTableNameOrderByIdAsc(name); - - //用hutool的集合判断工具 - //if 不为空 返回list - //else 调用 query() 将结果保存到数据库 - if (CollectionUtil.isNotEmpty(columnInfos)){ + public List getColumns(String tableName) { + List columnInfos = columnInfoRepository.findByTableNameOrderByIdAsc(tableName); + if (CollectionUtil.isNotEmpty(columnInfos)) { return columnInfos; - }else { - columnInfos = query(name); + } else { + columnInfos = query(tableName); return columnInfoRepository.saveAll(columnInfos); } } @Override public List query(String tableName) { + // 使用预编译防止sql注入 String sql = "select column_name, is_nullable, data_type, column_comment, column_key, extra from information_schema.columns " + "where table_name = ? and table_schema = (select database()) order by ordinal_position"; - - Query query = em.createNativeQuery(sql); - query.setParameter(1,tableName); - List result = query.getResultList(); - List columnInfos = new ArrayList<>(); - - for (Object object : result) { - Object[] objs = (Object[]) object; - columnInfos.add(new ColumnInfo( - tableName, - objs[0].toString(), - "NO".equals(objs[1]), - objs[2].toString(), - ObjectUtil.isNotNull(objs[3]) ? objs[3].toString():null, - ObjectUtil.isNotNull(objs[4]) ? objs[4].toString():null, - ObjectUtil.isNotNull(objs[5]) ? objs[5].toString():null - )); - + Query query = em.createNativeQuery(sql); + query.setParameter(1, tableName); + List result = query.getResultList(); + List columnInfos = new ArrayList<>(); + for (Object obj : result) { + Object[] arr = (Object[]) obj; + columnInfos.add( + new ColumnInfo( + tableName, + arr[0].toString(), + //是否必填 + "NO".equals(arr[1]), + arr[2].toString(), + ObjectUtil.isNotNull(arr[3]) ? arr[3].toString() : null, + ObjectUtil.isNotNull(arr[4]) ? arr[4].toString() : null, + ObjectUtil.isNotNull(arr[5]) ? arr[5].toString() : null) + ); } - - return columnInfos; } - /** - * 数据库字段名称 - * @param columnInfoList 数据库中字段集合 - * @param columnInfos 程序中字段集合 - * */ + @Override public void sync(List columnInfos, List columnInfoList) { - for (ColumnInfo columnInfo : columnInfoList){ + // 第一种情况,数据库类字段改变或者新增字段 + for (ColumnInfo columnInfo : columnInfoList) { + // 根据字段名称查找 List columns = columnInfos .stream() - //过滤 取出 从columnInfos 取出与 columnInfoList 的数据库字段名称相同的 - .filter(c->c.getColumnName().equals(columnInfo.getColumnName())) - //可以收集流中的数据到【集合】或者【数组】中去。 + .filter(c -> c.getColumnName().equals(columnInfo.getColumnName())) .collect(Collectors.toList()); + // 如果能找到,就修改部分可能被字段 - if (CollectionUtil.isNotEmpty(columns)){ - //只改变部分,所以随便获取一个 - ColumnInfo col = columns.get(0); -// ColumnInfo col = new ColumnInfo(); - col.setColumnType(columnInfo.getColumnType()); - col.setExtra(columnInfo.getExtra()); - col.setKeyType(columnInfo.getKeyType()); - if (StringUtils.isNotBlank(columnInfo.getRemark())){ - col.setRemark(columnInfo.getRemark()); + if (CollectionUtil.isNotEmpty(columns)) { + ColumnInfo column = columns.get(0); + column.setColumnType(columnInfo.getColumnType()); + column.setExtra(columnInfo.getExtra()); + column.setKeyType(columnInfo.getKeyType()); + if (StringUtils.isBlank(column.getRemark())) { + column.setRemark(columnInfo.getRemark()); } - columnInfoRepository.save(col); - }else { + columnInfoRepository.save(column); + } else { // 如果找不到,则保存新字段信息 columnInfoRepository.save(columnInfo); } + } - }//修改数据库中字段 - - //删除数据库字段 - + // 第二种情况,数据库字段删除了 for (ColumnInfo columnInfo : columnInfos) { // 根据字段名称查找 - List columns = columnInfoList - .stream() - .filter(c -> c.getColumnName().equals(columnInfo.getColumnName())) - .collect(Collectors.toList()); + List columns = columnInfoList.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList()); // 如果找不到,就代表字段被删除了,则需要删除该字段 - if (CollectionUtil.isEmpty(columns)){ + if (CollectionUtil.isEmpty(columns)) { columnInfoRepository.delete(columnInfo); } } - - - } @Override @@ -204,23 +155,17 @@ public class GeneratorServiceImpl implements GeneratorService { columnInfoRepository.saveAll(columnInfos); } - - @Override public void generator(GenConfig genConfig, List columns) { - if (genConfig.getId() == null){ - throw new BadRequestException("请先配置生成器"); + if (genConfig.getId() == null) { + throw new BadRequestException("请先配置生成器"); } - try { GenUtil.generatorCode(columns, genConfig); } catch (IOException e) { log.error(e.getMessage(), e); throw new BadRequestException("生成失败,请手动处理已生成的文件"); } - - - } @Override @@ -228,9 +173,7 @@ public class GeneratorServiceImpl implements GeneratorService { if (genConfig.getId() == null) { throw new BadRequestException("请先配置生成器"); } - List> genList = GenUtil.preview(columns, genConfig); - //返回List> return new ResponseEntity<>(genList, HttpStatus.OK); } @@ -247,11 +190,5 @@ public class GeneratorServiceImpl implements GeneratorService { } catch (IOException e) { throw new BadRequestException("打包失败"); } - - - - } - - } diff --git a/eladmin-generator/src/main/java/xiong/copy/utils/ColUtil.java b/eladmin-generator/src/main/java/xiong/copy/utils/ColUtil.java index b2ff6eab817bd98a37cab8a4631c37acaf2601fe..70748dd5a62fe25873102f36e3d4ea28d5ebe089 100644 --- a/eladmin-generator/src/main/java/xiong/copy/utils/ColUtil.java +++ b/eladmin-generator/src/main/java/xiong/copy/utils/ColUtil.java @@ -1,39 +1,39 @@ package xiong.copy.utils; -import lombok.extern.slf4j.Slf4j; + import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -@Slf4j public class ColUtil { + private static final Logger log = LoggerFactory.getLogger(ColUtil.class); /** * 转换mysql数据类型为java数据类型 * @param type 数据库字段类型 * @return String */ - public static String cloToJava(String type){ - Configuration config = getConfig(); - assert config != null; - return config.getString(type,"unknowType"); - } - - + static String cloToJava(String type) { + Configuration config = getConfig(); + assert config != null; + return config.getString(type, "unknowType"); + } /** * 获取配置信息 */ - - static PropertiesConfiguration getConfig(){ - try { - return new PropertiesConfiguration("generator.properties"); - } catch (ConfigurationException e) { - log.error(e.getMessage(),e); - } - return null; + public static PropertiesConfiguration getConfig() { + try { + return new PropertiesConfiguration("generator.properties"); + } catch (ConfigurationException e) { + log.error(e.getMessage(), e); } - + return null; + } } + + diff --git a/eladmin-generator/src/main/java/xiong/copy/utils/GenUtil.java b/eladmin-generator/src/main/java/xiong/copy/utils/GenUtil.java index 99bf2a1edfc5d44b5bd3388b5befdee6fc70bbe4..57597bbfca7d7443f03d396d3870009191b37041 100644 --- a/eladmin-generator/src/main/java/xiong/copy/utils/GenUtil.java +++ b/eladmin-generator/src/main/java/xiong/copy/utils/GenUtil.java @@ -1,13 +1,11 @@ package xiong.copy.utils; -import ch.qos.logback.classic.db.names.TableName; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.template.*; -import jdk.nashorn.internal.ir.ReturnNode; +import lombok.extern.slf4j.Slf4j; import org.springframework.util.ObjectUtils; import xiong.copy.domain.ColumnInfo; import xiong.copy.domain.GenConfig; -import javax.swing.*; import java.io.File; import java.io.FileWriter; import java.io.IOException; @@ -20,8 +18,10 @@ import java.util.Map; import static xiong.copy.utils.FileUtil.SYS_TEM_DIR; - +@Slf4j +@SuppressWarnings({"unchecked", "all"}) public class GenUtil { + private static final String TIMESTAMP = "Timestamp"; private static final String BIGDECIMAL = "BigDecimal"; @@ -30,7 +30,6 @@ public class GenUtil { public static final String EXTRA = "auto_increment"; - /** * 获取后端代码模板名称 * @@ -61,20 +60,12 @@ public class GenUtil { return templateNames; } - - /** - * 模块获取引擎 - * - * */ public static List> preview(List columns, GenConfig genConfig) { Map genMap = getGenMap(columns, genConfig); List> genList = new ArrayList<>(); - - List templates ; // 获取后端模版 - templates = getAdminTemplateNames(); + List templates = getAdminTemplateNames(); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); - for (String templateName : templates) { Map map = new HashMap<>(1); Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); @@ -82,43 +73,44 @@ public class GenUtil { map.put("name", templateName); genList.add(map); } - + // 获取前端模版 templates = getFrontTemplateNames(); - for (String templateName: templates){ - Map map = new HashMap<>(1); - Template template = engine.getTemplate("generator/front/"+templateName +"./ftl"); - //这里多一步 多存一次 + for (String templateName : templates) { + Map map = new HashMap<>(1); + Template template = engine.getTemplate("generator/front/" + templateName + ".ftl"); map.put(templateName, template.render(genMap)); map.put("content", template.render(genMap)); map.put("name", templateName); genList.add(map); } - return genList; + return genList; } -// 后端 tempPath + "eladmin" + File.separator rootPath - //前端 apipath srcPath - //有返回值 public static String download(List columns, GenConfig genConfig) throws IOException { + // 拼接的路径:/tmpeladmin-gen-temp/,这个路径在Linux下需要root用户才有权限创建,非root用户会权限错误而失败,更改为: /tmp/eladmin-gen-temp/ + // String tempPath =SYS_TEM_DIR + "eladmin-gen-temp" + File.separator + genConfig.getTableName() + File.separator; String tempPath = SYS_TEM_DIR + "eladmin-gen-temp" + File.separator + genConfig.getTableName() + File.separator; Map genMap = getGenMap(columns, genConfig); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); + // 生成后端代码 List templates = getAdminTemplateNames(); - for (String templateName : templates){ - Template template = engine.getTemplate("generator/admin/"+templateName+".ftl"); + for (String templateName : templates) { + Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); + String filePath = getAdminFilePath(templateName, genConfig, genMap.get("className").toString(), tempPath + "eladmin" + File.separator); + assert filePath != null; File file = new File(filePath); - // 如果非覆盖生成 跳过生成 + // 如果非覆盖生成 if (!genConfig.getCover() && FileUtil.exist(file)) { continue; } + // 生成代码 genFile(file, template, genMap); } - + // 生成前端代码 templates = getFrontTemplateNames(); - for (String templateName : templates){ - + for (String templateName : templates) { Template template = engine.getTemplate("generator/front/" + templateName + ".ftl"); String path = tempPath + "eladmin-web" + File.separator; @@ -128,7 +120,6 @@ public class GenUtil { assert filePath != null; File file = new File(filePath); - // 如果非覆盖生成 if (!genConfig.getCover() && FileUtil.exist(file)) { continue; @@ -136,16 +127,13 @@ public class GenUtil { // 生成代码 genFile(file, template, genMap); } - - - return tempPath; - } public static void generatorCode(List columnInfos, GenConfig genConfig) throws IOException { Map genMap = getGenMap(columnInfos, genConfig); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); + // 生成后端代码 List templates = getAdminTemplateNames(); for (String templateName : templates) { Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); @@ -162,6 +150,7 @@ public class GenUtil { // 生成代码 genFile(file, template, genMap); } + // 生成前端代码 templates = getFrontTemplateNames(); for (String templateName : templates) { @@ -178,14 +167,10 @@ public class GenUtil { // 生成代码 genFile(file, template, genMap); } - } - - - - private static Map getGenMap(List columnInfos, GenConfig genConfig){ - + // 获取模版数据 + private static Map getGenMap(List columnInfos, GenConfig genConfig) { // 存储模版字段数据 Map genMap = new HashMap<>(16); // 接口别名 @@ -200,20 +185,16 @@ public class GenUtil { genMap.put("date", LocalDate.now().toString()); // 表名 genMap.put("tableName", genConfig.getTableName()); - - //数据库字段 转换 驼峰命名不同函数 去除 '_' ,转换为大小写 - // 区别: 首字母大写 + // 大写开头的类名 String className = StringUtils.toCapitalizeCamelCase(genConfig.getTableName()); - //首字母小写 + // 小写开头的类名 String changeClassName = StringUtils.toCamelCase(genConfig.getTableName()); - - //去除前缀 - if(StringUtils.isNotEmpty(genConfig.getPrefix())){ - className = StringUtils.toCapitalizeCamelCase(StrUtil.removePrefix(className,genConfig.getPrefix())); + // 判断是否去除表前缀 + if (StringUtils.isNotEmpty(genConfig.getPrefix())) { + className = StringUtils.toCapitalizeCamelCase(StrUtil.removePrefix(genConfig.getTableName(), genConfig.getPrefix())); changeClassName = StringUtils.toCamelCase(StrUtil.removePrefix(genConfig.getTableName(), genConfig.getPrefix())); changeClassName = StringUtils.uncapitalize(changeClassName); } - // 保存类名 genMap.put("className", className); // 保存小写开头的类名 @@ -234,7 +215,6 @@ public class GenUtil { genMap.put("hasDict", false); // 存在日期注解 genMap.put("hasDateAnnotation", false); - // 保存字段信息 List> columns = new ArrayList<>(); // 保存查询字段的信息 @@ -246,21 +226,19 @@ public class GenUtil { // 存储不为空的字段信息 List> isNotNullColumns = new ArrayList<>(); - for (ColumnInfo column : columnInfos){ - Map listMap = new HashMap<>(16); + for (ColumnInfo column : columnInfos) { + Map listMap = new HashMap<>(16); // 字段描述 - listMap.put("remake",column.getRemark()); + listMap.put("remark", column.getRemark()); // 字段类型 - listMap.put("columnKey",column.getColumnName()); - // 主键类型 转成java - String colType = ColUtil.cloToJava(column.getColumnType()); + listMap.put("columnKey", column.getKeyType()); + // 主键类型 + String colType = ColUtil.cloToJava(column.getColumnType()); // 小写开头的字段名 String changeColumnName = StringUtils.toCamelCase(column.getColumnName()); // 大写开头的字段名 String capitalColumnName = StringUtils.toCapitalizeCamelCase(column.getColumnName()); - - //判断是否是主键 , 是主键,map就存储pk开头的 - if (PK.equals(column.getKeyType())){ + if (PK.equals(column.getKeyType())) { // 存储主键类型 genMap.put("pkColumnType", colType); // 存储小写开头的字段名 @@ -268,8 +246,6 @@ public class GenUtil { // 存储大写开头的字段名 genMap.put("pkCapitalColName", capitalColumnName); } - - // 是否存在 Timestamp 类型的字段 if (TIMESTAMP.equals(colType)) { genMap.put("hasTimestamp", true); @@ -287,6 +263,7 @@ public class GenUtil { genMap.put("hasDict", true); dicts.add(column.getDictName()); } + // 存储字段类型 listMap.put("columnType", colType); // 存储字原始段名称 @@ -310,13 +287,10 @@ public class GenUtil { if (StringUtils.isNotBlank(column.getDateAnnotation())) { genMap.put("hasDateAnnotation", true); } - - // 添加非空字段信息 if (column.getNotNull()) { isNotNullColumns.add(listMap); } - // 判断是否有查询,如有则把查询的字段set进columnQuery if (!StringUtils.isBlank(column.getQueryType())) { // 查询类型 @@ -340,7 +314,8 @@ public class GenUtil { } // 添加到字段列表中 columns.add(listMap); - }//循环迭代 + } + //这里存储是List> 向上转型 // 保存字段列表 genMap.put("columns", columns); @@ -353,66 +328,57 @@ public class GenUtil { // 保存非空字段信息 genMap.put("isNotNullColumns", isNotNullColumns); return genMap; - - - } -/** - * 定义后端文件路径以及名称 - * @apiNote getAdminFilePath - * @param templateName - * @param genConfig - * @param className - * @param rootPath - * @result String - */ - -private static String getAdminFilePath(String templateName, GenConfig genConfig, String className, String rootPath) { - String projectPath = rootPath + File.separator + genConfig.getModuleName(); - String packagePath = projectPath + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator; - - if (!ObjectUtils.isEmpty(genConfig.getPack())) { - packagePath += genConfig.getPack().replace(".", File.separator) + File.separator; - } + /** + * 定义后端文件路径以及名称 + */ + private static String getAdminFilePath(String templateName, GenConfig genConfig, String className, String rootPath) { + String projectPath = rootPath + File.separator + genConfig.getModuleName(); + String packagePath = projectPath + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator; - if ("Entity".equals(templateName)) { - return packagePath + "domain" + File.separator + className + ".java"; - } + if (!ObjectUtils.isEmpty(genConfig.getPack())) { + packagePath += genConfig.getPack().replace(".", File.separator) + File.separator; + } - if ("Controller".equals(templateName)) { - return packagePath + "rest" + File.separator + className + "Controller.java"; - } + if ("Entity".equals(templateName)) { + return packagePath + "domain" + File.separator + className + ".java"; + } - if ("Service".equals(templateName)) { - return packagePath + "service" + File.separator + className + "Service.java"; - } + if ("Controller".equals(templateName)) { + return packagePath + "rest" + File.separator + className + "Controller.java"; + } - if ("ServiceImpl".equals(templateName)) { - return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java"; - } + if ("Service".equals(templateName)) { + return packagePath + "service" + File.separator + className + "Service.java"; + } - if ("Dto".equals(templateName)) { - return packagePath + "service" + File.separator + "dto" + File.separator + className + "Dto.java"; - } + if ("ServiceImpl".equals(templateName)) { + return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java"; + } - if ("QueryCriteria".equals(templateName)) { - return packagePath + "service" + File.separator + "dto" + File.separator + className + "QueryCriteria.java"; - } + if ("Dto".equals(templateName)) { + return packagePath + "service" + File.separator + "dto" + File.separator + className + "Dto.java"; + } - if ("Mapper".equals(templateName)) { - return packagePath + "service" + File.separator + "mapstruct" + File.separator + className + "Mapper.java"; - } + if ("QueryCriteria".equals(templateName)) { + return packagePath + "service" + File.separator + "dto" + File.separator + className + "QueryCriteria.java"; + } - if ("Repository".equals(templateName)) { - return packagePath + "repository" + File.separator + className + "Repository.java"; - } + if ("Mapper".equals(templateName)) { + return packagePath + "service" + File.separator + "mapstruct" + File.separator + className + "Mapper.java"; + } - return null; -} + if ("Repository".equals(templateName)) { + return packagePath + "repository" + File.separator + className + "Repository.java"; + } + return null; + } - //获取前端路径 + /** + * 定义前端文件路径以及名称 + */ private static String getFrontFilePath(String templateName, String apiPath, String path, String apiName) { if ("api".equals(templateName)) { @@ -426,20 +392,13 @@ private static String getAdminFilePath(String templateName, GenConfig genConfig, return null; } - - private static void genFile(File file, Template template, Map map) throws IOException { // 生成目标文件 Writer writer = null; try { - //验证文件是否存在 FileUtil.touch(file); writer = new FileWriter(file); - //hutool 创建引擎文件 template.render(map, writer); - - - //多 exception 文件 } catch (TemplateException | IOException e) { throw new RuntimeException(e); } finally { @@ -447,7 +406,5 @@ private static String getAdminFilePath(String templateName, GenConfig genConfig, writer.close(); } } - - - } + diff --git a/eladmin-logging/eladmin-logging.iml b/eladmin-logging/eladmin-logging.iml index fc74f9f6dca171e2c13e6b018f49227ce20e109b..7d6efdb7b20d84fd78368b0042eaf67da6a2b9e1 100644 --- a/eladmin-logging/eladmin-logging.iml +++ b/eladmin-logging/eladmin-logging.iml @@ -15,129 +15,121 @@ + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + - - - - - + + - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -146,21 +138,39 @@ + - - - + + + + + + + + + + + + + + + + + + + + + + - - \ No newline at end of file diff --git a/eladmin-logging/pom.xml b/eladmin-logging/pom.xml index c35e9b85ec281bdb693cbd75c82ba2d5a2b69596..8a90d6b355a93db94108d8328d6b302eb09bafb3 100644 --- a/eladmin-logging/pom.xml +++ b/eladmin-logging/pom.xml @@ -23,19 +23,7 @@ 1.0 - - - - org.springframework.boot - spring-boot-maven-plugin - - exec - - - - - diff --git a/eladmin-logging/src/main/java/xiong/copy/annotation/Log.java b/eladmin-logging/src/main/java/xiong/copy/annotation/Log.java new file mode 100644 index 0000000000000000000000000000000000000000..a072a82c904e0c1abb43a3a0541cf9db96d8dc51 --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/annotation/Log.java @@ -0,0 +1,15 @@ +package xiong.copy.annotation; + +//自定义注解@Log + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Log { + + public String value() default ""; +} diff --git a/eladmin-logging/src/main/java/xiong/copy/aspect/LogAspect.java b/eladmin-logging/src/main/java/xiong/copy/aspect/LogAspect.java new file mode 100644 index 0000000000000000000000000000000000000000..f1f01dde44255917569cc376744c866ecbb250d6 --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/aspect/LogAspect.java @@ -0,0 +1,91 @@ +package xiong.copy.aspect; +import xiong.copy.service.LogService; +import xiong.copy.utils.RequestHolder; +import xiong.copy.utils.SecurityUtils; +import xiong.copy.utils.StringUtils; +import xiong.copy.utils.ThrowableUtil; + +import lombok.extern.slf4j.Slf4j; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; + +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; + +import xiong.copy.domain.Log; +import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; + +@Component +@Aspect +@Slf4j + +//AOP进行增强 +public class LogAspect { + + private LogService logService; + + //ThreadLocal则用于线程间的数据隔离 + ThreadLocal currentTime = new ThreadLocal<>(); + + public LogAspect(LogService logService) { + this.logService = logService; + } + + //配置需要的切入点 + @Pointcut("@annotation(xiong.copy.annotation.Log)") + public void logPointcut(){ + //该方法无方法体,主要为了让同类中其他方法使用此切入点 + } + + /** + *配置环绕通制,使用在方法@Pointcut()上注册的切入点 + * @param joinPoint join point for advice + * */ + @Around("logPointcut()") + public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{ + Object result; + //long 获得当前的时间 + currentTime.set(System.currentTimeMillis()); + //throws Throwable(proceed) + //joinPoint.proceed();在around中可以用,此時可以執行被包裹的代碼,可以根據情況來判斷是否執行被包裹的代碼,以實現控制的作用。 + result = joinPoint.proceed(); +// xiong.copy.domain.Log log = new xiong.copy.domain.Log("INFO",System.currentTimeMillis() - currentTime.get()); + Log log = new Log("INFO",System.currentTimeMillis() - currentTime.get()); + + + currentTime.remove(); + // + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + logService.save(log.getUsername(), StringUtils.getBrowser(request),StringUtils.getIp(request),joinPoint,log); + return result; + } + + /** + *配置异常通知 + * + * @param joinPoint join point for advice + * @param e exception + * **/ + @AfterThrowing(pointcut = "logPointcut()",throwing = "e") + public void logAfterThrowing(JoinPoint joinPoint,Throwable e){ +// xiong.copy.domain.Log log = new xiong.copy.domain.Log("Error", System.currentTimeMillis() - currentTime.get()); + Log log = new Log("Error", System.currentTimeMillis() - currentTime.get()); + currentTime.remove(); + log.setExceptionDetail(ThrowableUtil.getStackTrace(e).getBytes()); + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + logService.save(log.getUsername(), StringUtils.getBrowser(request),StringUtils.getIp(request),(ProceedingJoinPoint)joinPoint,log); + } + + public String getUserName() { + try { + return SecurityUtils.getCurrentUsername(); + } catch (Exception e) { + return ""; + } + } + +} diff --git a/eladmin-logging/src/main/java/xiong/copy/domain/Log.java b/eladmin-logging/src/main/java/xiong/copy/domain/Log.java new file mode 100644 index 0000000000000000000000000000000000000000..c304b998be383d3800a8a03b7d180b258d5788b3 --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/domain/Log.java @@ -0,0 +1,164 @@ +package xiong.copy.domain; + + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import org.hibernate.annotations.CreationTimestamp; +//import org.springframework.data.annotation.Id; + +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +//@Setter +//@Getter +//@NoArgsConstructor +@Entity +@Table(name = "sys_log") +public class Log implements Serializable { + + @Id + @Column(name = "log_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + //操作用户 + private String username; + + //具体得描述 + private String description; + + //方法得名字 + private String method; + + //存在得参数 + private String params; + + //日志得类型 + private String logType; + + //请求得IP + private String requestIp; + + //地址信息 + private String address; + + //浏览器(*) + private String browser; + + //请求得耗时时间 + private Long time; + + //出现得异常得详细信息 + private byte[] exceptionDetail; + + //创建得日期 + @CreationTimestamp + private Timestamp createTime; + + public Log(String logType, Long time) { + this.logType = logType; + this.time = time; + } + + public Log() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getParams() { + return params; + } + + public void setParams(String params) { + this.params = params; + } + + public String getLogType() { + return logType; + } + + public void setLogType(String logType) { + this.logType = logType; + } + + public String getRequestIp() { + return requestIp; + } + + public void setRequestIp(String requestIp) { + this.requestIp = requestIp; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getBrowser() { + return browser; + } + + public void setBrowser(String browser) { + this.browser = browser; + } + + public Long getTime() { + return time; + } + + public void setTime(Long time) { + this.time = time; + } + + public byte[] getExceptionDetail() { + return exceptionDetail; + } + + public void setExceptionDetail(byte[] exceptionDetail) { + this.exceptionDetail = exceptionDetail; + } + + public Timestamp getCreateTime() { + return createTime; + } + + public void setCreateTime(Timestamp createTime) { + this.createTime = createTime; + } +} diff --git a/eladmin-logging/src/main/java/xiong/copy/repository/LogRepository.java b/eladmin-logging/src/main/java/xiong/copy/repository/LogRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..19f3c12492594971195e7ad1e4fdb76881f3c285 --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/repository/LogRepository.java @@ -0,0 +1,24 @@ +package xiong.copy.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.support.JpaRepositoryFactory; +import org.springframework.stereotype.Repository; +import xiong.copy.domain.Log; + + +//根据日志的信息进行删除 + + +@Repository +public interface LogRepository extends JpaRepository, JpaSpecificationExecutor { + + + @Modifying + @Query(value = "delete from sys_log where logType = ?1",nativeQuery = true) + public void deleteByLogType(String logType); + + +} diff --git a/eladmin-logging/src/main/java/xiong/copy/rest/LogController.java b/eladmin-logging/src/main/java/xiong/copy/rest/LogController.java new file mode 100644 index 0000000000000000000000000000000000000000..e6e859b04aa2d8308c7684e715652d7b6993395f --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/rest/LogController.java @@ -0,0 +1,122 @@ +package xiong.copy.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import xiong.copy.annotation.Log; +import xiong.copy.service.LogService; +import xiong.copy.service.dto.LogQueryCriteria; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@RestController +//@RequiredArgsConstructor: 会生成一个包含常量,和标识了NotNull的变量的构造方法。生成的构造方法是私有的private。 +@RequiredArgsConstructor +@RequestMapping("/api/logs") +//@Api: 用在请求的类上,表示对类的说明 +//tags="说明该类的作用,可以在前台界面上看到的注解" +//value="该参数无意义,在UI界面上看不到,不需要配置" +@Api(tags = "系统:日志管理") +public class LogController { + + private final LogService logService; + + //自定义接口 + @Log("导出数据") + //首先@ApiOperation注解不是Spring自带的,它是是swagger里的 + //注解@ApiOperation是用来构建Api文档的 + //@ApiOperation(value = “接口说明”, httpMethod = “接口请求方式”, response = + //“接口返回参数类型”, notes = “接口发布说明”;其他参数可参考源码; + @ApiOperation("导出数据") + @GetMapping(value = "/download") + //@PreAuthorize 注解适合进入方法前的权限验证, @PreAuthorize可以将登录用户的roles/permissions参数传到方法中。 + //@el.check() ElPermissionConfig中判断当前用户的所有权限是否包含接口上定义的权限 返回一个boolean类型,true or false + @PreAuthorize("@el.check()") + public void exportLog(HttpServletResponse response, LogQueryCriteria criteria) throws IOException { + criteria.setLogType("INFO"); + //throws IOException download + // response download中导出日志 void download(List logs, HttpServletResponse response) throws IOException; + logService.download(logService.queryAll(criteria),response); + } + + /** + * 导出 -> void + * 查询,删除 -> ResponseEntity + * 为啥导出无需返回值,是否为日志显示 + * */ + + @Log("导出错误数据") + @ApiOperation("导出错误数据") + @GetMapping("/error/download") + @PreAuthorize("@el.check()") + public void exportErrorLog(HttpServletResponse response,LogQueryCriteria criteria) throws IOException{ + criteria.setLogType("error"); + logService.download(logService.queryAll(criteria),response); + } + + @GetMapping + @ApiOperation("日志查询") + @PreAuthorize("@el.check()") + //使用ResponseEntity作为controller的返回值,我们可以方便地处理响应的header,状态码以及body + //ResponseEntity对应一个http请求或者响应,可以用在controller的返回值里,方便处理header及status。 + /** + * 我们在使用ResponseEntity时,更多的是为了设置不同的HttpResponse Code, + * 如果你的系统偏好是通过Response Body中的Code来判断API状态即几乎所有API的HttpResponse Code=200, + * 那么完全可以不使用ResponseEntity作为返回数据类型,只需要去返回Response Body, + * 通过Body中开发者自定义的Code给API设置状态。 + * */ + //前端显示得到一个200得code,正确true,否则为400,则有错误。 + //而通常使用的@ResponseBody注解,只能处理body部分。这也是为什么通常在下载场景中会使用ResponseEntity, + // 因为下载需要设置header里的content-type以及特殊的status + public ResponseEntity queryLog(LogQueryCriteria criteria, Pageable pageable){ + criteria.setLogType("INFO"); + return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK); + } + + @GetMapping("/user") + @ApiOperation("用户日志查询") + public ResponseEntity queryUserLog(LogQueryCriteria criteria,Pageable pageable){ + criteria.setLogType("INFO"); + return new ResponseEntity<>(logService.queryAllByUser(criteria,pageable),HttpStatus.OK); + } + + @GetMapping("/error") + @ApiOperation("错误日志查询") + @PreAuthorize("@el.check()") + public ResponseEntity queryErrorLog(LogQueryCriteria criteria,Pageable pageable){ + criteria.setLogType("error"); + return new ResponseEntity<>(logService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @GetMapping("/error/{id}") + @ApiOperation("日志异常详情查询") + @PreAuthorize("@el.check()") + public ResponseEntity queryErrorLogDetail(@PathVariable Long id){ + return new ResponseEntity<>(logService.findByErrDetail(id),HttpStatus.OK); + } + + @Log("删除所有ERROR日志") + @ApiOperation("删除所有ERROR日志") + @DeleteMapping("del/error") + @PreAuthorize("@el.check()") + public ResponseEntity delAllErrorLog(){ + logService.delAllByError(); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("删除所有INFO日志") + @ApiOperation("删除所有INFO日志") + @DeleteMapping("del/info") + @PreAuthorize("@el.check()") + public ResponseEntity delAllInfoLog(){ + logService.delAllByInfo(); + return new ResponseEntity<>(HttpStatus.OK); + } + +} diff --git a/eladmin-logging/src/main/java/xiong/copy/service/LogService.java b/eladmin-logging/src/main/java/xiong/copy/service/LogService.java new file mode 100644 index 0000000000000000000000000000000000000000..3a416ace8df075ac38c12cdb882a3d2b421da68a --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/service/LogService.java @@ -0,0 +1,71 @@ +package xiong.copy.service; + + +import org.aspectj.lang.ProceedingJoinPoint; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; +import xiong.copy.domain.Log; +import xiong.copy.service.dto.LogQueryCriteria; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +//logService接口提供方法 +public interface LogService { + + + /** + * 分页查询 + * LogQueryCriteria criteria 查询条件 + * Pageable pageable 分页参数 + * */ + public Object queryAll(LogQueryCriteria criteria, Pageable pageable); + + //查询全部数据 LogQueryCriteria criteria 查询条件 + public List queryAll(LogQueryCriteria criteria); + + /** + * 查询用户日志 + * LogQueryCriteria criteria 查询条件 + * Pageable pageable 分页参数 + * */ + public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable); + + /** + * 保存日志数据 + * @param username 用户 + * @param browser 浏览器 + * @param ip 请求IP + * @param joinPoint/ + * @param log 日志实体 + */ + @Async + public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log); + + /** + * 查询异常详情 + * @param id 日志id domain id + * @return Object + * */ + public Object findByErrDetail(Long id); + + /** + * 导出日志 + * @param logs 需要等待导出的数据 + * @param response/ + * */ + public void download(List logs, HttpServletResponse response) throws IOException; + + /** + * 删除错误日志 + * */ + public void delAllByError(); + + /** + * 删除所有错误日志 + * */ + public void delAllByInfo(); + + +} diff --git a/eladmin-logging/src/main/java/xiong/copy/service/dto/LogErrorDTO.java b/eladmin-logging/src/main/java/xiong/copy/service/dto/LogErrorDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..c7a6f784148661e20b2027a2cea8fcac6270802f --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/service/dto/LogErrorDTO.java @@ -0,0 +1,36 @@ +package xiong.copy.service.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.sql.Timestamp; + +//Data DTO:DTO数据传输对象 + +@Data +public class LogErrorDTO implements Serializable { + + //id + private Long id; + //操作用户 + private String username; + //具体得描述 + private String description; + //方法名 + private String method; + //存在得参数 + private String params; + + //请求的IP + private String requestIp; + //地址信息 + private String address; + + //浏览器 + private String browser; + + //time创建的日期 + private Timestamp createTime; + + +} diff --git a/eladmin-logging/src/main/java/xiong/copy/service/dto/LogQueryCriteria.java b/eladmin-logging/src/main/java/xiong/copy/service/dto/LogQueryCriteria.java new file mode 100644 index 0000000000000000000000000000000000000000..1a7722e41fe06067a1b84972566609788c492d6b --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/service/dto/LogQueryCriteria.java @@ -0,0 +1,25 @@ +package xiong.copy.service.dto; + + +//日志查询类 + +import lombok.Data; +import xiong.copy.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +@Data +public class LogQueryCriteria { + + + @Query(blurry = "username,description,address,requestIp,method,params") + private String blurry; + + @Query + private String logType; + + @Query(type = Query.Type.BETWEEN) + private List createTime; + +} diff --git a/eladmin-logging/src/main/java/xiong/copy/service/dto/LogSmallDTO.java b/eladmin-logging/src/main/java/xiong/copy/service/dto/LogSmallDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..d3c0fad50214b27ee4d2f601af7ceac7dbb92653 --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/service/dto/LogSmallDTO.java @@ -0,0 +1,32 @@ +package xiong.copy.service.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.sql.Timestamp; + +//Data DTO数据传输对象 + +@Data +public class LogSmallDTO implements Serializable { + + //具体的描述 + private String description; + + //请求Ip + private String requestIp; + + //请求的耗时时间 + private Long time; + + //详细地址 + private String address; + + //浏览器 + private String browser; + + //创建的日期 + private Timestamp createTime; + + +} diff --git a/eladmin-logging/src/main/java/xiong/copy/service/impl/LogServiceImpl.java b/eladmin-logging/src/main/java/xiong/copy/service/impl/LogServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..4cdb0d046f12b0af768f236820cbb36b90a108f5 --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/service/impl/LogServiceImpl.java @@ -0,0 +1,221 @@ +package xiong.copy.service.impl; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import lombok.RequiredArgsConstructor; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.ValidationUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import xiong.copy.domain.Log; +import xiong.copy.repository.LogRepository; +import xiong.copy.service.LogService; +import xiong.copy.service.dto.LogQueryCriteria; +import xiong.copy.service.mapstruct.LogErrorMapper; +import xiong.copy.service.mapstruct.LogSmallMapper; +import xiong.copy.utils.*; + +import javax.servlet.http.HttpServletResponse; +import javax.xml.bind.ValidationEvent; +import java.io.IOException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.nio.charset.StandardCharsets; +import java.util.*; + +/** + * 5.5号 + * ycl + * serviceImpl得实现 + * **/ + + +@Service +@RequiredArgsConstructor +public class LogServiceImpl implements LogService { + + private final LogRepository logRepository; + private final LogErrorMapper logErrorMapper; + private final LogSmallMapper logSmallMapper; + + + /** + * 分页查询 + * LogQueryCriteria criteria 查询条件 + * Pageable pageable 分页参数 + * */ + @Override + public Object queryAll(LogQueryCriteria criteria, Pageable pageable) { + //lambda表达式-> jpa的JpaSpecificationExecutor接口提供的方法(findAll()) + //两个参数 ((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb))和pageable + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); + String status = "ERROR"; + if (status.equals(criteria.getLogType())){ + //如果存在异常类型ERROR,则通过分页工具类中的toPage的方法去处理数据(LogErrorDTO中的数据) + return PageUtil.toPage(page.map(logErrorMapper::toDto)); + } + return page; + } + + /** + * 查询全部数据 + * @param criteria 查询条件 + * @return / + */ + @Override + public List queryAll(LogQueryCriteria criteria) { + return logRepository.findAll(((root, query, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + /** + * 查询用户日志 + * LogQueryCriteria criteria 查询条件 + * Pageable pageable 分页参数 + * */ + @Override + public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) { + Page page = logRepository.findAll((((root, query, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))), pageable); + //根据LogSmallDTO里面封装的数据,通过toPage方法处理数据 + //还需要深究具体的逻辑功能如何实现,实现什么以及与其他类等之间的使用 + return PageUtil.toPage(page.map(logSmallMapper::toDto)); + } + + /** + *根据方法和传入的参数获取请求参数 + */ + private String getParameter(Method method,Object[] args){ + List list = new ArrayList<>(); + Parameter[] parameters = method.getParameters(); + for (int i = 1; i < parameters.length; i++){ + //将RequestBody注解修饰得参数作为请求参数 + RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); + if (requestBody != null){ + list.add(args[i]); + } + //将RequestParam注解修饰的参数作为请求参数 + RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); + if (requestParam != null){ + Map map = new HashMap<>(4); + String key = parameters[i].getName(); + if (!StringUtils.isEmpty(requestParam.value())){ + key = requestParam.value(); + } + map.put(key,args[i]); + list.add(map); + } + } + if (list.isEmpty()){ + return ""; + } + return list.size() == 1 ? JSONUtil.toJsonStr(list.get(0)) : JSONUtil.toJsonStr(list); + } + + + /** + * 保存日志数据 + * @param username 用户 + * @param browser 浏览器 + * @param ip 请求IP + * @param joinPoint/ + * @param log 日志实体 + */ + @Override + //Class对象数组,必须继承自Throwable(导致事务回滚的异常类数组) + @Transactional(rollbackFor = Exception.class) + public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log) { + if (log == null){ + throw new IllegalArgumentException("Log不能为空!"); + } + //ProceedingJoinPoint继承了JointPoint,proceed,aop代理链执行的方法 + //在使用springboot写aop的时候,有个JoinPoint类,用来获取代理类和被代理类的信息。 + //访问目标方法即用jointpoint(@around用poceedingjointpoint) + //joinpoint.getSignature():(signature是信号,标识的意思):获取被增强的方法相关信息 + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + //标记获得相应的方法信息 + Method method = signature.getMethod(); + //Log 自定义注解 method.getAnnotation 通过反射将返回该元素注释指定的注释类型 + xiong.copy.annotation.Log aopLog = method.getAnnotation(xiong.copy.annotation.Log.class); + + //综上,获得方法得路径 + String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; + + //描述: + log.setDescription(aopLog.value()); + + log.setRequestIp(ip); + log.setAddress(StringUtils.getCityInfo(log.getRequestIp())); + log.setMethod(methodName); + log.setUsername(username); + //Parameter 根据方法和传入的参数获取请求参数 + log.setParams(getParameter(method,joinPoint.getArgs())); + log.setBrowser(browser); + logRepository.save(log); + } + + /** + * 查询异常详情 + * @param id 日志id domain id + * @return Object + * */ + @Override + public Object findByErrDetail(Long id) { + //findById jpa中的 + // orElseGet() + //当optional值不存在时,调用orElseGet()中接口调用的返回值,如果optional的值存在时返回optional的值 + //如果fingById(id)不为空则返回findById(id)的值,如果findById(id)为空,则返回domain.Log中的异常信息 + Log log = logRepository.findById(id).orElseGet(Log :: new); + //通过工具类的isNull方法,如果对象为空则将返回一个异常BadRequestException + ValidationUtil.isNull(log.getId(),"Log","id",id); + byte[] details = log.getExceptionDetail(); + //hutool + //“::”是Java 8 引入的新特性之一,常常被称作为方法引用,提供了一种不执行方法的方法。 + //先进行判断,如果isNotNull成立,则返回details,不成立,则返回"".getBytes()空;(三目运算符) + return Dict.create().set("exception",new String(ObjectUtil.isNotNull(details) ? details : "".getBytes())); + } + + /** + * 导出日志 + * @param logs 需要等待导出的数据 + * @param response/ + * */ + @Override + public void download(List logs, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (Log log : logs){ + Map map = new LinkedHashMap<>(); + map.put("用户名",log.getUsername()); + map.put("IP",log.getRequestIp()); + map.put("IP来源",log.getAddress()); + map.put("描述",log.getDescription()); + map.put("浏览器",log.getBrowser()); + map.put("请求耗时/毫秒",log.getTime()); + map.put("异常详情",new String(ObjectUtil.isNotNull(log.getExceptionDetail()) ? log.getExceptionDetail() : "".getBytes())); + map.put("创建日期",log.getCreateTime()); + list.add(map); + } + //throws IOException + FileUtil.downloadExcel(list,response); + } + + /** + * 删除错误日志 + * */ + @Override + public void delAllByError() { + logRepository.deleteByLogType("ERROR"); + } + + /** + * 删除所有错误日志 + * */ + @Override + public void delAllByInfo() { + logRepository.deleteByLogType("INFO"); + } +} diff --git a/eladmin-logging/src/main/java/xiong/copy/service/mapstruct/LogErrorMapper.java b/eladmin-logging/src/main/java/xiong/copy/service/mapstruct/LogErrorMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..47181d3c970e9108aea7ca0c861d876759ad75e3 --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/service/mapstruct/LogErrorMapper.java @@ -0,0 +1,15 @@ +package xiong.copy.service.mapstruct; + + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import xiong.copy.base.BaseMapper; +import xiong.copy.domain.Log; +import xiong.copy.service.dto.LogErrorDTO; + + +//Entity转DTO +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LogErrorMapper extends BaseMapper { + +} diff --git a/eladmin-logging/src/main/java/xiong/copy/service/mapstruct/LogSmallMapper.java b/eladmin-logging/src/main/java/xiong/copy/service/mapstruct/LogSmallMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..9b09b399cb613fbeecdce741bcfb880ca487a043 --- /dev/null +++ b/eladmin-logging/src/main/java/xiong/copy/service/mapstruct/LogSmallMapper.java @@ -0,0 +1,14 @@ +package xiong.copy.service.mapstruct; + + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import xiong.copy.base.BaseMapper; +import xiong.copy.domain.Log; +import xiong.copy.service.dto.LogSmallDTO; + + +//Entity转DTO +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface LogSmallMapper extends BaseMapper { +} diff --git a/eladmin-system/eladmin-system.iml b/eladmin-system/eladmin-system.iml index 0c966d56b2dd7f423f9e1f7bbc1dd20130b554bb..344f672cdc0e5eba00971bfd6eb0305d45b4a53d 100644 --- a/eladmin-system/eladmin-system.iml +++ b/eladmin-system/eladmin-system.iml @@ -10,6 +10,7 @@ + @@ -21,13 +22,18 @@ + - + + + + + - + @@ -36,123 +42,123 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + - - - - - + + - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -166,16 +172,33 @@ - - - + + + + + + + + + + + + + + + + + + + + + + - - \ No newline at end of file diff --git a/eladmin-system/pom.xml b/eladmin-system/pom.xml index fcd01107ce6904029ae54a9cd580a14dcb0193e8..ca7f713257db3a7ad15cf074e6f4ccd05e292984 100644 --- a/eladmin-system/pom.xml +++ b/eladmin-system/pom.xml @@ -17,11 +17,22 @@ 1.0 核心模块 eladmin-system + - 1.8 + 0.11.1 + + 5.8.0 + + + + org.springframework.boot + spring-boot-starter-websocket + + + xiong.copy @@ -42,8 +53,52 @@ 1.0 + + + org.springframework.boot + spring-boot-starter-websocket + + + + io.jsonwebtoken + jjwt-api + ${jjwt.version} + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + + + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + + + + org.quartz-scheduler + quartz + + + + ch.ethz.ganymed + ganymed-ssh2 + build210 + + + com.jcraft + jsch + 0.1.55 + + + + + com.github.oshi + oshi-core + 5.7.1 + diff --git a/eladmin-system/src/main/java/xiong/copy/EladminSystemApplication.java b/eladmin-system/src/main/java/xiong/copy/EladminSystemApplication.java index b4b88dda645a0b1fdd9159cf075a351db4bf9ef7..67132761201ae218d2adcec608afe93bd45df9a7 100644 --- a/eladmin-system/src/main/java/xiong/copy/EladminSystemApplication.java +++ b/eladmin-system/src/main/java/xiong/copy/EladminSystemApplication.java @@ -1,13 +1,49 @@ package xiong.copy; +import io.swagger.annotations.Api; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.web.bind.annotation.RestController; +import xiong.copy.annotation.rest.AnonymousGetMapping; +import xiong.copy.utils.SpringContextHolder; +@EnableAsync +@RestController +@Api(hidden = true) @SpringBootApplication +@EnableTransactionManagement +@EnableJpaAuditing(auditorAwareRef = "auditorAware") public class EladminSystemApplication { public static void main(String[] args) { SpringApplication.run(EladminSystemApplication.class, args); } + @Bean + public SpringContextHolder springContextHolder() { + return new SpringContextHolder(); + } + + @Bean + public ServletWebServerFactory webServerFactory() { + TomcatServletWebServerFactory fa = new TomcatServletWebServerFactory(); + fa.addConnectorCustomizers(connector -> connector.setProperty("relaxedQueryChars", "[]{}")); + return fa; + } + /** + * 访问首页提示 + * + * @return / + */ + @AnonymousGetMapping("/") + public String index() { + return "Backend service started successfully"; + } } + diff --git a/eladmin-system/src/main/java/xiong/copy/config/ConfigurerAdapter.java b/eladmin-system/src/main/java/xiong/copy/config/ConfigurerAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..885ba60e3394228086fd809148c48cafb4333b44 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/config/ConfigurerAdapter.java @@ -0,0 +1,101 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.config; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +/** + * WebMvcConfigurer + * + * @author Zheng Jie + * @date 2018-11-30 + */ + + +@Configuration +@EnableWebMvc +public class ConfigurerAdapter implements WebMvcConfigurer { + + /** 文件配置 */ + private final FileProperties properties; + + public ConfigurerAdapter(FileProperties properties) { + this.properties = properties; + } + +// @Override +// public void addCorsMappings(CorsRegistry registry) { +// registry.addMapping("/**") // 所有的当前站点的请求地址,都支持跨域访问。 +// .allowedOriginPatterns("*") // 所有的外部域都可跨域访问。 如果是localhost则很难配置,因为在跨域请求的时候,外部域的解析可能是localhost、127.0.0.1、主机名 +// .allowCredentials(true) // 是否支持跨域用户凭证 +// .maxAge(3600); // 超时时长设置为1小时。 时间单位是秒。 +// } + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + config.addAllowedOrigin("*"); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + FileProperties.ElPath path = properties.getPath(); + String avatarUtl = "file:" + path.getAvatar().replace("\\","/"); + String pathUtl = "file:" + path.getPath().replace("\\","/"); + registry.addResourceHandler("/avatar/**").addResourceLocations(avatarUtl).setCachePeriod(0); + registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0); + registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0); + } + + @Override + public void configureMessageConverters(List> converters) { + // 使用 fastjson 序列化,会导致 @JsonIgnore 失效,可以使用 @JSONField(serialize = false) 替换 + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + List supportMediaTypeList = new ArrayList<>(); + supportMediaTypeList.add(MediaType.APPLICATION_JSON_UTF8); + FastJsonConfig config = new FastJsonConfig(); + config.setDateFormat("yyyy-MM-dd HH:mm:ss"); + config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); + converter.setFastJsonConfig(config); + converter.setSupportedMediaTypes(supportMediaTypeList); + converter.setDefaultCharset(StandardCharsets.UTF_8); + converters.add(converter); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/config/WebSocketConfig.java b/eladmin-system/src/main/java/xiong/copy/config/WebSocketConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..d4087e9a37a2f422bc6ad0eef16e38be44f055fc --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/config/WebSocketConfig.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @author ZhangHouYing + * @date 2019-08-24 15:44 + */ +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/config/thread/AsyncTaskExecutePool.java b/eladmin-system/src/main/java/xiong/copy/config/thread/AsyncTaskExecutePool.java new file mode 100644 index 0000000000000000000000000000000000000000..ea078cbc0d1d61dc2d230c964a1bb818f550fe48 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/config/thread/AsyncTaskExecutePool.java @@ -0,0 +1,55 @@ +package xiong.copy.config.thread; + +import javafx.concurrent.Task; +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import sun.awt.ConstrainableGraphics; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Slf4j +@Configuration +public class AsyncTaskExecutePool implements AsyncConfigurer { + + private final AsyncTaskProperties config; + + @Override + public Executor getAsyncExecutor() { + //这里有 task + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + + executor.setCorePoolSize(config.getCorePoolSize()); + executor.setMaxPoolSize(config.getMaxPoolSize()); + executor.setKeepAliveSeconds(config.getKeepAliveSeconds()); + executor.setQueueCapacity(config.getQueueCapacity()); + + executor.setThreadNamePrefix("el-async-"); + + //设置拒绝策略 + // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + executor.initialize(); + return executor; + } + + public AsyncTaskExecutePool(AsyncTaskProperties config) { + this.config = config; + } + + + /** + * 同步不可控异常 + * 用于捕获run方法中异常 + * */ + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return ((throwable,method,objects)->{ + log.error("===="+throwable.getMessage()+"====", throwable); + log.error("exception method:"+method.getName()); + }); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/config/thread/AsyncTaskProperties.java b/eladmin-system/src/main/java/xiong/copy/config/thread/AsyncTaskProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..307243ca75e09d363c8e1301315818cb63f0a5ff --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/config/thread/AsyncTaskProperties.java @@ -0,0 +1,19 @@ +package xiong.copy.config.thread; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "task.pool") +public class AsyncTaskProperties { + + private int corePoolSize; + + private int maxPoolSize; + + private int keepAliveSeconds; + + private int queueCapacity; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/config/thread/TheadFactoryName.java b/eladmin-system/src/main/java/xiong/copy/config/thread/TheadFactoryName.java new file mode 100644 index 0000000000000000000000000000000000000000..371c851540a3918d93f36ac9c4c4509504d3825c --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/config/thread/TheadFactoryName.java @@ -0,0 +1,50 @@ +package xiong.copy.config.thread; + +import java.security.acl.Group; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +public class TheadFactoryName implements ThreadFactory { + + //POOL_NUMBER ,threadNumber 当前线程池中线程数目 1 + //threadGroup + private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1); + private final AtomicInteger threadNumber = new AtomicInteger(1); + //公共的的线程组 + private ThreadGroup threadGroup; + private final String namePrefix; + + public TheadFactoryName() { + this("el-xyl-pool"); + } + + public TheadFactoryName(String namePrefix) { + //系统中获取安全 的线程组 + SecurityManager s = System.getSecurityManager(); + threadGroup = (s.getThreadGroup() != null) ? + s.getThreadGroup():Thread.currentThread().getThreadGroup(); + //此时namePrefix就是 name + 第几个用这个工厂创建线程池的 + this.namePrefix = namePrefix + POOL_NUMBER.getAndIncrement(); + } + + @Override + public Thread newThread(Runnable r) { + //此时线程的名字 就是 namePrefix + -thread- + 这个线程池中第几个执行的线程 + Thread thread = new Thread(threadGroup,r + ,namePrefix+"-thread-"+threadNumber.getAndIncrement(),0); + + //取消守护,并且设置 + if (thread.isDaemon()) { + thread.setDaemon(false); + } + if (thread.getPriority()!= Thread.NORM_PRIORITY){ + thread.setPriority(Thread.NORM_PRIORITY); + } + + + return thread; + } + + + +} diff --git a/eladmin-system/src/main/java/xiong/copy/config/thread/ThreadPoolExecutorUtil.java b/eladmin-system/src/main/java/xiong/copy/config/thread/ThreadPoolExecutorUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..947f67f03fbee3cb33bb82fec2cc1a51eb562d1b --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/config/thread/ThreadPoolExecutorUtil.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.config.thread; + +import xiong.copy.utils.SpringContextHolder; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 用于获取自定义线程池 + * @author Zheng Jie + * @date 2019年10月31日18:16:47 + */ +public class ThreadPoolExecutorUtil { + + public static ThreadPoolExecutor getPoll(){ + AsyncTaskProperties properties = SpringContextHolder.getBean(AsyncTaskProperties.class); + return new ThreadPoolExecutor( + properties.getCorePoolSize(), + properties.getMaxPoolSize(), + properties.getKeepAliveSeconds(), + TimeUnit.SECONDS, + new ArrayBlockingQueue<>(properties.getQueueCapacity()), + new TheadFactoryName() + ); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/config/ConfigBeanConfiguration.java b/eladmin-system/src/main/java/xiong/copy/modules/security/config/ConfigBeanConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..8aa3eb561b3e380181b2494a8529a2654b9d8dcb --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/config/ConfigBeanConfiguration.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed 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. + */ +package xiong.copy.modules.security.config; + +import xiong.copy.modules.security.config.bean.LoginProperties; +import xiong.copy.modules.security.config.bean.SecurityProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @apiNote 配置文件转换Pojo类的 统一配置 类 + * @author: liaojinlong + * @date: 2020/6/10 19:04 + */ +@Configuration +public class ConfigBeanConfiguration { + + @Bean + @ConfigurationProperties(prefix = "login") + public LoginProperties loginProperties() { + return new LoginProperties(); + } + + @Bean + @ConfigurationProperties(prefix = "jwt") + public SecurityProperties securityProperties() { + return new SecurityProperties(); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/config/SpringSecurityConfig.java b/eladmin-system/src/main/java/xiong/copy/modules/security/config/SpringSecurityConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..1de500857c94b7481b8d17f529eb7a3b945f6816 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/config/SpringSecurityConfig.java @@ -0,0 +1,191 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.config; + +import lombok.RequiredArgsConstructor; +import xiong.copy.annotation.AnonymousAccess; +import xiong.copy.modules.security.config.bean.SecurityProperties; +import xiong.copy.modules.security.security.*; +import xiong.copy.modules.security.service.OnlineUserService; +import xiong.copy.modules.security.service.UserCacheClean; +import xiong.copy.utils.enums.RequestMethodEnum; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.core.GrantedAuthorityDefaults; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.*; + +/** + * @author Zheng Jie + */ +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { + + private final TokenProvider tokenProvider; + private final CorsFilter corsFilter; + private final JwtAuthenticationEntryPoint authenticationErrorHandler; + private final JwtAccessDeniedHandler jwtAccessDeniedHandler; + private final ApplicationContext applicationContext; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + + @Bean + GrantedAuthorityDefaults grantedAuthorityDefaults() { + // 去除 ROLE_ 前缀 + return new GrantedAuthorityDefaults(""); + } + + @Bean + public PasswordEncoder passwordEncoder() { + // 密码加密方式 + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + // 搜寻匿名标记 url: @AnonymousAccess + RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); + Map handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); + // 获取匿名标记 + Map> anonymousUrls = getAnonymousUrl(handlerMethodMap); + httpSecurity + + // 禁用 CSRF + .csrf().disable() + + .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class) + // 授权异常 + .exceptionHandling() + .authenticationEntryPoint(authenticationErrorHandler) + .accessDeniedHandler(jwtAccessDeniedHandler) + // 防止iframe 造成跨域 + .and() + .headers() + .frameOptions() + .disable() + // 不创建会话 + .and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests() + // 静态资源等等 + .antMatchers( + HttpMethod.GET, + "/*.html", + "/**/*.html", + "/**/*.css", + "/**/*.js", + "/webSocket/**" + ).permitAll() + // swagger 文档 + .antMatchers("/swagger-ui.html").permitAll() + .antMatchers("/swagger-resources/**").permitAll() + .antMatchers("/webjars/**").permitAll() + .antMatchers("/*/api-docs").permitAll() + // 文件 + .antMatchers("/avatar/**").permitAll() + .antMatchers("/file/**").permitAll() + // 阿里巴巴 druid + .antMatchers("/druid/**").permitAll() + // 放行OPTIONS请求 + .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() + // 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型 + // GET + .antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll() + // POST + .antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll() + // PUT + .antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll() + // PATCH + .antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll() + // DELETE + .antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll() + // 所有类型的接口都放行 + .antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll() + // 所有请求都需要认证 + .anyRequest().authenticated() + .and().apply(securityConfigurerAdapter()); + } + + private TokenConfigurer securityConfigurerAdapter() { + return new TokenConfigurer(tokenProvider, properties, onlineUserService, userCacheClean); + } + + private Map> getAnonymousUrl(Map handlerMethodMap) { + Map> anonymousUrls = new HashMap<>(6); + Set get = new HashSet<>(); + Set post = new HashSet<>(); + Set put = new HashSet<>(); + Set patch = new HashSet<>(); + Set delete = new HashSet<>(); + Set all = new HashSet<>(); + for (Map.Entry infoEntry : handlerMethodMap.entrySet()) { + HandlerMethod handlerMethod = infoEntry.getValue(); + AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); + if (null != anonymousAccess) { + List requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); + RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name()); + switch (Objects.requireNonNull(request)) { + case GET: + get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case POST: + post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PUT: + put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PATCH: + patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case DELETE: + delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + default: + all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + } + } + } + anonymousUrls.put(RequestMethodEnum.GET.getType(), get); + anonymousUrls.put(RequestMethodEnum.POST.getType(), post); + anonymousUrls.put(RequestMethodEnum.PUT.getType(), put); + anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch); + anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete); + anonymousUrls.put(RequestMethodEnum.ALL.getType(), all); + return anonymousUrls; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginCode.java b/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginCode.java new file mode 100644 index 0000000000000000000000000000000000000000..8a7bd0f6d29a66c1a21f1b516f6a6da504a0c2be --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginCode.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed 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. + */ +package xiong.copy.modules.security.config.bean; + +import lombok.Data; + +/** + * 登录验证码配置信息 + * + * @author liaojinlong + * @date 2020/6/10 18:53 + */ +@Data +public class LoginCode { + + /** + * 验证码配置 + */ + private LoginCodeEnum codeType; + /** + * 验证码有效期 分钟 + */ + private Long expiration = 2L; + /** + * 验证码内容长度 + */ + private int length = 2; + /** + * 验证码宽度 + */ + private int width = 111; + /** + * 验证码高度 + */ + private int height = 36; + /** + * 验证码字体 + */ + private String fontName; + /** + * 字体大小 + */ + private int fontSize = 25; + + public LoginCodeEnum getCodeType() { + return codeType; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginCodeEnum.java b/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginCodeEnum.java new file mode 100644 index 0000000000000000000000000000000000000000..a456659b4a98a2431c0c8f3385964f4ea7280edb --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginCodeEnum.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed 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. + */ +package xiong.copy.modules.security.config.bean; + +/** + * 验证码配置枚举 + * + * @author: liaojinlong + * @date: 2020/6/10 17:40 + */ + +public enum LoginCodeEnum { + /** + * 算数 + */ + arithmetic, + /** + * 中文 + */ + chinese, + /** + * 中文闪图 + */ + chinese_gif, + /** + * 闪图 + */ + gif, + spec +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginProperties.java b/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..b1aa17dceaa13145c1dd03c601a86bfb2f963255 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/LoginProperties.java @@ -0,0 +1,135 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version loginCode.length.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-loginCode.length.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. + */ +package xiong.copy.modules.security.config.bean; + +import com.wf.captcha.*; +import com.wf.captcha.base.Captcha; +import lombok.Data; +import xiong.copy.exception.BadConfigurationException; +import xiong.copy.utils.StringUtils; + +import java.awt.*; +import java.util.Objects; + +/** + * 配置文件读取 + * + * @author liaojinlong + * @date loginCode.length0loginCode.length0/6/10 17:loginCode.length6 + */ +@Data +public class LoginProperties { + + /** + * 账号单用户 登录 + */ + private boolean singleLogin = false; + + private LoginCode loginCode; + + /** + * 用户登录信息缓存 + */ + private boolean cacheEnable; + + public boolean isSingleLogin() { + return singleLogin; + } + + public boolean isCacheEnable() { + return cacheEnable; + } + + /** + * 获取验证码生产类 + * + * @return / + */ + public Captcha getCaptcha() { + if (Objects.isNull(loginCode)) { + loginCode = new LoginCode(); + if (Objects.isNull(loginCode.getCodeType())) { + loginCode.setCodeType(LoginCodeEnum.arithmetic); + } + } + return switchCaptcha(loginCode); + } + + /** + * 依据配置信息生产验证码 + * + * @param loginCode 验证码配置信息 + * @return / + */ + private Captcha switchCaptcha(LoginCode loginCode) { + Captcha captcha; + synchronized (this) { + switch (loginCode.getCodeType()) { + case arithmetic: + // 算术类型 https://gitee.com/whvse/EasyCaptcha + captcha = new FixedArithmeticCaptcha(loginCode.getWidth(), loginCode.getHeight()); + // 几位数运算,默认是两位 + captcha.setLen(loginCode.getLength()); + break; + case chinese: + captcha = new ChineseCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case chinese_gif: + captcha = new ChineseGifCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case gif: + captcha = new GifCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case spec: + captcha = new SpecCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + default: + throw new BadConfigurationException("验证码配置信息错误!正确配置查看 LoginCodeEnum "); + } + } + if(StringUtils.isNotBlank(loginCode.getFontName())){ + captcha.setFont(new Font(loginCode.getFontName(), Font.PLAIN, loginCode.getFontSize())); + } + return captcha; + } + + static class FixedArithmeticCaptcha extends ArithmeticCaptcha { + public FixedArithmeticCaptcha(int width, int height) { + super(width, height); + } + + @Override + protected char[] alphas() { + // 生成随机数字和运算符 + int n1 = num(1, 10), n2 = num(1, 10); + int opt = num(3); + + // 计算结果 + int res = new int[]{n1 + n2, n1 - n2, n1 * n2}[opt]; + // 转换为字符运算符 + char optChar = "+-x".charAt(opt); + + this.setArithmeticString(String.format("%s%c%s=?", n1, optChar, n2)); + this.chars = String.valueOf(res); + + return chars.toCharArray(); + } + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/SecurityProperties.java b/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/SecurityProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..1616c1e1c198e8bf1e8b6a9a92413327c64ef0ad --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/config/bean/SecurityProperties.java @@ -0,0 +1,72 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.config.bean; + +import lombok.Data; + +/** + * Jwt参数配置 + * + * @author Zheng Jie + * @date 2019年11月28日 + */ +@Data +public class SecurityProperties { + + /** + * Request Headers : Authorization + */ + private String header; + + /** + * 令牌前缀,最后留个空格 Bearer + */ + private String tokenStartWith; + + /** + * 必须使用最少88位的Base64对该令牌进行编码 + */ + private String base64Secret; + + /** + * 令牌过期时间 此处单位/毫秒 + */ + private Long tokenValidityInSeconds; + + /** + * 在线用户 key,根据 key 查询 redis 中在线用户的数据 + */ + private String onlineKey; + + /** + * 验证码 key + */ + private String codeKey; + + /** + * token 续期检查 + */ + private Long detect; + + /** + * 续期时间 + */ + private Long renew; + + public String getTokenStartWith() { + return tokenStartWith + " "; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/rest/AuthorizationController.java b/eladmin-system/src/main/java/xiong/copy/modules/security/rest/AuthorizationController.java new file mode 100644 index 0000000000000000000000000000000000000000..9e4090bd159f7e4c6b849434a28cdae152435830 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/rest/AuthorizationController.java @@ -0,0 +1,149 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.rest; + +import cn.hutool.core.util.IdUtil; +import com.wf.captcha.base.Captcha; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import xiong.copy.annotation.rest.AnonymousDeleteMapping; +import xiong.copy.annotation.rest.AnonymousGetMapping; +import xiong.copy.annotation.rest.AnonymousPostMapping; +import xiong.copy.config.RsaProperties; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.security.config.bean.LoginCodeEnum; +import xiong.copy.modules.security.config.bean.LoginProperties; +import xiong.copy.modules.security.config.bean.SecurityProperties; +import xiong.copy.modules.security.security.TokenProvider; +import xiong.copy.modules.security.service.OnlineUserService; +import xiong.copy.modules.security.service.dto.AuthUserDto; +import xiong.copy.modules.security.service.dto.JwtUserDto; +import xiong.copy.utils.RedisUtils; +import xiong.copy.utils.RsaUtils; +import xiong.copy.utils.SecurityUtils; +import xiong.copy.utils.StringUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @author Zheng Jie + * @date 2018-11-23 + * 授权、根据token获取用户详细信息 + */ +@Slf4j +@RestController +@RequestMapping("/auth") +@RequiredArgsConstructor +@Api(tags = "系统:系统授权接口") +public class AuthorizationController { + private final SecurityProperties properties; + private final RedisUtils redisUtils; + private final OnlineUserService onlineUserService; + private final TokenProvider tokenProvider; + private final AuthenticationManagerBuilder authenticationManagerBuilder; + @Resource + private LoginProperties loginProperties; + + @ApiOperation("登录授权") + @AnonymousPostMapping(value = "/login") + public ResponseEntity login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception { + // 密码解密 + String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, authUser.getPassword()); + // 查询验证码 + String code = (String) redisUtils.get(authUser.getUuid()); + // 清除验证码 + redisUtils.del(authUser.getUuid()); + if (StringUtils.isBlank(code)) { + throw new BadRequestException("验证码不存在或已过期"); + } + if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) { + throw new BadRequestException("验证码错误"); + } + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(authUser.getUsername(), password); + Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + // 生成令牌与第三方系统获取令牌方式 + // UserDetails userDetails = userDetailsService.loadUserByUsername(userInfo.getUsername()); + // Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + // SecurityContextHolder.getContext().setAuthentication(authentication); + String token = tokenProvider.createToken(authentication); + final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal(); + // 保存在线信息 + onlineUserService.save(jwtUserDto, token, request); + // 返回 token 与 用户信息 + Map authInfo = new HashMap(2) {{ + put("token", properties.getTokenStartWith() + token); + put("user", jwtUserDto); + }}; + if (loginProperties.isSingleLogin()) { + //踢掉之前已经登录的token + onlineUserService.checkLoginOnUser(authUser.getUsername(), token); + } + return ResponseEntity.ok(authInfo); + } + + @ApiOperation("获取用户信息") + @GetMapping(value = "/info") + public ResponseEntity getUserInfo() { + return ResponseEntity.ok(SecurityUtils.getCurrentUser()); + } + + @ApiOperation("获取验证码") + @AnonymousGetMapping(value = "/code") + public ResponseEntity getCode() { + // 获取运算的结果 + Captcha captcha = loginProperties.getCaptcha(); + String uuid = properties.getCodeKey() + IdUtil.simpleUUID(); + //当验证码类型为 arithmetic时且长度 >= 2 时,captcha.text()的结果有几率为浮点型 + String captchaValue = captcha.text(); + if (captcha.getCharType() - 1 == LoginCodeEnum.arithmetic.ordinal() && captchaValue.contains(".")) { + captchaValue = captchaValue.split("\\.")[0]; + } + // 保存 + redisUtils.set(uuid, captchaValue, loginProperties.getLoginCode().getExpiration(), TimeUnit.MINUTES); + // 验证码信息 + Map imgResult = new HashMap(2) {{ + put("img", captcha.toBase64()); + put("uuid", uuid); + }}; + return ResponseEntity.ok(imgResult); + } + + @ApiOperation("退出登录") + @AnonymousDeleteMapping(value = "/logout") + public ResponseEntity logout(HttpServletRequest request) { + onlineUserService.logout(tokenProvider.getToken(request)); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/rest/OnlineController.java b/eladmin-system/src/main/java/xiong/copy/modules/security/rest/OnlineController.java new file mode 100644 index 0000000000000000000000000000000000000000..6cfba0f4681a74e448d67a0cc3d70e5c9bf3d103 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/rest/OnlineController.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.modules.security.service.OnlineUserService; +import xiong.copy.utils.EncryptUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** + * @author Zheng Jie + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/auth/online") +@Api(tags = "系统:在线用户管理") +public class OnlineController { + + private final OnlineUserService onlineUserService; + + @ApiOperation("查询在线用户") + @GetMapping + @PreAuthorize("@el.check()") + public ResponseEntity query(String filter, Pageable pageable){ + return new ResponseEntity<>(onlineUserService.getAll(filter, pageable),HttpStatus.OK); + } + + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check()") + public void download(HttpServletResponse response, String filter) throws IOException { + onlineUserService.download(onlineUserService.getAll(filter), response); + } + + @ApiOperation("踢出用户") + @DeleteMapping + @PreAuthorize("@el.check()") + public ResponseEntity delete(@RequestBody Set keys) throws Exception { + for (String key : keys) { + // 解密Key + key = EncryptUtils.desDecrypt(key); + onlineUserService.kickOut(key); + } + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/security/JwtAccessDeniedHandler.java b/eladmin-system/src/main/java/xiong/copy/modules/security/security/JwtAccessDeniedHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..752c8c8f4c74f276434f3690febc6a92b7bdc676 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/security/JwtAccessDeniedHandler.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.security; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Zheng Jie + */ +@Component +public class JwtAccessDeniedHandler implements AccessDeniedHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException { + //当用户在没有授权的情况下访问受保护的REST资源时,将调用此方法发送403 Forbidden响应 + response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage()); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/security/JwtAuthenticationEntryPoint.java b/eladmin-system/src/main/java/xiong/copy/modules/security/security/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000000000000000000000000000000000000..91572a3cd1ed861efc672fc1a465101038f093b4 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/security/JwtAuthenticationEntryPoint.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.security; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Zheng Jie + */ +@Component +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException authException) throws IOException { + // 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应 + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage()); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenConfigurer.java b/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenConfigurer.java new file mode 100644 index 0000000000000000000000000000000000000000..770921198a100ac19cd0af12e570d8cb976e669b --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenConfigurer.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.security; + +import lombok.RequiredArgsConstructor; +import xiong.copy.modules.security.config.bean.SecurityProperties; +import xiong.copy.modules.security.service.OnlineUserService; +import xiong.copy.modules.security.service.UserCacheClean; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +/** + * @author / + */ +@RequiredArgsConstructor +public class TokenConfigurer extends SecurityConfigurerAdapter { + + private final TokenProvider tokenProvider; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + + @Override + public void configure(HttpSecurity http) { + TokenFilter customFilter = new TokenFilter(tokenProvider, properties, onlineUserService, userCacheClean); + http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenFilter.java b/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..375cc9c4732c08424486dc1d5a1bb0f23f4447a4 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenFilter.java @@ -0,0 +1,109 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.security; + +import cn.hutool.core.util.StrUtil; +import io.jsonwebtoken.ExpiredJwtException; +import xiong.copy.modules.security.config.bean.SecurityProperties; +import xiong.copy.modules.security.service.OnlineUserService; +import xiong.copy.modules.security.service.UserCacheClean; +import xiong.copy.modules.security.service.dto.OnlineUserDto; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.Objects; + +/** + * @author / + */ +public class TokenFilter extends GenericFilterBean { + private static final Logger log = LoggerFactory.getLogger(TokenFilter.class); + + + private final TokenProvider tokenProvider; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; + + /** + * @param tokenProvider Token + * @param properties JWT + * @param onlineUserService 用户在线 + * @param userCacheClean 用户缓存清理工具 + */ + public TokenFilter(TokenProvider tokenProvider, SecurityProperties properties, OnlineUserService onlineUserService, UserCacheClean userCacheClean) { + this.properties = properties; + this.onlineUserService = onlineUserService; + this.tokenProvider = tokenProvider; + this.userCacheClean = userCacheClean; + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; + String token = resolveToken(httpServletRequest); + // 对于 Token 为空的不需要去查 Redis + if (StrUtil.isNotBlank(token)) { + OnlineUserDto onlineUserDto = null; + boolean cleanUserCache = false; + try { + onlineUserDto = onlineUserService.getOne(properties.getOnlineKey() + token); + } catch (ExpiredJwtException e) { + log.error(e.getMessage()); + cleanUserCache = true; + } finally { + if (cleanUserCache || Objects.isNull(onlineUserDto)) { + userCacheClean.cleanUserCache(String.valueOf(tokenProvider.getClaims(token).get(TokenProvider.AUTHORITIES_KEY))); + } + } + if (onlineUserDto != null && StringUtils.hasText(token)) { + Authentication authentication = tokenProvider.getAuthentication(token); + SecurityContextHolder.getContext().setAuthentication(authentication); + // Token 续期 + tokenProvider.checkRenewal(token); + } + } + filterChain.doFilter(servletRequest, servletResponse); + } + + /** + * 初步检测Token + * + * @param request / + * @return / + */ + private String resolveToken(HttpServletRequest request) { + String bearerToken = request.getHeader(properties.getHeader()); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(properties.getTokenStartWith())) { + // 去掉令牌前缀 + return bearerToken.replace(properties.getTokenStartWith(), ""); + } else { + log.debug("非法Token:{}", bearerToken); + } + return null; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenProvider.java b/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..e17ccd7123ac784c7d255e661384a83314a82ef6 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/security/TokenProvider.java @@ -0,0 +1,125 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.security; + +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import io.jsonwebtoken.*; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import lombok.extern.slf4j.Slf4j; +import xiong.copy.modules.security.config.bean.SecurityProperties; +import xiong.copy.utils.RedisUtils; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.security.Key; +import java.util.ArrayList; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * @author / + */ +@Slf4j +@Component +public class TokenProvider implements InitializingBean { + + private final SecurityProperties properties; + private final RedisUtils redisUtils; + public static final String AUTHORITIES_KEY = "user"; + private JwtParser jwtParser; + private JwtBuilder jwtBuilder; + + public TokenProvider(SecurityProperties properties, RedisUtils redisUtils) { + this.properties = properties; + this.redisUtils = redisUtils; + } + + @Override + public void afterPropertiesSet() { + byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret()); + Key key = Keys.hmacShaKeyFor(keyBytes); + jwtParser = Jwts.parserBuilder() + .setSigningKey(key) + .build(); + jwtBuilder = Jwts.builder() + .signWith(key, SignatureAlgorithm.HS512); + } + + /** + * 创建Token 设置永不过期, + * Token 的时间有效性转到Redis 维护 + * + * @param authentication / + * @return / + */ + public String createToken(Authentication authentication) { + return jwtBuilder + // 加入ID确保生成的 Token 都不一致 + .setId(IdUtil.simpleUUID()) + .claim(AUTHORITIES_KEY, authentication.getName()) + .setSubject(authentication.getName()) + .compact(); + } + + /** + * 依据Token 获取鉴权信息 + * + * @param token / + * @return / + */ + Authentication getAuthentication(String token) { + Claims claims = getClaims(token); + User principal = new User(claims.getSubject(), "******", new ArrayList<>()); + return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>()); + } + + public Claims getClaims(String token) { + return jwtParser + .parseClaimsJws(token) + .getBody(); + } + + /** + * @param token 需要检查的token + */ + public void checkRenewal(String token) { + // 判断是否续期token,计算token的过期时间 + long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000; + Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time); + // 判断当前时间与过期时间的时间差 + long differ = expireDate.getTime() - System.currentTimeMillis(); + // 如果在续期检查的范围内,则续期 + if (differ <= properties.getDetect()) { + long renew = time + properties.getRenew(); + redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS); + } + } + + public String getToken(HttpServletRequest request) { + final String requestHeader = request.getHeader(properties.getHeader()); + if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) { + return requestHeader.substring(7); + } + return null; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/service/OnlineUserService.java b/eladmin-system/src/main/java/xiong/copy/modules/security/service/OnlineUserService.java new file mode 100644 index 0000000000000000000000000000000000000000..e9d2593d29ce3aca4d40e7fb1a6e0ef14b43a062 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/service/OnlineUserService.java @@ -0,0 +1,192 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.service; + +import lombok.extern.slf4j.Slf4j; +import xiong.copy.modules.security.config.bean.SecurityProperties; +import xiong.copy.modules.security.service.dto.JwtUserDto; +import xiong.copy.modules.security.service.dto.OnlineUserDto; +import xiong.copy.utils.*; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** + * @author Zheng Jie + * @date 2019年10月26日21:56:27 + */ +@Service +@Slf4j +public class OnlineUserService { + + private final SecurityProperties properties; + private final RedisUtils redisUtils; + + public OnlineUserService(SecurityProperties properties, RedisUtils redisUtils) { + this.properties = properties; + this.redisUtils = redisUtils; + } + + /** + * 保存在线用户信息 + * @param jwtUserDto / + * @param token / + * @param request / + */ + public void save(JwtUserDto jwtUserDto, String token, HttpServletRequest request){ + String dept = jwtUserDto.getUser().getDept().getName(); + String ip = StringUtils.getIp(request); + String browser = StringUtils.getBrowser(request); + String address = StringUtils.getCityInfo(ip); + OnlineUserDto onlineUserDto = null; + try { + onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), jwtUserDto.getUser().getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date()); + } catch (Exception e) { + log.error(e.getMessage(),e); + } + redisUtils.set(properties.getOnlineKey() + token, onlineUserDto, properties.getTokenValidityInSeconds()/1000); + } + + /** + * 查询全部数据 + * @param filter / + * @param pageable / + * @return / + */ + public Map getAll(String filter, Pageable pageable){ + List onlineUserDtos = getAll(filter); + return PageUtil.toPage( + PageUtil.toPage(pageable.getPageNumber(),pageable.getPageSize(), onlineUserDtos), + onlineUserDtos.size() + ); + } + + /** + * 查询全部数据,不分页 + * @param filter / + * @return / + */ + public List getAll(String filter){ + List keys = redisUtils.scan(properties.getOnlineKey() + "*"); + Collections.reverse(keys); + List onlineUserDtos = new ArrayList<>(); + for (String key : keys) { + OnlineUserDto onlineUserDto = (OnlineUserDto) redisUtils.get(key); + if(StringUtils.isNotBlank(filter)){ + if(onlineUserDto.toString().contains(filter)){ + onlineUserDtos.add(onlineUserDto); + } + } else { + onlineUserDtos.add(onlineUserDto); + } + } + onlineUserDtos.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime())); + return onlineUserDtos; + } + + /** + * 踢出用户 + * @param key / + */ + public void kickOut(String key){ + key = properties.getOnlineKey() + key; + redisUtils.del(key); + } + + /** + * 退出登录 + * @param token / + */ + public void logout(String token) { + String key = properties.getOnlineKey() + token; + redisUtils.del(key); + } + + /** + * 导出 + * @param all / + * @param response / + * @throws IOException / + */ + public void download(List all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (OnlineUserDto user : all) { + Map map = new LinkedHashMap<>(); + map.put("用户名", user.getUserName()); + map.put("部门", user.getDept()); + map.put("登录IP", user.getIp()); + map.put("登录地点", user.getAddress()); + map.put("浏览器", user.getBrowser()); + map.put("登录日期", user.getLoginTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + /** + * 查询用户 + * @param key / + * @return / + */ + public OnlineUserDto getOne(String key) { + return (OnlineUserDto)redisUtils.get(key); + } + + /** + * 检测用户是否在之前已经登录,已经登录踢下线 + * @param userName 用户名 + */ + public void checkLoginOnUser(String userName, String igoreToken){ + List onlineUserDtos = getAll(userName); + if(onlineUserDtos ==null || onlineUserDtos.isEmpty()){ + return; + } + for(OnlineUserDto onlineUserDto : onlineUserDtos){ + if(onlineUserDto.getUserName().equals(userName)){ + try { + String token =EncryptUtils.desDecrypt(onlineUserDto.getKey()); + if(StringUtils.isNotBlank(igoreToken)&&!igoreToken.equals(token)){ + this.kickOut(token); + }else if(StringUtils.isBlank(igoreToken)){ + this.kickOut(token); + } + } catch (Exception e) { + log.error("checkUser is error",e); + } + } + } + } + + /** + * 根据用户名强退用户 + * @param username / + */ + @Async + public void kickOutForUsername(String username) throws Exception { + List onlineUsers = getAll(username); + for (OnlineUserDto onlineUser : onlineUsers) { + if (onlineUser.getUserName().equals(username)) { + String token =EncryptUtils.desDecrypt(onlineUser.getKey()); + kickOut(token); + } + } + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/service/UserCacheClean.java b/eladmin-system/src/main/java/xiong/copy/modules/security/service/UserCacheClean.java new file mode 100644 index 0000000000000000000000000000000000000000..7ed172c8d97a0f3c8e27aed8b47763d69434694e --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/service/UserCacheClean.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed 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. + */ + +package xiong.copy.modules.security.service; + +import xiong.copy.utils.StringUtils; +import org.springframework.stereotype.Component; + +/** + * @author: liaojinlong + * @date: 2020/6/11 18:01 + * @apiNote: 用于清理 用户登录信息缓存,为防止Spring循环依赖与安全考虑 ,单独构成工具类 + */ +@Component +public class UserCacheClean { + + /** + * 清理特定用户缓存信息
+ * 用户信息变更时 + * + * @param userName / + */ + public void cleanUserCache(String userName) { + if (StringUtils.isNotEmpty(userName)) { + UserDetailsServiceImpl.userDtoCache.remove(userName); + } + } + + /** + * 清理所有用户的缓存信息
+ * ,如发生角色授权信息变化,可以简便的全部失效缓存 + */ + public void cleanAll() { + UserDetailsServiceImpl.userDtoCache.clear(); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/service/UserDetailsServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/security/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..5f4a02e15320e7f04ab89a5de19d2aaeb2951d7b --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/service/UserDetailsServiceImpl.java @@ -0,0 +1,94 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.service; + +import lombok.RequiredArgsConstructor; +import xiong.copy.exception.BadRequestException; +import xiong.copy.exception.EntityNotFoundException; +import xiong.copy.modules.security.config.bean.LoginProperties; +import xiong.copy.modules.security.service.dto.JwtUserDto; +import xiong.copy.modules.system.service.DataService; +import xiong.copy.modules.system.service.RoleService; +import xiong.copy.modules.system.service.UserService; +import xiong.copy.modules.system.service.dto.UserDto; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author Zheng Jie + * @date 2018-11-22 + */ +@RequiredArgsConstructor +@Service("userDetailsService") +public class UserDetailsServiceImpl implements UserDetailsService { + private final UserService userService; + private final RoleService roleService; + private final DataService dataService; + private final LoginProperties loginProperties; + + public void setEnableCache(boolean enableCache) { + this.loginProperties.setCacheEnable(enableCache); + } + + /** + * 用户信息缓存 + * + * @see {@link UserCacheClean} + */ + static Map userDtoCache = new ConcurrentHashMap<>(); + + @Override + public JwtUserDto loadUserByUsername(String username) { + boolean searchDb = true; + JwtUserDto jwtUserDto = null; + if (loginProperties.isCacheEnable() && userDtoCache.containsKey(username)) { + jwtUserDto = userDtoCache.get(username); + // 检查dataScope是否修改 + List dataScopes = jwtUserDto.getDataScopes(); + dataScopes.clear(); + dataScopes.addAll(dataService.getDeptIds(jwtUserDto.getUser())); + searchDb = false; + } + if (searchDb) { + UserDto user; + try { + user = userService.findByName(username); + } catch (EntityNotFoundException e) { + // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException + throw new UsernameNotFoundException("", e); + } + if (user == null) { + throw new UsernameNotFoundException(""); + } else { + if (!user.getEnabled()) { + throw new BadRequestException("账号未激活!"); + } + jwtUserDto = new JwtUserDto( + user, + dataService.getDeptIds(user), + roleService.mapToGrantedAuthorities(user) + ); + userDtoCache.put(username, jwtUserDto); + } + } + return jwtUserDto; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/AuthUserDto.java b/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/AuthUserDto.java new file mode 100644 index 0000000000000000000000000000000000000000..ed82e909dcedffb0b78c9a1124e6abd6bbd561f3 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/AuthUserDto.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.service.dto; + +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotBlank; + +/** + * @author Zheng Jie + * @date 2018-11-30 + */ +@Getter +@Setter +public class AuthUserDto { + + @NotBlank + private String username; + + @NotBlank + private String password; + + private String code; + + private String uuid = ""; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/JwtUserDto.java b/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/JwtUserDto.java new file mode 100644 index 0000000000000000000000000000000000000000..e64a84033297ead845389c038c1b26d85e938c6c --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/JwtUserDto.java @@ -0,0 +1,83 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.service.dto; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.AllArgsConstructor; +import lombok.Getter; +import xiong.copy.modules.system.service.dto.UserDto; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Getter +@AllArgsConstructor +public class JwtUserDto implements UserDetails { + + private final UserDto user; + + private final List dataScopes; + + @JSONField(serialize = false) + private final List authorities; + + public Set getRoles() { + return authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet()); + } + + @Override + @JSONField(serialize = false) + public String getPassword() { + return user.getPassword(); + } + + @Override + @JSONField(serialize = false) + public String getUsername() { + return user.getUsername(); + } + + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() { + return true; + } + + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() { + return true; + } + + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + @JSONField(serialize = false) + public boolean isEnabled() { + return user.getEnabled(); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/OnlineUserDto.java b/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/OnlineUserDto.java new file mode 100644 index 0000000000000000000000000000000000000000..c2b1d081c5062221fa4590c3e5a094eca3f661ac --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/security/service/dto/OnlineUserDto.java @@ -0,0 +1,74 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.security.service.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 在线用户 + * @author Zheng Jie + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class OnlineUserDto { + + /** + * 用户名 + */ + private String userName; + + /** + * 昵称 + */ + private String nickName; + + /** + * 岗位 + */ + private String dept; + + /** + * 浏览器 + */ + private String browser; + + /** + * IP + */ + private String ip; + + /** + * 地址 + */ + private String address; + + /** + * token + */ + private String key; + + /** + * 登录时间 + */ + private Date loginTime; + + +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Dept.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Dept.java new file mode 100644 index 0000000000000000000000000000000000000000..a49aa539a0bfb6be1630ad9d67690b8532645b00 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Dept.java @@ -0,0 +1,87 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseEntity; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dept") +public class Dept extends BaseEntity implements Serializable { + + @Id + @Column(name = "dept_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "depts") + @ApiModelProperty(value = "角色") + private Set roles; + + @ApiModelProperty(value = "排序") + private Integer deptSort; + + @NotBlank + @ApiModelProperty(value = "部门名称") + private String name; + + @NotNull + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @ApiModelProperty(value = "上级部门") + private Long pid; + + @ApiModelProperty(value = "子节点数目", hidden = true) + private Integer subCount = 0; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Dept dept = (Dept) o; + return Objects.equals(id, dept.id) && + Objects.equals(name, dept.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Dict.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Dict.java new file mode 100644 index 0000000000000000000000000000000000000000..0491eca8d1025bf6db8f92e7c1b2ce078316feee --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Dict.java @@ -0,0 +1,55 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseEntity; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dict") +public class Dict extends BaseEntity implements Serializable { + + @Id + @Column(name = "dict_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToMany(mappedBy = "dict",cascade={CascadeType.PERSIST,CascadeType.REMOVE}) + private List dictDetails; + + @NotBlank + @ApiModelProperty(value = "名称") + private String name; + + @ApiModelProperty(value = "描述") + private String description; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/DictDetail.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/DictDetail.java new file mode 100644 index 0000000000000000000000000000000000000000..dba43326bdba64d81daabf98b62fe4d6def88197 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/DictDetail.java @@ -0,0 +1,57 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseEntity; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_dict_detail") +public class DictDetail extends BaseEntity implements Serializable { + + @Id + @Column(name = "detail_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JoinColumn(name = "dict_id") + @ManyToOne(fetch=FetchType.LAZY) + @ApiModelProperty(value = "字典", hidden = true) + private Dict dict; + + @ApiModelProperty(value = "字典标签") + private String label; + + @ApiModelProperty(value = "字典值") + private String value; + + @ApiModelProperty(value = "排序") + private Integer dictSort = 999; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Job.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Job.java new file mode 100644 index 0000000000000000000000000000000000000000..470dfc318c318df20c751e5e4c77e33e5cbeb392 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Job.java @@ -0,0 +1,74 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseEntity; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Entity +@Getter +@Setter +@Table(name="sys_job") +public class Job extends BaseEntity implements Serializable { + + @Id + @Column(name = "job_id") + @NotNull(groups = Update.class) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank + @ApiModelProperty(value = "岗位名称") + private String name; + + @NotNull + @ApiModelProperty(value = "岗位排序") + private Long jobSort; + + @NotNull + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Job job = (Job) o; + return Objects.equals(id, job.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Menu.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Menu.java new file mode 100644 index 0000000000000000000000000000000000000000..2f035f634e2efd96d43adfcd437ad48549888f08 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Menu.java @@ -0,0 +1,110 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseEntity; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +@Entity +@Getter +@Setter +@Table(name = "sys_menu") +public class Menu extends BaseEntity implements Serializable { + + @Id + @Column(name = "menu_id") + @NotNull(groups = {Update.class}) + @ApiModelProperty(value = "ID", hidden = true) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "menus") + @ApiModelProperty(value = "菜单角色") + private Set roles; + + @ApiModelProperty(value = "菜单标题") + private String title; + + @Column(name = "name") + @ApiModelProperty(value = "菜单组件名称") + private String componentName; + + @ApiModelProperty(value = "排序") + private Integer menuSort = 999; + + @ApiModelProperty(value = "组件路径") + private String component; + + @ApiModelProperty(value = "路由地址") + private String path; + + @ApiModelProperty(value = "菜单类型,目录、菜单、按钮") + private Integer type; + + @ApiModelProperty(value = "权限标识") + private String permission; + + @ApiModelProperty(value = "菜单图标") + private String icon; + + @Column(columnDefinition = "bit(1) default 0") + @ApiModelProperty(value = "缓存") + private Boolean cache; + + @Column(columnDefinition = "bit(1) default 0") + @ApiModelProperty(value = "是否隐藏") + private Boolean hidden; + + @ApiModelProperty(value = "上级菜单") + private Long pid; + + @ApiModelProperty(value = "子节点数目", hidden = true) + private Integer subCount = 0; + + @ApiModelProperty(value = "外链菜单") + private Boolean iFrame; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Menu menu = (Menu) o; + return Objects.equals(id, menu.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Role.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Role.java new file mode 100644 index 0000000000000000000000000000000000000000..9e402cc3a1fdd54804a884c76863309f17c394d9 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/Role.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain; + +import com.alibaba.fastjson.annotation.JSONField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseEntity; +import xiong.copy.utils.enums.DataScopeEnum; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** + * 角色 + * @author Zheng Jie + * @date 2018-11-22 + */ +@Getter +@Setter +@Entity +@Table(name = "sys_role") +public class Role extends BaseEntity implements Serializable { + + @Id + @Column(name = "role_id") + @NotNull(groups = {Update.class}) + @GeneratedValue(strategy = GenerationType.IDENTITY) + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @JSONField(serialize = false) + @ManyToMany(mappedBy = "roles") + @ApiModelProperty(value = "用户", hidden = true) + private Set users; + + @ManyToMany + @JoinTable(name = "sys_roles_menus", + joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}, + inverseJoinColumns = {@JoinColumn(name = "menu_id",referencedColumnName = "menu_id")}) + @ApiModelProperty(value = "菜单", hidden = true) + private Set menus; + + @ManyToMany + @JoinTable(name = "sys_roles_depts", + joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}, + inverseJoinColumns = {@JoinColumn(name = "dept_id",referencedColumnName = "dept_id")}) + @ApiModelProperty(value = "部门", hidden = true) + private Set depts; + + @NotBlank + @ApiModelProperty(value = "名称", hidden = true) + private String name; + + @ApiModelProperty(value = "数据权限,全部 、 本级 、 自定义") + private String dataScope = DataScopeEnum.THIS_LEVEL.getValue(); + + @Column(name = "level") + @ApiModelProperty(value = "级别,数值越小,级别越大") + private Integer level = 3; + + @ApiModelProperty(value = "描述") + private String description; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Role role = (Role) o; + return Objects.equals(id, role.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/User.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/User.java new file mode 100644 index 0000000000000000000000000000000000000000..6e56f2794398a3169a425780b869ce576cd86c8f --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/User.java @@ -0,0 +1,126 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseEntity; + +import javax.persistence.*; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; +import java.util.Objects; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-22 + */ +@Entity +@Getter +@Setter +@Table(name="sys_user") +public class User extends BaseEntity implements Serializable { + + @Id + @Column(name = "user_id") + @NotNull(groups = Update.class) + @GeneratedValue(strategy = GenerationType.IDENTITY) + @ApiModelProperty(value = "ID", hidden = true) + private Long id; + + @ManyToMany + @ApiModelProperty(value = "用户角色") + @JoinTable(name = "sys_users_roles", + joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")}, + inverseJoinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")}) + private Set roles; + + @ManyToMany + @ApiModelProperty(value = "用户岗位") + @JoinTable(name = "sys_users_jobs", + joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")}, + inverseJoinColumns = {@JoinColumn(name = "job_id",referencedColumnName = "job_id")}) + private Set jobs; + + @OneToOne + @JoinColumn(name = "dept_id") + @ApiModelProperty(value = "用户部门") + private Dept dept; + + @NotBlank + @Column(unique = true) + @ApiModelProperty(value = "用户名称") + private String username; + + @NotBlank + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @Email + @NotBlank + @ApiModelProperty(value = "邮箱") + private String email; + + @NotBlank + @ApiModelProperty(value = "电话号码") + private String phone; + + @ApiModelProperty(value = "用户性别") + private String gender; + + @ApiModelProperty(value = "头像真实名称",hidden = true) + private String avatarName; + + @ApiModelProperty(value = "头像存储的路径", hidden = true) + private String avatarPath; + + @ApiModelProperty(value = "密码") + private String password; + + @NotNull + @ApiModelProperty(value = "是否启用") + private Boolean enabled; + + @ApiModelProperty(value = "是否为admin账号", hidden = true) + private Boolean isAdmin = false; + + @Column(name = "pwd_reset_time") + @ApiModelProperty(value = "最后修改密码的时间", hidden = true) + private Date pwdResetTime; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(id, user.id) && + Objects.equals(username, user.username); + } + + @Override + public int hashCode() { + return Objects.hash(id, username); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/MenuMetaVo.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/MenuMetaVo.java new file mode 100644 index 0000000000000000000000000000000000000000..c08685f5d1f8e523513e574a7a68b36e4dd54d10 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/MenuMetaVo.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author Zheng Jie + * @date 2018-12-20 + */ +@Data +@AllArgsConstructor +public class MenuMetaVo implements Serializable { + + private String title; + + private String icon; + + private Boolean noCache; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/MenuVo.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/MenuVo.java new file mode 100644 index 0000000000000000000000000000000000000000..ca11e1b3d01fcb3ca0d433ae20c8914729882a0d --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/MenuVo.java @@ -0,0 +1,48 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 构建前端路由时用到 + * @author Zheng Jie + * @date 2018-12-20 + */ +@Data +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class MenuVo implements Serializable { + + private String name; + + private String path; + + private Boolean hidden; + + private String redirect; + + private String component; + + private Boolean alwaysShow; + + private MenuMetaVo meta; + + private List children; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/UserPassVo.java b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/UserPassVo.java new file mode 100644 index 0000000000000000000000000000000000000000..b4c7d53d5b9777e3c751a81f1059e872f644e29c --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/domain/vo/UserPassVo.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.domain.vo; + +import lombok.Data; + +/** + * 修改密码的 Vo 类 + * @author Zheng Jie + * @date 2019年7月11日13:59:49 + */ +@Data +public class UserPassVo { + + private String oldPass; + + private String newPass; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DeptRepository.java b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DeptRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..782f5ed48473dd38e35d29952cc71c0c08f9f40b --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DeptRepository.java @@ -0,0 +1,70 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.repository; + +import xiong.copy.modules.system.domain.Dept; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +public interface DeptRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据 PID 查询 + * @param id pid + * @return / + */ + List findByPid(Long id); + + /** + * 获取顶级部门 + * @return / + */ + List findByPidIsNull(); + + /** + * 根据角色ID 查询 + * @param roleId 角色ID + * @return / + */ + @Query(value = "select d.* from sys_dept d, sys_roles_depts r where " + + "d.dept_id = r.dept_id and r.role_id = ?1", nativeQuery = true) + Set findByRoleId(Long roleId); + + /** + * 判断是否存在子节点 + * @param pid / + * @return / + */ + int countByPid(Long pid); + + /** + * 根据ID更新sub_count + * @param count / + * @param id / + */ + @Modifying + @Query(value = " update sys_dept set sub_count = ?1 where dept_id = ?2 ",nativeQuery = true) + void updateSubCntById(Integer count, Long id); +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DictDetailRepository.java b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DictDetailRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..ae9d30ac260d101a3df31d109f3475c55bef1546 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DictDetailRepository.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.repository; + +import xiong.copy.modules.system.domain.DictDetail; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +public interface DictDetailRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据字典名称查询 + * @param name / + * @return / + */ + List findByDictName(String name); +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DictRepository.java b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DictRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..845e73e0c6ce50109b30c352ce76cb87a91e31ff --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/DictRepository.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.repository; + +import xiong.copy.modules.system.domain.Dict; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.List; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +public interface DictRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 删除 + * @param ids / + */ + void deleteByIdIn(Set ids); + + /** + * 查询 + * @param ids / + * @return / + */ + List findByIdIn(Set ids); +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/repository/JobRepository.java b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/JobRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..686bda136464611f4c40d70986d928d713c5b775 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/JobRepository.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.repository; + +import xiong.copy.modules.system.domain.Job; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +public interface JobRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据名称查询 + * @param name 名称 + * @return / + */ + Job findByName(String name); + + /** + * 根据Id删除 + * @param ids / + */ + void deleteAllByIdIn(Set ids); +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/repository/MenuRepository.java b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/MenuRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..e1212979aa22a99e6d51859cf58f9f77808bf68f --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/MenuRepository.java @@ -0,0 +1,86 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.repository; + +import xiong.copy.modules.system.domain.Menu; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +public interface MenuRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据菜单标题查询 + * @param title 菜单标题 + * @return / + */ + Menu findByTitle(String title); + + /** + * 根据组件名称查询 + * @param name 组件名称 + * @return / + */ + Menu findByComponentName(String name); + + /** + * 根据菜单的 PID 查询 + * @param pid / + * @return / + */ + List findByPid(long pid); + + /** + * 查询顶级菜单 + * @return / + */ + List findByPidIsNull(); + + /** + * 根据角色ID与菜单类型查询菜单 + * @param roleIds roleIDs + * @param type 类型 + * @return / + */ + @Query(value = "SELECT m.* FROM sys_menu m, sys_roles_menus r WHERE " + + "m.menu_id = r.menu_id AND r.role_id IN ?1 AND type != ?2 order by m.menu_sort asc",nativeQuery = true) + LinkedHashSet findByRoleIdsAndTypeNot(Set roleIds, int type); + + /** + * 获取节点数量 + * @param id / + * @return / + */ + int countByPid(Long id); + + /** + * 更新节点数目 + * @param count / + * @param menuId / + */ + @Modifying + @Query(value = " update sys_menu set sub_count = ?1 where menu_id = ?2 ",nativeQuery = true) + void updateSubCntById(int count, Long menuId); +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/repository/RoleRepository.java b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/RoleRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..0b98edced9a9e2f82e55311fabb3c8d1040c4820 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/RoleRepository.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.repository; + +import xiong.copy.modules.system.domain.Role; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ +public interface RoleRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据名称查询 + * @param name / + * @return / + */ + Role findByName(String name); + + /** + * 删除多个角色 + * @param ids / + */ + void deleteAllByIdIn(Set ids); + + /** + * 根据用户ID查询 + * @param id 用户ID + * @return / + */ + @Query(value = "SELECT r.* FROM sys_role r, sys_users_roles u WHERE " + + "r.role_id = u.role_id AND u.user_id = ?1",nativeQuery = true) + Set findByUserId(Long id); + + /** + * 解绑角色菜单 + * @param id 菜单ID + */ + @Modifying + @Query(value = "delete from sys_roles_menus where menu_id = ?1",nativeQuery = true) + void untiedMenu(Long id); + + /** + * 根据部门查询 + * @param deptIds / + * @return / + */ + @Query(value = "select count(1) from sys_role r, sys_roles_depts d where " + + "r.role_id = d.role_id and d.dept_id in ?1",nativeQuery = true) + int countByDepts(Set deptIds); + + /** + * 根据菜单Id查询 + * @param menuIds / + * @return / + */ + @Query(value = "SELECT r.* FROM sys_role r, sys_roles_menus m WHERE " + + "r.role_id = m.role_id AND m.menu_id in ?1",nativeQuery = true) + List findInMenuId(List menuIds); +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/repository/UserRepository.java b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/UserRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..3818432dfb3d4bb5b98805607e76126acd511358 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/repository/UserRepository.java @@ -0,0 +1,131 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.repository; + +import xiong.copy.modules.system.domain.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import java.util.Date; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-22 + */ +public interface UserRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 根据用户名查询 + * @param username 用户名 + * @return / + */ + User findByUsername(String username); + + /** + * 根据邮箱查询 + * @param email 邮箱 + * @return / + */ + User findByEmail(String email); + + /** + * 根据手机号查询 + * @param phone 手机号 + * @return / + */ + User findByPhone(String phone); + + /** + * 修改密码 + * @param username 用户名 + * @param pass 密码 + * @param lastPasswordResetTime / + */ + @Modifying + @Query(value = "update sys_user set password = ?2 , pwd_reset_time = ?3 where username = ?1",nativeQuery = true) + void updatePass(String username, String pass, Date lastPasswordResetTime); + + /** + * 修改邮箱 + * @param username 用户名 + * @param email 邮箱 + */ + @Modifying + @Query(value = "update sys_user set email = ?2 where username = ?1",nativeQuery = true) + void updateEmail(String username, String email); + + /** + * 根据角色查询用户 + * @param roleId / + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles r WHERE" + + " u.user_id = r.user_id AND r.role_id = ?1", nativeQuery = true) + List findByRoleId(Long roleId); + + /** + * 根据角色中的部门查询 + * @param deptId / + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles r, sys_roles_depts d WHERE " + + "u.user_id = r.user_id AND r.role_id = d.role_id AND d.dept_id = ?1 group by u.user_id", nativeQuery = true) + List findByRoleDeptId(Long deptId); + + /** + * 根据菜单查询 + * @param id 菜单ID + * @return / + */ + @Query(value = "SELECT u.* FROM sys_user u, sys_users_roles ur, sys_roles_menus rm WHERE\n" + + "u.user_id = ur.user_id AND ur.role_id = rm.role_id AND rm.menu_id = ?1 group by u.user_id", nativeQuery = true) + List findByMenuId(Long id); + + /** + * 根据Id删除 + * @param ids / + */ + void deleteAllByIdIn(Set ids); + + /** + * 根据岗位查询 + * @param ids / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u, sys_users_jobs j WHERE u.user_id = j.user_id AND j.job_id IN ?1", nativeQuery = true) + int countByJobs(Set ids); + + /** + * 根据部门查询 + * @param deptIds / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u WHERE u.dept_id IN ?1", nativeQuery = true) + int countByDepts(Set deptIds); + + /** + * 根据角色查询 + * @param ids / + * @return / + */ + @Query(value = "SELECT count(1) FROM sys_user u, sys_users_roles r WHERE " + + "u.user_id = r.user_id AND r.role_id in ?1", nativeQuery = true) + int countByRoles(Set ids); +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DeptController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DeptController.java new file mode 100644 index 0000000000000000000000000000000000000000..f61cf733ab4f5f90a6974601800600bcf25f5230 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DeptController.java @@ -0,0 +1,118 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import cn.hutool.core.collection.CollectionUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.annotation.Log; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.system.domain.Dept; +import xiong.copy.modules.system.service.DeptService; +import xiong.copy.modules.system.service.dto.DeptDto; +import xiong.copy.modules.system.service.dto.DeptQueryCriteria; +import xiong.copy.utils.PageUtil; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.*; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:部门管理") +@RequestMapping("/api/dept") +public class DeptController { + + private final DeptService deptService; + private static final String ENTITY_NAME = "dept"; + + @ApiOperation("导出部门数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('dept:list')") + public void download(HttpServletResponse response, DeptQueryCriteria criteria) throws Exception { + deptService.download(deptService.queryAll(criteria, false), response); + } + + @ApiOperation("查询部门") + @GetMapping + @PreAuthorize("@el.check('user:list','dept:list')") + public ResponseEntity query(DeptQueryCriteria criteria) throws Exception { + List deptDtos = deptService.queryAll(criteria, true); + return new ResponseEntity<>(PageUtil.toPage(deptDtos, deptDtos.size()),HttpStatus.OK); + } + + @ApiOperation("查询部门:根据ID获取同级与上级数据") + @PostMapping("/superior") + @PreAuthorize("@el.check('user:list','dept:list')") + public ResponseEntity getSuperior(@RequestBody List ids) { + Set deptDtos = new LinkedHashSet<>(); + for (Long id : ids) { + DeptDto deptDto = deptService.findById(id); + List depts = deptService.getSuperior(deptDto, new ArrayList<>()); + deptDtos.addAll(depts); + } + return new ResponseEntity<>(deptService.buildTree(new ArrayList<>(deptDtos)),HttpStatus.OK); + } + + @Log("新增部门") + @ApiOperation("新增部门") + @PostMapping + @PreAuthorize("@el.check('dept:add')") + public ResponseEntity create(@Validated @RequestBody Dept resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + deptService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改部门") + @ApiOperation("修改部门") + @PutMapping + @PreAuthorize("@el.check('dept:edit')") + public ResponseEntity update(@Validated(Dept.Update.class) @RequestBody Dept resources){ + deptService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除部门") + @ApiOperation("删除部门") + @DeleteMapping + @PreAuthorize("@el.check('dept:del')") + public ResponseEntity delete(@RequestBody Set ids){ + Set deptDtos = new HashSet<>(); + for (Long id : ids) { + List deptList = deptService.findByPid(id); + deptDtos.add(deptService.findById(id)); + if(CollectionUtil.isNotEmpty(deptList)){ + deptDtos = deptService.getDeleteDepts(deptList, deptDtos); + } + } + // 验证是否被角色或用户关联 + deptService.verification(deptDtos); + deptService.delete(deptDtos); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DictController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DictController.java new file mode 100644 index 0000000000000000000000000000000000000000..85b78d12c6d8914af60dfa5f77bb56f553c5b6d1 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DictController.java @@ -0,0 +1,100 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.annotation.Log; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.system.domain.Dict; +import xiong.copy.modules.system.service.DictService; +import xiong.copy.modules.system.service.dto.DictQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:字典管理") +@RequestMapping("/api/dict") +public class DictController { + + private final DictService dictService; + private static final String ENTITY_NAME = "dict"; + + @ApiOperation("导出字典数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('dict:list')") + public void download(HttpServletResponse response, DictQueryCriteria criteria) throws IOException { + dictService.download(dictService.queryAll(criteria), response); + } + + @ApiOperation("查询字典") + @GetMapping(value = "/all") + @PreAuthorize("@el.check('dict:list')") + public ResponseEntity queryAll(){ + return new ResponseEntity<>(dictService.queryAll(new DictQueryCriteria()),HttpStatus.OK); + } + + @ApiOperation("查询字典") + @GetMapping + @PreAuthorize("@el.check('dict:list')") + public ResponseEntity query(DictQueryCriteria resources, Pageable pageable){ + return new ResponseEntity<>(dictService.queryAll(resources,pageable),HttpStatus.OK); + } + + @Log("新增字典") + @ApiOperation("新增字典") + @PostMapping + @PreAuthorize("@el.check('dict:add')") + public ResponseEntity create(@Validated @RequestBody Dict resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + dictService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改字典") + @ApiOperation("修改字典") + @PutMapping + @PreAuthorize("@el.check('dict:edit')") + public ResponseEntity update(@Validated(Dict.Update.class) @RequestBody Dict resources){ + dictService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除字典") + @ApiOperation("删除字典") + @DeleteMapping + @PreAuthorize("@el.check('dict:del')") + public ResponseEntity delete(@RequestBody Set ids){ + dictService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DictDetailController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DictDetailController.java new file mode 100644 index 0000000000000000000000000000000000000000..f60c592fb6f79e207bc2a2b568c83f3cc4cc7da9 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/DictDetailController.java @@ -0,0 +1,100 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.annotation.Log; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.system.domain.DictDetail; +import xiong.copy.modules.system.service.DictDetailService; +import xiong.copy.modules.system.service.dto.DictDetailDto; +import xiong.copy.modules.system.service.dto.DictDetailQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:字典详情管理") +@RequestMapping("/api/dictDetail") +public class DictDetailController { + + private final DictDetailService dictDetailService; + private static final String ENTITY_NAME = "dictDetail"; + + @ApiOperation("查询字典详情") + @GetMapping + public ResponseEntity query(DictDetailQueryCriteria criteria, + @PageableDefault(sort = {"dictSort"}, direction = Sort.Direction.ASC) Pageable pageable){ + return new ResponseEntity<>(dictDetailService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @ApiOperation("查询多个字典详情") + @GetMapping(value = "/map") + public ResponseEntity getDictDetailMaps(@RequestParam String dictName){ + String[] names = dictName.split("[,,]"); + Map> dictMap = new HashMap<>(16); + for (String name : names) { + dictMap.put(name, dictDetailService.getDictByName(name)); + } + return new ResponseEntity<>(dictMap, HttpStatus.OK); + } + + @Log("新增字典详情") + @ApiOperation("新增字典详情") + @PostMapping + @PreAuthorize("@el.check('dict:add')") + public ResponseEntity create(@Validated @RequestBody DictDetail resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + dictDetailService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改字典详情") + @ApiOperation("修改字典详情") + @PutMapping + @PreAuthorize("@el.check('dict:edit')") + public ResponseEntity update(@Validated(DictDetail.Update.class) @RequestBody DictDetail resources){ + dictDetailService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除字典详情") + @ApiOperation("删除字典详情") + @DeleteMapping(value = "/{id}") + @PreAuthorize("@el.check('dict:del')") + public ResponseEntity delete(@PathVariable Long id){ + dictDetailService.delete(id); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/JobController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/JobController.java new file mode 100644 index 0000000000000000000000000000000000000000..409c02fdc2b0bf06daffab1b87aea6e8e8684209 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/JobController.java @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.annotation.Log; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.system.domain.Job; +import xiong.copy.modules.system.service.JobService; +import xiong.copy.modules.system.service.dto.JobQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:岗位管理") +@RequestMapping("/api/job") +public class JobController { + + private final JobService jobService; + private static final String ENTITY_NAME = "job"; + + @ApiOperation("导出岗位数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('job:list')") + public void download(HttpServletResponse response, JobQueryCriteria criteria) throws IOException { + jobService.download(jobService.queryAll(criteria), response); + } + + @ApiOperation("查询岗位") + @GetMapping + @PreAuthorize("@el.check('job:list','user:list')") + public ResponseEntity query(JobQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(jobService.queryAll(criteria, pageable),HttpStatus.OK); + } + + @Log("新增岗位") + @ApiOperation("新增岗位") + @PostMapping + @PreAuthorize("@el.check('job:add')") + public ResponseEntity create(@Validated @RequestBody Job resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + jobService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改岗位") + @ApiOperation("修改岗位") + @PutMapping + @PreAuthorize("@el.check('job:edit')") + public ResponseEntity update(@Validated(Job.Update.class) @RequestBody Job resources){ + jobService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除岗位") + @ApiOperation("删除岗位") + @DeleteMapping + @PreAuthorize("@el.check('job:del')") + public ResponseEntity delete(@RequestBody Set ids){ + // 验证是否被用户关联 + jobService.verification(ids); + jobService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/LimitController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/LimitController.java new file mode 100644 index 0000000000000000000000000000000000000000..e4e51255313d6f478c29a27ab54ea2f4925dec62 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/LimitController.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import xiong.copy.annotation.Limit; +import xiong.copy.annotation.rest.AnonymousGetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author / + * 接口限流测试类 + */ +@RestController +@RequestMapping("/api/limit") +@Api(tags = "系统:限流测试管理") +public class LimitController { + + private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger(); + + /** + * 测试限流注解,下面配置说明该接口 60秒内最多只能访问 10次,保存到redis的键名为 limit_test, + */ + @AnonymousGetMapping + @ApiOperation("测试") + @Limit(key = "test", period = 60, count = 10, name = "testLimit", prefix = "limit") + public int test() { + return ATOMIC_INTEGER.incrementAndGet(); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/MenuController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/MenuController.java new file mode 100644 index 0000000000000000000000000000000000000000..39f070742225322c7b701781ac6c94b0e24cb86d --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/MenuController.java @@ -0,0 +1,148 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import cn.hutool.core.collection.CollectionUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.annotation.Log; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.system.domain.Menu; +import xiong.copy.modules.system.service.MenuService; +import xiong.copy.modules.system.service.dto.MenuDto; +import xiong.copy.modules.system.service.dto.MenuQueryCriteria; +import xiong.copy.modules.system.service.mapstruct.MenuMapper; +import xiong.copy.utils.PageUtil; +import xiong.copy.utils.SecurityUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ + +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:菜单管理") +@RequestMapping("/api/menus") +public class MenuController { + + private final MenuService menuService; + private final MenuMapper menuMapper; + private static final String ENTITY_NAME = "menu"; + + @ApiOperation("导出菜单数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('menu:list')") + public void download(HttpServletResponse response, MenuQueryCriteria criteria) throws Exception { + menuService.download(menuService.queryAll(criteria, false), response); + } + + @GetMapping(value = "/build") + @ApiOperation("获取前端所需菜单") + public ResponseEntity buildMenus(){ + List menuDtoList = menuService.findByUser(SecurityUtils.getCurrentUserId()); + List menuDtos = menuService.buildTree(menuDtoList); + return new ResponseEntity<>(menuService.buildMenus(menuDtos),HttpStatus.OK); + } + + @ApiOperation("返回全部的菜单") + @GetMapping(value = "/lazy") + @PreAuthorize("@el.check('menu:list','roles:list')") + public ResponseEntity query(@RequestParam Long pid){ + return new ResponseEntity<>(menuService.getMenus(pid),HttpStatus.OK); + } + + @ApiOperation("根据菜单ID返回所有子节点ID,包含自身ID") + @GetMapping(value = "/child") + @PreAuthorize("@el.check('menu:list','roles:list')") + public ResponseEntity child(@RequestParam Long id){ + Set menuSet = new HashSet<>(); + List menuList = menuService.getMenus(id); + menuSet.add(menuService.findOne(id)); + menuSet = menuService.getChildMenus(menuMapper.toEntity(menuList), menuSet); + Set ids = menuSet.stream().map(Menu::getId).collect(Collectors.toSet()); + return new ResponseEntity<>(ids,HttpStatus.OK); + } + + @GetMapping + @ApiOperation("查询菜单") + @PreAuthorize("@el.check('menu:list')") + public ResponseEntity query(MenuQueryCriteria criteria) throws Exception { + List menuDtoList = menuService.queryAll(criteria, true); + return new ResponseEntity<>(PageUtil.toPage(menuDtoList, menuDtoList.size()),HttpStatus.OK); + } + + @ApiOperation("查询菜单:根据ID获取同级与上级数据") + @PostMapping("/superior") + @PreAuthorize("@el.check('menu:list')") + public ResponseEntity getSuperior(@RequestBody List ids) { + Set menuDtos = new LinkedHashSet<>(); + if(CollectionUtil.isNotEmpty(ids)){ + for (Long id : ids) { + MenuDto menuDto = menuService.findById(id); + menuDtos.addAll(menuService.getSuperior(menuDto, new ArrayList<>())); + } + return new ResponseEntity<>(menuService.buildTree(new ArrayList<>(menuDtos)),HttpStatus.OK); + } + return new ResponseEntity<>(menuService.getMenus(null),HttpStatus.OK); + } + + @Log("新增菜单") + @ApiOperation("新增菜单") + @PostMapping + @PreAuthorize("@el.check('menu:add')") + public ResponseEntity create(@Validated @RequestBody Menu resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + menuService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改菜单") + @ApiOperation("修改菜单") + @PutMapping + @PreAuthorize("@el.check('menu:edit')") + public ResponseEntity update(@Validated(Menu.Update.class) @RequestBody Menu resources){ + menuService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除菜单") + @ApiOperation("删除菜单") + @DeleteMapping + @PreAuthorize("@el.check('menu:del')") + public ResponseEntity delete(@RequestBody Set ids){ + Set menuSet = new HashSet<>(); + for (Long id : ids) { + List menuList = menuService.getMenus(id); + menuSet.add(menuService.findOne(id)); + menuSet = menuService.getChildMenus(menuMapper.toEntity(menuList), menuSet); + } + menuService.delete(menuSet); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/MonitorController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/MonitorController.java new file mode 100644 index 0000000000000000000000000000000000000000..be0c9d34f02c538604033b9724f5715b47ca2b8b --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/MonitorController.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.modules.system.service.MonitorService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Zheng Jie + * @date 2020-05-02 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统-服务监控管理") +@RequestMapping("/api/monitor") +public class MonitorController { + + private final MonitorService serverService; + + @GetMapping + @ApiOperation("查询服务监控") + @PreAuthorize("@el.check('monitor:list')") + public ResponseEntity query(){ + return new ResponseEntity<>(serverService.getServers(),HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/RoleController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/RoleController.java new file mode 100644 index 0000000000000000000000000000000000000000..17287f5e64cc8548511437381f83cb0e6a42411c --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/RoleController.java @@ -0,0 +1,155 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import cn.hutool.core.lang.Dict; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.annotation.Log; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.system.domain.Role; +import xiong.copy.modules.system.service.RoleService; +import xiong.copy.modules.system.service.dto.RoleDto; +import xiong.copy.modules.system.service.dto.RoleQueryCriteria; +import xiong.copy.modules.system.service.dto.RoleSmallDto; +import xiong.copy.utils.SecurityUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "系统:角色管理") +@RequestMapping("/api/roles") +public class RoleController { + + private final RoleService roleService; + + private static final String ENTITY_NAME = "role"; + + @ApiOperation("获取单个role") + @GetMapping(value = "/{id}") + @PreAuthorize("@el.check('roles:list')") + public ResponseEntity query(@PathVariable Long id){ + return new ResponseEntity<>(roleService.findById(id), HttpStatus.OK); + } + + @ApiOperation("导出角色数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('role:list')") + public void download(HttpServletResponse response, RoleQueryCriteria criteria) throws IOException { + roleService.download(roleService.queryAll(criteria), response); + } + + @ApiOperation("返回全部的角色") + @GetMapping(value = "/all") + @PreAuthorize("@el.check('roles:list','user:add','user:edit')") + public ResponseEntity query(){ + return new ResponseEntity<>(roleService.queryAll(),HttpStatus.OK); + } + + @ApiOperation("查询角色") + @GetMapping + @PreAuthorize("@el.check('roles:list')") + public ResponseEntity query(RoleQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(roleService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @ApiOperation("获取用户级别") + @GetMapping(value = "/level") + public ResponseEntity getLevel(){ + return new ResponseEntity<>(Dict.create().set("level", getLevels(null)),HttpStatus.OK); + } + + @Log("新增角色") + @ApiOperation("新增角色") + @PostMapping + @PreAuthorize("@el.check('roles:add')") + public ResponseEntity create(@Validated @RequestBody Role resources){ + if (resources.getId() != null) { + throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); + } + getLevels(resources.getLevel()); + roleService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改角色") + @ApiOperation("修改角色") + @PutMapping + @PreAuthorize("@el.check('roles:edit')") + public ResponseEntity update(@Validated(Role.Update.class) @RequestBody Role resources){ + getLevels(resources.getLevel()); + roleService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("修改角色菜单") + @ApiOperation("修改角色菜单") + @PutMapping(value = "/menu") + @PreAuthorize("@el.check('roles:edit')") + public ResponseEntity updateMenu(@RequestBody Role resources){ + RoleDto role = roleService.findById(resources.getId()); + getLevels(role.getLevel()); + roleService.updateMenu(resources,role); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除角色") + @ApiOperation("删除角色") + @DeleteMapping + @PreAuthorize("@el.check('roles:del')") + public ResponseEntity delete(@RequestBody Set ids){ + for (Long id : ids) { + RoleDto role = roleService.findById(id); + getLevels(role.getLevel()); + } + // 验证是否被用户关联 + roleService.verification(ids); + roleService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * 获取用户的角色级别 + * @return / + */ + private int getLevels(Integer level){ + List levels = roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()); + int min = Collections.min(levels); + if(level != null){ + if(level < min){ + throw new BadRequestException("权限不足,你的角色级别:" + min + ",低于操作的角色级别:" + level); + } + } + return min; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/UserController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/UserController.java new file mode 100644 index 0000000000000000000000000000000000000000..4cd22be433f5052ba9dc4bd8f07535509142423e --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/UserController.java @@ -0,0 +1,200 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.rest; + +import cn.hutool.core.collection.CollectionUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import xiong.copy.annotation.Log; +import xiong.copy.config.RsaProperties; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.system.domain.Dept; +import xiong.copy.modules.system.domain.User; +import xiong.copy.modules.system.domain.vo.UserPassVo; +import xiong.copy.modules.system.service.*; +import xiong.copy.modules.system.service.dto.RoleSmallDto; +import xiong.copy.modules.system.service.dto.UserDto; +import xiong.copy.modules.system.service.dto.UserQueryCriteria; +import xiong.copy.utils.*; +import xiong.copy.utils.enums.CodeEnum; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Api(tags = "系统:用户管理") +@RestController +@RequestMapping("/api/users") +@RequiredArgsConstructor +public class UserController { + + private final PasswordEncoder passwordEncoder; + private final UserService userService; + private final DataService dataService; + private final DeptService deptService; + private final RoleService roleService; +// private final VerifyService verificationCodeService; + + @ApiOperation("导出用户数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('user:list')") + public void download(HttpServletResponse response, UserQueryCriteria criteria) throws IOException { + userService.download(userService.queryAll(criteria), response); + } + + @ApiOperation("查询用户") + @GetMapping + @PreAuthorize("@el.check('user:list')") + public ResponseEntity query(UserQueryCriteria criteria, Pageable pageable){ + if (!ObjectUtils.isEmpty(criteria.getDeptId())) { + criteria.getDeptIds().add(criteria.getDeptId()); + // 先查找是否存在子节点 + List data = deptService.findByPid(criteria.getDeptId()); + // 然后把子节点的ID都加入到集合中 + criteria.getDeptIds().addAll(deptService.getDeptChildren(data)); + } + // 数据权限 + List dataScopes = dataService.getDeptIds(userService.findByName(SecurityUtils.getCurrentUsername())); + // criteria.getDeptIds() 不为空并且数据权限不为空则取交集 + if (!CollectionUtils.isEmpty(criteria.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)){ + // 取交集 + criteria.getDeptIds().retainAll(dataScopes); + if(!CollectionUtil.isEmpty(criteria.getDeptIds())){ + return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK); + } + } else { + // 否则取并集 + criteria.getDeptIds().addAll(dataScopes); + return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK); + } + return new ResponseEntity<>(PageUtil.toPage(null,0),HttpStatus.OK); + } + + @Log("新增用户") + @ApiOperation("新增用户") + @PostMapping + @PreAuthorize("@el.check('user:add')") + public ResponseEntity create(@Validated @RequestBody User resources){ + checkLevel(resources); + // 默认密码 123456 + resources.setPassword(passwordEncoder.encode("123456")); + userService.create(resources); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @Log("修改用户") + @ApiOperation("修改用户") + @PutMapping + @PreAuthorize("@el.check('user:edit')") + public ResponseEntity update(@Validated(User.Update.class) @RequestBody User resources) throws Exception { + checkLevel(resources); + userService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("修改用户:个人中心") + @ApiOperation("修改用户:个人中心") + @PutMapping(value = "center") + public ResponseEntity center(@Validated(User.Update.class) @RequestBody User resources){ + if(!resources.getId().equals(SecurityUtils.getCurrentUserId())){ + throw new BadRequestException("不能修改他人资料"); + } + userService.updateCenter(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除用户") + @ApiOperation("删除用户") + @DeleteMapping + @PreAuthorize("@el.check('user:del')") + public ResponseEntity delete(@RequestBody Set ids){ + for (Long id : ids) { + Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + Integer optLevel = Collections.min(roleService.findByUsersId(id).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + if (currentLevel > optLevel) { + throw new BadRequestException("角色权限不足,不能删除:" + userService.findById(id).getUsername()); + } + } + userService.delete(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("修改密码") + @PostMapping(value = "/updatePass") + public ResponseEntity updatePass(@RequestBody UserPassVo passVo) throws Exception { + String oldPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getOldPass()); + String newPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getNewPass()); + UserDto user = userService.findByName(SecurityUtils.getCurrentUsername()); + if(!passwordEncoder.matches(oldPass, user.getPassword())){ + throw new BadRequestException("修改失败,旧密码错误"); + } + if(passwordEncoder.matches(newPass, user.getPassword())){ + throw new BadRequestException("新密码不能与旧密码相同"); + } + userService.updatePass(user.getUsername(),passwordEncoder.encode(newPass)); + return new ResponseEntity<>(HttpStatus.OK); + } + + @ApiOperation("修改头像") + @PostMapping(value = "/updateAvatar") + public ResponseEntity updateAvatar(@RequestParam MultipartFile avatar){ + return new ResponseEntity<>(userService.updateAvatar(avatar), HttpStatus.OK); + } + +// @Log("修改邮箱") +// @ApiOperation("修改邮箱") +// @PostMapping(value = "/updateEmail/{code}") +// public ResponseEntity updateEmail(@PathVariable String code, @RequestBody User user) throws Exception { +// String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,user.getPassword()); +// UserDto userDto = userService.findByName(SecurityUtils.getCurrentUsername()); +// if(!passwordEncoder.matches(password, userDto.getPassword())){ +// throw new BadRequestException("密码错误"); +// } +// verificationCodeService.validated(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey() + user.getEmail(), code); +// userService.updateEmail(userDto.getUsername(),user.getEmail()); +// return new ResponseEntity<>(HttpStatus.OK); +// } + + /** + * 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误 + * @param resources / + */ + private void checkLevel(User resources) { + Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + Integer optLevel = roleService.findByRoles(resources.getRoles()); + if (currentLevel > optLevel) { + throw new BadRequestException("角色权限不足"); + } + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/rest/VerifyController.java b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/VerifyController.java new file mode 100644 index 0000000000000000000000000000000000000000..a2b915f89fc9c0a8b3545351a8b28044cce5590f --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/rest/VerifyController.java @@ -0,0 +1,77 @@ +///* +// * Copyright 2019-2020 Zheng Jie +// * +// * Licensed 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. +// */ +//package xiong.copy.modules.system.rest; +// +//import io.swagger.annotations.Api; +//import io.swagger.annotations.ApiOperation; +//import lombok.RequiredArgsConstructor; +//import xiong.copy.domain.vo.EmailVo; +//import xiong.copy.modules.system.service.VerifyService; +//import xiong.copy.service.EmailService; +//import xiong.copy.utils.enums.CodeBiEnum; +//import xiong.copy.utils.enums.CodeEnum; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.*; +// +//import java.util.Objects; +// +///** +// * @author Zheng Jie +// * @date 2018-12-26 +// */ +//@RestController +//@RequiredArgsConstructor +//@RequestMapping("/api/code") +//@Api(tags = "系统:验证码管理") +//public class VerifyController { +// +// private final VerifyService verificationCodeService; +// private final EmailService emailService; +// +// @PostMapping(value = "/resetEmail") +// @ApiOperation("重置邮箱,发送验证码") +// public ResponseEntity resetEmail(@RequestParam String email){ +// EmailVo emailVo = verificationCodeService.sendEmail(email, CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey()); +// emailService.send(emailVo,emailService.find()); +// return new ResponseEntity<>(HttpStatus.OK); +// } +// +// @PostMapping(value = "/email/resetPass") +// @ApiOperation("重置密码,发送验证码") +// public ResponseEntity resetPass(@RequestParam String email){ +// EmailVo emailVo = verificationCodeService.sendEmail(email, CodeEnum.EMAIL_RESET_PWD_CODE.getKey()); +// emailService.send(emailVo,emailService.find()); +// return new ResponseEntity<>(HttpStatus.OK); +// } +// +// @GetMapping(value = "/validated") +// @ApiOperation("验证码验证") +// public ResponseEntity validated(@RequestParam String email, @RequestParam String code, @RequestParam Integer codeBi){ +// CodeBiEnum biEnum = CodeBiEnum.find(codeBi); +// switch (Objects.requireNonNull(biEnum)){ +// case ONE: +// verificationCodeService.validated(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey() + email ,code); +// break; +// case TWO: +// verificationCodeService.validated(CodeEnum.EMAIL_RESET_PWD_CODE.getKey() + email ,code); +// break; +// default: +// break; +// } +// return new ResponseEntity<>(HttpStatus.OK); +// } +//} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/DataService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/DataService.java new file mode 100644 index 0000000000000000000000000000000000000000..b62605bd8c103825a743e99aa5cd9aba637e508d --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/DataService.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import xiong.copy.modules.system.service.dto.UserDto; + +import java.util.List; + +/** + * 数据权限服务类 + * @author Zheng Jie + * @date 2020-05-07 + */ +public interface DataService { + + /** + * 获取数据权限 + * @param user / + * @return / + */ + List getDeptIds(UserDto user); +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/DeptService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/DeptService.java new file mode 100644 index 0000000000000000000000000000000000000000..69a9ce1482a9c1462577976f921d078dbe613bd3 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/DeptService.java @@ -0,0 +1,125 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import xiong.copy.modules.system.domain.Dept; +import xiong.copy.modules.system.service.dto.DeptDto; +import xiong.copy.modules.system.service.dto.DeptQueryCriteria; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +public interface DeptService { + + /** + * 查询所有数据 + * @param criteria 条件 + * @param isQuery / + * @throws Exception / + * @return / + */ + List queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception; + + /** + * 根据ID查询 + * @param id / + * @return / + */ + DeptDto findById(Long id); + + /** + * 创建 + * @param resources / + */ + void create(Dept resources); + + /** + * 编辑 + * @param resources / + */ + void update(Dept resources); + + /** + * 删除 + * @param deptDtos / + * + */ + void delete(Set deptDtos); + + /** + * 根据PID查询 + * @param pid / + * @return / + */ + List findByPid(long pid); + + /** + * 根据角色ID查询 + * @param id / + * @return / + */ + Set findByRoleId(Long id); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 获取待删除的部门 + * @param deptList / + * @param deptDtos / + * @return / + */ + Set getDeleteDepts(List deptList, Set deptDtos); + + /** + * 根据ID获取同级与上级数据 + * @param deptDto / + * @param depts / + * @return / + */ + List getSuperior(DeptDto deptDto, List depts); + + /** + * 构建树形数据 + * @param deptDtos / + * @return / + */ + Object buildTree(List deptDtos); + + /** + * 获取 + * @param deptList + * @return + */ + List getDeptChildren(List deptList); + + /** + * 验证是否被角色或用户关联 + * @param deptDtos / + */ + void verification(Set deptDtos); +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/DictDetailService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/DictDetailService.java new file mode 100644 index 0000000000000000000000000000000000000000..0a6855107b4e30f179ebd65e2ca821c8a96649af --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/DictDetailService.java @@ -0,0 +1,64 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import xiong.copy.modules.system.domain.DictDetail; +import xiong.copy.modules.system.service.dto.DictDetailDto; +import xiong.copy.modules.system.service.dto.DictDetailQueryCriteria; +import org.springframework.data.domain.Pageable; + +import java.util.List; +import java.util.Map; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +public interface DictDetailService { + + /** + * 创建 + * @param resources / + */ + void create(DictDetail resources); + + /** + * 编辑 + * @param resources / + */ + void update(DictDetail resources); + + /** + * 删除 + * @param id / + */ + void delete(Long id); + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(DictDetailQueryCriteria criteria, Pageable pageable); + + /** + * 根据字典名称获取字典详情 + * @param name 字典名称 + * @return / + */ + List getDictByName(String name); +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/DictService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/DictService.java new file mode 100644 index 0000000000000000000000000000000000000000..2f4e43e632b0c78c3535dfe42161139fe4cea8fd --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/DictService.java @@ -0,0 +1,76 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import xiong.copy.modules.system.domain.Dict; +import xiong.copy.modules.system.service.dto.DictDto; +import xiong.copy.modules.system.service.dto.DictQueryCriteria; +import org.springframework.data.domain.Pageable; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +public interface DictService { + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(DictQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param dict / + * @return / + */ + List queryAll(DictQueryCriteria dict); + + /** + * 创建 + * @param resources / + * @return / + */ + void create(Dict resources); + + /** + * 编辑 + * @param resources / + */ + void update(Dict resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/JobService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/JobService.java new file mode 100644 index 0000000000000000000000000000000000000000..138ae46941703bcada034675e9a5cdf50f625f32 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/JobService.java @@ -0,0 +1,89 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import xiong.copy.modules.system.domain.Job; +import xiong.copy.modules.system.service.dto.JobDto; +import xiong.copy.modules.system.service.dto.JobQueryCriteria; +import org.springframework.data.domain.Pageable; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +public interface JobService { + + /** + * 根据ID查询 + * @param id / + * @return / + */ + JobDto findById(Long id); + + /** + * 创建 + * @param resources / + * @return / + */ + void create(Job resources); + + /** + * 编辑 + * @param resources / + */ + void update(Job resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Map queryAll(JobQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部数据 + * @param criteria / + * @return / + */ + List queryAll(JobQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 验证是否被用户关联 + * @param ids / + */ + void verification(Set ids); +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/MenuService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/MenuService.java new file mode 100644 index 0000000000000000000000000000000000000000..23054bc7bce89d04dea01b9f569e75ccdba36a43 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/MenuService.java @@ -0,0 +1,125 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import xiong.copy.modules.system.domain.Menu; +import xiong.copy.modules.system.service.dto.MenuDto; +import xiong.copy.modules.system.service.dto.MenuQueryCriteria; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +public interface MenuService { + + /** + * 查询全部数据 + * @param criteria 条件 + * @param isQuery / + * @throws Exception / + * @return / + */ + List queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception; + + /** + * 根据ID查询 + * @param id / + * @return / + */ + MenuDto findById(long id); + + /** + * 创建 + * @param resources / + */ + void create(Menu resources); + + /** + * 编辑 + * @param resources / + */ + void update(Menu resources); + + /** + * 获取所有子节点,包含自身ID + * @param menuList / + * @param menuSet / + * @return / + */ + Set getChildMenus(List menuList, Set menuSet); + + /** + * 构建菜单树 + * @param menuDtos 原始数据 + * @return / + */ + List buildTree(List menuDtos); + + /** + * 构建菜单树 + * @param menuDtos / + * @return / + */ + Object buildMenus(List menuDtos); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + Menu findOne(Long id); + + /** + * 删除 + * @param menuSet / + */ + void delete(Set menuSet); + + /** + * 导出 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 懒加载菜单数据 + * @param pid / + * @return / + */ + List getMenus(Long pid); + + /** + * 根据ID获取同级与上级数据 + * @param menuDto / + * @param objects / + * @return / + */ + List getSuperior(MenuDto menuDto, List objects); + + /** + * 根据当前用户获取菜单 + * @param currentUserId / + * @return / + */ + List findByUser(Long currentUserId); +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/MonitorService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/MonitorService.java new file mode 100644 index 0000000000000000000000000000000000000000..17275fe85a9519a93a4085a8b1804c214661c0b8 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/MonitorService.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import java.util.Map; + +/** + * @author Zheng Jie + * @date 2020-05-02 + */ +public interface MonitorService { + + /** + * 查询数据分页 + * @return Map + */ + Map getServers(); +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/RoleService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/RoleService.java new file mode 100644 index 0000000000000000000000000000000000000000..89ed17e8628a863556be991077ed7948a7ef6737 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/RoleService.java @@ -0,0 +1,137 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import xiong.copy.modules.system.domain.Role; +import xiong.copy.modules.system.service.dto.RoleDto; +import xiong.copy.modules.system.service.dto.RoleQueryCriteria; +import xiong.copy.modules.system.service.dto.RoleSmallDto; +import xiong.copy.modules.system.service.dto.UserDto; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.GrantedAuthority; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ +public interface RoleService { + + /** + * 查询全部数据 + * @return / + */ + List queryAll(); + + /** + * 根据ID查询 + * @param id / + * @return / + */ + RoleDto findById(long id); + + /** + * 创建 + * @param resources / + */ + void create(Role resources); + + /** + * 编辑 + * @param resources / + */ + void update(Role resources); + + /** + * 删除 + * @param ids / + */ + void delete(Set ids); + + /** + * 根据用户ID查询 + * @param id 用户ID + * @return / + */ + List findByUsersId(Long id); + + /** + * 根据角色查询角色级别 + * @param roles / + * @return / + */ + Integer findByRoles(Set roles); + + /** + * 修改绑定的菜单 + * @param resources / + * @param roleDTO / + */ + void updateMenu(Role resources, RoleDto roleDTO); + + /** + * 解绑菜单 + * @param id / + */ + void untiedMenu(Long id); + + /** + * 待条件分页查询 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(RoleQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部 + * @param criteria 条件 + * @return / + */ + List queryAll(RoleQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 获取用户权限信息 + * @param user 用户信息 + * @return 权限信息 + */ + List mapToGrantedAuthorities(UserDto user); + + /** + * 验证是否被用户关联 + * @param ids / + */ + void verification(Set ids); + + /** + * 根据菜单Id查询 + * @param menuIds / + * @return / + */ + List findInMenuId(List menuIds); +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/UserService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/UserService.java new file mode 100644 index 0000000000000000000000000000000000000000..c59c7deaddccf6a76472a1070ac119ddbdc09599 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/UserService.java @@ -0,0 +1,117 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service; + +import xiong.copy.modules.system.domain.User; +import xiong.copy.modules.system.service.dto.UserDto; +import xiong.copy.modules.system.service.dto.UserQueryCriteria; +import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +public interface UserService { + + /** + * 根据ID查询 + * @param id ID + * @return / + */ + UserDto findById(long id); + + /** + * 新增用户 + * @param resources / + */ + void create(User resources); + + /** + * 编辑用户 + * @param resources / + */ + void update(User resources) throws Exception; + + /** + * 删除用户 + * @param ids / + */ + void delete(Set ids); + + /** + * 根据用户名查询 + * @param userName / + * @return / + */ + UserDto findByName(String userName); + + /** + * 修改密码 + * @param username 用户名 + * @param encryptPassword 密码 + */ + void updatePass(String username, String encryptPassword); + + /** + * 修改头像 + * @param file 文件 + * @return / + */ + Map updateAvatar(MultipartFile file); + + /** + * 修改邮箱 + * @param username 用户名 + * @param email 邮箱 + */ + void updateEmail(String username, String email); + + /** + * 查询全部 + * @param criteria 条件 + * @param pageable 分页参数 + * @return / + */ + Object queryAll(UserQueryCriteria criteria, Pageable pageable); + + /** + * 查询全部不分页 + * @param criteria 条件 + * @return / + */ + List queryAll(UserQueryCriteria criteria); + + /** + * 导出数据 + * @param queryAll 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List queryAll, HttpServletResponse response) throws IOException; + + /** + * 用户自助修改资料 + * @param resources / + */ + void updateCenter(User resources); +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/VerifyService.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/VerifyService.java new file mode 100644 index 0000000000000000000000000000000000000000..952826b367c78e1d7aa0d09e68ce8f189b729f67 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/VerifyService.java @@ -0,0 +1,41 @@ +///* +// * Copyright 2019-2020 Zheng Jie +// * +// * Licensed 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. +// */ +//package xiong.copy.modules.system.service; +// +//import xiong.copy.domain.vo.EmailVo; +// +///** +// * @author Zheng Jie +// * @date 2018-12-26 +// */ +//public interface VerifyService { +// +// /** +// * 发送验证码 +// * @param email / +// * @param key / +// * @return / +// */ +// EmailVo sendEmail(String email, String key); +// +// +// /** +// * 验证 +// * @param code / +// * @param key / +// */ +// void validated(String key, String code); +//} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptDto.java new file mode 100644 index 0000000000000000000000000000000000000000..d13396385e5f2404a693fa21e130d72743abc213 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptDto.java @@ -0,0 +1,79 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseDTO; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Getter +@Setter +public class DeptDto extends BaseDTO implements Serializable { + + private Long id; + + private String name; + + private Boolean enabled; + + private Integer deptSort; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + private Long pid; + + private Integer subCount; + + public Boolean getHasChildren() { + return subCount > 0; + } + + public Boolean getLeaf() { + return subCount <= 0; + } + + public String getLabel() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DeptDto deptDto = (DeptDto) o; + return Objects.equals(id, deptDto.id) && + Objects.equals(name, deptDto.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptQueryCriteria.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptQueryCriteria.java new file mode 100644 index 0000000000000000000000000000000000000000..28258e226a4f3b5393e6d1edc2c8ad6d04cb6e15 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptQueryCriteria.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; +import xiong.copy.annotation.DataPermission; +import xiong.copy.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Data +@DataPermission(fieldName = "id") +public class DeptQueryCriteria{ + + @Query(type = Query.Type.INNER_LIKE) + private String name; + + @Query + private Boolean enabled; + + @Query + private Long pid; + + @Query(type = Query.Type.IS_NULL, propName = "pid") + private Boolean pidIsNull; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptSmallDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptSmallDto.java new file mode 100644 index 0000000000000000000000000000000000000000..2be737a0a0ad6171c66ac55bc93494f73e4af08e --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DeptSmallDto.java @@ -0,0 +1,32 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-6-10 16:32:18 +*/ +@Data +public class DeptSmallDto implements Serializable { + + private Long id; + + private String name; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDetailDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDetailDto.java new file mode 100644 index 0000000000000000000000000000000000000000..91f9e5bc2f01f455a734f30c8998de515fc9118c --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDetailDto.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseDTO; + +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Getter +@Setter +public class DictDetailDto extends BaseDTO implements Serializable { + + private Long id; + + private DictSmallDto dict; + + private String label; + + private String value; + + private Integer dictSort; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDetailQueryCriteria.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDetailQueryCriteria.java new file mode 100644 index 0000000000000000000000000000000000000000..2af047aabfb4be38592333d14957363a96013b97 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDetailQueryCriteria.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; +import xiong.copy.annotation.Query; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Data +public class DictDetailQueryCriteria { + + @Query(type = Query.Type.INNER_LIKE) + private String label; + + @Query(propName = "name",jionName = "dict") + private String dictName; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDto.java new file mode 100644 index 0000000000000000000000000000000000000000..a633d814458a48ab5ba8568ffa914ebb8dfe8d8b --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictDto.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseDTO; + +import java.io.Serializable; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Getter +@Setter +public class DictDto extends BaseDTO implements Serializable { + + private Long id; + + private List dictDetails; + + private String name; + + private String description; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictQueryCriteria.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictQueryCriteria.java new file mode 100644 index 0000000000000000000000000000000000000000..c1857a3fafb6cfe32b9eee7e5e4679fb04638416 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictQueryCriteria.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; +import xiong.copy.annotation.Query; + +/** + * @author Zheng Jie + * 公共查询类 + */ +@Data +public class DictQueryCriteria { + + @Query(blurry = "name,description") + private String blurry; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictSmallDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictSmallDto.java new file mode 100644 index 0000000000000000000000000000000000000000..ebc6ef1508639a794f9e8b068b9e60d4afc7774e --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/DictSmallDto.java @@ -0,0 +1,32 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Getter +@Setter +public class DictSmallDto implements Serializable { + + private Long id; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobDto.java new file mode 100644 index 0000000000000000000000000000000000000000..16167ba93e2dd298ad30a236bfa0611cbf6db73d --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobDto.java @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + + +import xiong.copy.base.BaseDTO; + +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +//@Getter +//@Setter +//@NoArgsConstructor +public class JobDto extends BaseDTO implements Serializable { + + private Long id; + + private Integer jobSort; + + private String name; + + private Boolean enabled; + + public JobDto(String name, Boolean enabled) { + this.name = name; + this.enabled = enabled; + } + + + public JobDto() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getJobSort() { + return jobSort; + } + + public void setJobSort(Integer jobSort) { + this.jobSort = jobSort; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobQueryCriteria.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobQueryCriteria.java new file mode 100644 index 0000000000000000000000000000000000000000..57249227f56edbcf09ca129cb0ffc15c65fb79d7 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobQueryCriteria.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; +import xiong.copy.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +/** +* @author Zheng Jie +* @date 2019-6-4 14:49:34 +*/ +@Data +@NoArgsConstructor +public class JobQueryCriteria { + + @Query(type = Query.Type.INNER_LIKE) + private String name; + + @Query + private Boolean enabled; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobSmallDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobSmallDto.java new file mode 100644 index 0000000000000000000000000000000000000000..a354ecec61b7889f3c805f5b88a0adffeb06b299 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/JobSmallDto.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** +* @author Zheng Jie +* @date 2019-6-10 16:32:18 +*/ +@Data +@NoArgsConstructor +public class JobSmallDto implements Serializable { + + private Long id; + + private String name; +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/MenuDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/MenuDto.java new file mode 100644 index 0000000000000000000000000000000000000000..dcfb1ab5aad3b913cda8ad854a0d87e730bf42f0 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/MenuDto.java @@ -0,0 +1,92 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseDTO; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +@Getter +@Setter +public class MenuDto extends BaseDTO implements Serializable { + + private Long id; + + private List children; + + private Integer type; + + private String permission; + + private String title; + + private Integer menuSort; + + private String path; + + private String component; + + private Long pid; + + private Integer subCount; + + private Boolean iFrame; + + private Boolean cache; + + private Boolean hidden; + + private String componentName; + + private String icon; + + public Boolean getHasChildren() { + return subCount > 0; + } + + public Boolean getLeaf() { + return subCount <= 0; + } + + public String getLabel() { + return title; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MenuDto menuDto = (MenuDto) o; + return Objects.equals(id, menuDto.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/MenuQueryCriteria.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/MenuQueryCriteria.java new file mode 100644 index 0000000000000000000000000000000000000000..852ce314c4bf1e3628e21a8f8ce8c444dab73349 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/MenuQueryCriteria.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; +import xiong.copy.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +/** + * @author Zheng Jie + * 公共查询类 + */ +@Data +public class MenuQueryCriteria { + + @Query(blurry = "title,component,permission") + private String blurry; + + @Query(type = Query.Type.BETWEEN) + private List createTime; + + @Query(type = Query.Type.IS_NULL, propName = "pid") + private Boolean pidIsNull; + + @Query + private Long pid; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleDto.java new file mode 100644 index 0000000000000000000000000000000000000000..e247907b1acda4c5601bfa2547aae461c7868436 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleDto.java @@ -0,0 +1,64 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseDTO; + +import java.io.Serializable; +import java.util.Objects; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Getter +@Setter +public class RoleDto extends BaseDTO implements Serializable { + + private Long id; + + private Set menus; + + private Set depts; + + private String name; + + private String dataScope; + + private Integer level; + + private String description; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RoleDto roleDto = (RoleDto) o; + return Objects.equals(id, roleDto.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleQueryCriteria.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleQueryCriteria.java new file mode 100644 index 0000000000000000000000000000000000000000..0640a9373c2c5c0f275fed0d657d3ba6f0d75add --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleQueryCriteria.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; +import xiong.copy.annotation.Query; + +import java.sql.Timestamp; +import java.util.List; + +/** + * @author Zheng Jie + * 公共查询类 + */ +@Data +public class RoleQueryCriteria { + + @Query(blurry = "name,description") + private String blurry; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleSmallDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleSmallDto.java new file mode 100644 index 0000000000000000000000000000000000000000..3f98732c7b9b3ad6a9444e79d89a0ff99d6be1bf --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/RoleSmallDto.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Data +public class RoleSmallDto implements Serializable { + + private Long id; + + private String name; + + private Integer level; + + private String dataScope; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/UserDto.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/UserDto.java new file mode 100644 index 0000000000000000000000000000000000000000..2a2df28e37d0c2666ff6190fc39af716c0cd3c5e --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/UserDto.java @@ -0,0 +1,68 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Getter; +import lombok.Setter; +import xiong.copy.base.BaseDTO; + +import java.io.Serializable; +import java.util.Date; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Getter +@Setter +public class UserDto extends BaseDTO implements Serializable { + + private Long id; + + private Set roles; + + private Set jobs; + + private DeptSmallDto dept; + + private Long deptId; + + private String username; + + private String nickName; + + private String email; + + private String phone; + + private String gender; + + private String avatarName; + + private String avatarPath; + + @JSONField(serialize = false) + private String password; + + private Boolean enabled; + + @JSONField(serialize = false) + private Boolean isAdmin = false; + + private Date pwdResetTime; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/UserQueryCriteria.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/UserQueryCriteria.java new file mode 100644 index 0000000000000000000000000000000000000000..f2d6418f5205c841c8274f69040f291d851dde66 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/dto/UserQueryCriteria.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.dto; + +import lombok.Data; +import xiong.copy.annotation.Query; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Data +public class UserQueryCriteria implements Serializable { + + @Query + private Long id; + + @Query(propName = "id", type = Query.Type.IN, jionName = "dept") + private Set deptIds = new HashSet<>(); + + @Query(blurry = "email,username,nickName") + private String blurry; + + @Query + private Boolean enabled; + + private Long deptId; + + @Query(type = Query.Type.BETWEEN) + private List createTime; +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DataServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DataServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..be261c440a890f69f9fba812b722652f94a457b3 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DataServiceImpl.java @@ -0,0 +1,92 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import lombok.RequiredArgsConstructor; +import xiong.copy.modules.system.domain.Dept; +import xiong.copy.modules.system.service.DataService; +import xiong.copy.modules.system.service.DeptService; +import xiong.copy.modules.system.service.RoleService; +import xiong.copy.modules.system.service.dto.RoleSmallDto; +import xiong.copy.modules.system.service.dto.UserDto; +import xiong.copy.utils.enums.DataScopeEnum; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * @author Zheng Jie + * @website https://el-admin.vip + * @description 数据权限服务实现 + * @date 2020-05-07 + **/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "data") +public class DataServiceImpl implements DataService { + + private final RoleService roleService; + private final DeptService deptService; + + /** + * 用户角色改变时需清理缓存 + * @param user / + * @return / + */ + @Override + @Cacheable(key = "'user:' + #p0.id") + public List getDeptIds(UserDto user) { + // 用于存储部门id + Set deptIds = new HashSet<>(); + // 查询用户角色 + List roleSet = roleService.findByUsersId(user.getId()); + // 获取对应的部门ID + for (RoleSmallDto role : roleSet) { + DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope()); + switch (Objects.requireNonNull(dataScopeEnum)) { + case THIS_LEVEL: + deptIds.add(user.getDept().getId()); + break; + case CUSTOMIZE: + deptIds.addAll(getCustomize(deptIds, role)); + break; + default: + return new ArrayList<>(deptIds); + } + } + return new ArrayList<>(deptIds); + } + + /** + * 获取自定义的数据权限 + * @param deptIds 部门ID + * @param role 角色 + * @return 数据权限ID + */ + public Set getCustomize(Set deptIds, RoleSmallDto role){ + Set depts = deptService.findByRoleId(role.getId()); + for (Dept dept : depts) { + deptIds.add(dept.getId()); + List deptChildren = deptService.findByPid(dept.getId()); + if (deptChildren != null && deptChildren.size() != 0) { + deptIds.addAll(deptService.getDeptChildren(deptChildren)); + } + } + return deptIds; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DeptServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DeptServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..49715b1edc309a843ebb1f7f567bb026a0397d90 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DeptServiceImpl.java @@ -0,0 +1,284 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.RequiredArgsConstructor; +import xiong.copy.exception.BadRequestException; +import xiong.copy.modules.system.domain.Dept; +import xiong.copy.modules.system.domain.User; +import xiong.copy.modules.system.repository.DeptRepository; +import xiong.copy.modules.system.repository.RoleRepository; +import xiong.copy.modules.system.repository.UserRepository; +import xiong.copy.modules.system.service.DeptService; +import xiong.copy.modules.system.service.dto.DeptDto; +import xiong.copy.modules.system.service.dto.DeptQueryCriteria; +import xiong.copy.modules.system.service.mapstruct.DeptMapper; +import xiong.copy.utils.*; +import xiong.copy.utils.enums.DataScopeEnum; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dept") +public class DeptServiceImpl implements DeptService { + + private final DeptRepository deptRepository; + private final DeptMapper deptMapper; + private final UserRepository userRepository; + private final RedisUtils redisUtils; + private final RoleRepository roleRepository; + + @Override + public List queryAll(DeptQueryCriteria criteria, Boolean isQuery) throws Exception { + Sort sort = Sort.by(Sort.Direction.ASC, "deptSort"); + String dataScopeType = SecurityUtils.getDataScopeType(); + if (isQuery) { + if(dataScopeType.equals(DataScopeEnum.ALL.getValue())){ + criteria.setPidIsNull(true); + } + List fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>()); + List fieldNames = new ArrayList(){{ add("pidIsNull");add("enabled");}}; + for (Field field : fields) { + //设置对象的访问权限,保证对private的属性的访问 + field.setAccessible(true); + Object val = field.get(criteria); + if(fieldNames.contains(field.getName())){ + continue; + } + if (ObjectUtil.isNotNull(val)) { + criteria.setPidIsNull(null); + break; + } + } + } + List list = deptMapper.toDto(deptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort)); + // 如果为空,就代表为自定义权限或者本级权限,就需要去重,不理解可以注释掉,看查询结果 + if(StringUtils.isBlank(dataScopeType)){ + return deduplication(list); + } + return list; + } + + @Override + @Cacheable(key = "'id:' + #p0") + public DeptDto findById(Long id) { + Dept dept = deptRepository.findById(id).orElseGet(Dept::new); + ValidationUtil.isNull(dept.getId(),"Dept","id",id); + return deptMapper.toDto(dept); + } + + @Override + public List findByPid(long pid) { + return deptRepository.findByPid(pid); + } + + @Override + public Set findByRoleId(Long id) { + return deptRepository.findByRoleId(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Dept resources) { + deptRepository.save(resources); + // 计算子节点数目 + resources.setSubCount(0); + // 清理缓存 + updateSubCnt(resources.getPid()); + // 清理自定义角色权限的datascope缓存 + delCaches(resources.getPid()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Dept resources) { + // 旧的部门 + Long oldPid = findById(resources.getId()).getPid(); + Long newPid = resources.getPid(); + if(resources.getPid() != null && resources.getId().equals(resources.getPid())) { + throw new BadRequestException("上级不能为自己"); + } + Dept dept = deptRepository.findById(resources.getId()).orElseGet(Dept::new); + ValidationUtil.isNull( dept.getId(),"Dept","id",resources.getId()); + resources.setId(dept.getId()); + deptRepository.save(resources); + // 更新父节点中子节点数目 + updateSubCnt(oldPid); + updateSubCnt(newPid); + // 清理缓存 + delCaches(resources.getId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set deptDtos) { + for (DeptDto deptDto : deptDtos) { + // 清理缓存 + delCaches(deptDto.getId()); + deptRepository.deleteById(deptDto.getId()); + updateSubCnt(deptDto.getPid()); + } + } + + @Override + public void download(List deptDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DeptDto deptDTO : deptDtos) { + Map map = new LinkedHashMap<>(); + map.put("部门名称", deptDTO.getName()); + map.put("部门状态", deptDTO.getEnabled() ? "启用" : "停用"); + map.put("创建日期", deptDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public Set getDeleteDepts(List menuList, Set deptDtos) { + for (Dept dept : menuList) { + deptDtos.add(deptMapper.toDto(dept)); + List depts = deptRepository.findByPid(dept.getId()); + if(depts!=null && depts.size()!=0){ + getDeleteDepts(depts, deptDtos); + } + } + return deptDtos; + } + + @Override + public List getDeptChildren(List deptList) { + List list = new ArrayList<>(); + deptList.forEach(dept -> { + if (dept!=null && dept.getEnabled()) { + List depts = deptRepository.findByPid(dept.getId()); + if (depts.size() != 0) { + list.addAll(getDeptChildren(depts)); + } + list.add(dept.getId()); + } + } + ); + return list; + } + + @Override + public List getSuperior(DeptDto deptDto, List depts) { + if(deptDto.getPid() == null){ + depts.addAll(deptRepository.findByPidIsNull()); + return deptMapper.toDto(depts); + } + depts.addAll(deptRepository.findByPid(deptDto.getPid())); + return getSuperior(findById(deptDto.getPid()), depts); + } + + @Override + public Object buildTree(List deptDtos) { + Set trees = new LinkedHashSet<>(); + Set depts= new LinkedHashSet<>(); + List deptNames = deptDtos.stream().map(DeptDto::getName).collect(Collectors.toList()); + boolean isChild; + for (DeptDto deptDTO : deptDtos) { + isChild = false; + if (deptDTO.getPid() == null) { + trees.add(deptDTO); + } + for (DeptDto it : deptDtos) { + if (it.getPid() != null && deptDTO.getId().equals(it.getPid())) { + isChild = true; + if (deptDTO.getChildren() == null) { + deptDTO.setChildren(new ArrayList<>()); + } + deptDTO.getChildren().add(it); + } + } + if(isChild) { + depts.add(deptDTO); + } else if(deptDTO.getPid() != null && !deptNames.contains(findById(deptDTO.getPid()).getName())) { + depts.add(deptDTO); + } + } + + if (CollectionUtil.isEmpty(trees)) { + trees = depts; + } + Map map = new HashMap<>(2); + map.put("totalElements",deptDtos.size()); + map.put("content",CollectionUtil.isEmpty(trees)? deptDtos :trees); + return map; + } + + @Override + public void verification(Set deptDtos) { + Set deptIds = deptDtos.stream().map(DeptDto::getId).collect(Collectors.toSet()); + if(userRepository.countByDepts(deptIds) > 0){ + throw new BadRequestException("所选部门存在用户关联,请解除后再试!"); + } + if(roleRepository.countByDepts(deptIds) > 0){ + throw new BadRequestException("所选部门存在角色关联,请解除后再试!"); + } + } + + private void updateSubCnt(Long deptId){ + if(deptId != null){ + int count = deptRepository.countByPid(deptId); + deptRepository.updateSubCntById(count, deptId); + } + } + + private List deduplication(List list) { + List deptDtos = new ArrayList<>(); + for (DeptDto deptDto : list) { + boolean flag = true; + for (DeptDto dto : list) { + if (dto.getId().equals(deptDto.getPid())) { + flag = false; + break; + } + } + if (flag){ + deptDtos.add(deptDto); + } + } + return deptDtos; + } + + /** + * 清理缓存 + * @param id / + */ + public void delCaches(Long id){ + List users = userRepository.findByRoleDeptId(id); + // 删除数据权限 + redisUtils.delByKeys(CacheKey.DATA_USER, users.stream().map(User::getId).collect(Collectors.toSet())); + redisUtils.del(CacheKey.DEPT_ID + id); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DictDetailServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DictDetailServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e9e72f83f6cfd989cd513a66ab72ae7445074bf4 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DictDetailServiceImpl.java @@ -0,0 +1,96 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import lombok.RequiredArgsConstructor; +import xiong.copy.modules.system.domain.Dict; +import xiong.copy.modules.system.domain.DictDetail; +import xiong.copy.modules.system.repository.DictDetailRepository; +import xiong.copy.modules.system.repository.DictRepository; +import xiong.copy.modules.system.service.DictDetailService; +import xiong.copy.modules.system.service.dto.DictDetailDto; +import xiong.copy.modules.system.service.dto.DictDetailQueryCriteria; +import xiong.copy.modules.system.service.mapstruct.DictDetailMapper; +import xiong.copy.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dict") +public class DictDetailServiceImpl implements DictDetailService { + + private final DictRepository dictRepository; + private final DictDetailRepository dictDetailRepository; + private final DictDetailMapper dictDetailMapper; + private final RedisUtils redisUtils; + + @Override + public Map queryAll(DictDetailQueryCriteria criteria, Pageable pageable) { + Page page = dictDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(dictDetailMapper::toDto)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(DictDetail resources) { + dictDetailRepository.save(resources); + // 清理缓存 + delCaches(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(DictDetail resources) { + DictDetail dictDetail = dictDetailRepository.findById(resources.getId()).orElseGet(DictDetail::new); + ValidationUtil.isNull( dictDetail.getId(),"DictDetail","id",resources.getId()); + resources.setId(dictDetail.getId()); + dictDetailRepository.save(resources); + // 清理缓存 + delCaches(resources); + } + + @Override + @Cacheable(key = "'name:' + #p0") + public List getDictByName(String name) { + return dictDetailMapper.toDto(dictDetailRepository.findByDictName(name)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long id) { + DictDetail dictDetail = dictDetailRepository.findById(id).orElseGet(DictDetail::new); + // 清理缓存 + delCaches(dictDetail); + dictDetailRepository.deleteById(id); + } + + public void delCaches(DictDetail dictDetail){ + Dict dict = dictRepository.findById(dictDetail.getDict().getId()).orElseGet(Dict::new); + redisUtils.del(CacheKey.DICT_NAME + dict.getName()); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DictServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DictServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..554973070cc8e05907b41e67d570deed967125f7 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/DictServiceImpl.java @@ -0,0 +1,122 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import lombok.RequiredArgsConstructor; +import xiong.copy.modules.system.domain.Dict; +import xiong.copy.modules.system.repository.DictRepository; +import xiong.copy.modules.system.service.DictService; +import xiong.copy.modules.system.service.dto.DictDetailDto; +import xiong.copy.modules.system.service.dto.DictDto; +import xiong.copy.modules.system.service.dto.DictQueryCriteria; +import xiong.copy.modules.system.service.mapstruct.DictMapper; +import xiong.copy.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "dict") +public class DictServiceImpl implements DictService { + + private final DictRepository dictRepository; + private final DictMapper dictMapper; + private final RedisUtils redisUtils; + + @Override + public Map queryAll(DictQueryCriteria dict, Pageable pageable){ + Page page = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb), pageable); + return PageUtil.toPage(page.map(dictMapper::toDto)); + } + + @Override + public List queryAll(DictQueryCriteria dict) { + List list = dictRepository.findAll((root, query, cb) -> QueryHelp.getPredicate(root, dict, cb)); + return dictMapper.toDto(list); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Dict resources) { + dictRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Dict resources) { + // 清理缓存 + delCaches(resources); + Dict dict = dictRepository.findById(resources.getId()).orElseGet(Dict::new); + ValidationUtil.isNull( dict.getId(),"Dict","id",resources.getId()); + dict.setName(resources.getName()); + dict.setDescription(resources.getDescription()); + dictRepository.save(dict); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + // 清理缓存 + List dicts = dictRepository.findByIdIn(ids); + for (Dict dict : dicts) { + delCaches(dict); + } + dictRepository.deleteByIdIn(ids); + } + + @Override + public void download(List dictDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (DictDto dictDTO : dictDtos) { + if(CollectionUtil.isNotEmpty(dictDTO.getDictDetails())){ + for (DictDetailDto dictDetail : dictDTO.getDictDetails()) { + Map map = new LinkedHashMap<>(); + map.put("字典名称", dictDTO.getName()); + map.put("字典描述", dictDTO.getDescription()); + map.put("字典标签", dictDetail.getLabel()); + map.put("字典值", dictDetail.getValue()); + map.put("创建日期", dictDetail.getCreateTime()); + list.add(map); + } + } else { + Map map = new LinkedHashMap<>(); + map.put("字典名称", dictDTO.getName()); + map.put("字典描述", dictDTO.getDescription()); + map.put("字典标签", null); + map.put("字典值", null); + map.put("创建日期", dictDTO.getCreateTime()); + list.add(map); + } + } + FileUtil.downloadExcel(list, response); + } + + public void delCaches(Dict dict){ + redisUtils.del(CacheKey.DICT_NAME + dict.getName()); + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/JobServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/JobServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..2cdfeb8497fae66208d1ed69e2c52ffd85881ec5 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/JobServiceImpl.java @@ -0,0 +1,126 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import lombok.RequiredArgsConstructor; +import xiong.copy.exception.BadRequestException; +import xiong.copy.exception.EntityExistException; +import xiong.copy.modules.system.domain.Job; +import xiong.copy.modules.system.repository.JobRepository; +import xiong.copy.modules.system.repository.UserRepository; +import xiong.copy.modules.system.service.JobService; +import xiong.copy.modules.system.service.dto.JobDto; +import xiong.copy.modules.system.service.dto.JobQueryCriteria; +import xiong.copy.modules.system.service.mapstruct.JobMapper; +import xiong.copy.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "job") +public class JobServiceImpl implements JobService { + + private final JobRepository jobRepository; + private final JobMapper jobMapper; + private final RedisUtils redisUtils; + private final UserRepository userRepository; + + @Override + public Map queryAll(JobQueryCriteria criteria, Pageable pageable) { + Page page = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(jobMapper::toDto).getContent(),page.getTotalElements()); + } + + @Override + public List queryAll(JobQueryCriteria criteria) { + List list = jobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); + return jobMapper.toDto(list); + } + + @Override + @Cacheable(key = "'id:' + #p0") + public JobDto findById(Long id) { + Job job = jobRepository.findById(id).orElseGet(Job::new); + ValidationUtil.isNull(job.getId(),"Job","id",id); + return jobMapper.toDto(job); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Job resources) { + Job job = jobRepository.findByName(resources.getName()); + if(job != null){ + throw new EntityExistException(Job.class,"name",resources.getName()); + } + jobRepository.save(resources); + } + + @Override + @CacheEvict(key = "'id:' + #p0.id") + @Transactional(rollbackFor = Exception.class) + public void update(Job resources) { + Job job = jobRepository.findById(resources.getId()).orElseGet(Job::new); + Job old = jobRepository.findByName(resources.getName()); + if(old != null && !old.getId().equals(resources.getId())){ + throw new EntityExistException(Job.class,"name",resources.getName()); + } + ValidationUtil.isNull( job.getId(),"Job","id",resources.getId()); + resources.setId(job.getId()); + jobRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + jobRepository.deleteAllByIdIn(ids); + // 删除缓存 + redisUtils.delByKeys(CacheKey.JOB_ID, ids); + } + + @Override + public void download(List jobDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (JobDto jobDTO : jobDtos) { + Map map = new LinkedHashMap<>(); + map.put("岗位名称", jobDTO.getName()); + map.put("岗位状态", jobDTO.getEnabled() ? "启用" : "停用"); + map.put("创建日期", jobDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public void verification(Set ids) { + if(userRepository.countByJobs(ids) > 0){ + throw new BadRequestException("所选的岗位中存在用户关联,请解除关联再试!"); + } + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/MenuServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/MenuServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6b684080f042ed914399fd43a3288468ee68d600 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/MenuServiceImpl.java @@ -0,0 +1,356 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import lombok.RequiredArgsConstructor; +import xiong.copy.exception.BadRequestException; +import xiong.copy.exception.EntityExistException; +import xiong.copy.modules.system.domain.Menu; +import xiong.copy.modules.system.domain.Role; +import xiong.copy.modules.system.domain.User; +import xiong.copy.modules.system.domain.vo.MenuMetaVo; +import xiong.copy.modules.system.domain.vo.MenuVo; +import xiong.copy.modules.system.repository.MenuRepository; +import xiong.copy.modules.system.repository.UserRepository; +import xiong.copy.modules.system.service.MenuService; +import xiong.copy.modules.system.service.RoleService; +import xiong.copy.modules.system.service.dto.MenuDto; +import xiong.copy.modules.system.service.dto.MenuQueryCriteria; +import xiong.copy.modules.system.service.dto.RoleSmallDto; +import xiong.copy.modules.system.service.mapstruct.MenuMapper; +import xiong.copy.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "menu") +public class MenuServiceImpl implements MenuService { + + private final MenuRepository menuRepository; + private final UserRepository userRepository; + private final MenuMapper menuMapper; + private final RoleService roleService; + private final RedisUtils redisUtils; + + @Override + public List queryAll(MenuQueryCriteria criteria, Boolean isQuery) throws Exception { + Sort sort = Sort.by(Sort.Direction.ASC, "menuSort"); + if(Boolean.TRUE.equals(isQuery)){ + criteria.setPidIsNull(true); + List fields = QueryHelp.getAllFields(criteria.getClass(), new ArrayList<>()); + for (Field field : fields) { + //设置对象的访问权限,保证对private的属性的访问 + field.setAccessible(true); + Object val = field.get(criteria); + if("pidIsNull".equals(field.getName())){ + continue; + } + if (ObjectUtil.isNotNull(val)) { + criteria.setPidIsNull(null); + break; + } + } + } + return menuMapper.toDto(menuRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort)); + } + + @Override + @Cacheable(key = "'id:' + #p0") + public MenuDto findById(long id) { + Menu menu = menuRepository.findById(id).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Menu","id",id); + return menuMapper.toDto(menu); + } + + /** + * 用户角色改变时需清理缓存 + * @param currentUserId / + * @return / + */ + @Override + @Cacheable(key = "'user:' + #p0") + public List findByUser(Long currentUserId) { + List roles = roleService.findByUsersId(currentUserId); + Set roleIds = roles.stream().map(RoleSmallDto::getId).collect(Collectors.toSet()); + LinkedHashSet menus = menuRepository.findByRoleIdsAndTypeNot(roleIds, 2); + return menus.stream().map(menuMapper::toDto).collect(Collectors.toList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Menu resources) { + if(menuRepository.findByTitle(resources.getTitle()) != null){ + throw new EntityExistException(Menu.class,"title",resources.getTitle()); + } + if(StringUtils.isNotBlank(resources.getComponentName())){ + if(menuRepository.findByComponentName(resources.getComponentName()) != null){ + throw new EntityExistException(Menu.class,"componentName",resources.getComponentName()); + } + } + if(resources.getPid().equals(0L)){ + resources.setPid(null); + } + if(resources.getIFrame()){ + String http = "http://", https = "https://"; + if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) { + throw new BadRequestException("外链必须以http://或者https://开头"); + } + } + menuRepository.save(resources); + // 计算子节点数目 + resources.setSubCount(0); + // 更新父节点菜单数目 + updateSubCnt(resources.getPid()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Menu resources) { + if(resources.getId().equals(resources.getPid())) { + throw new BadRequestException("上级不能为自己"); + } + Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Permission","id",resources.getId()); + + if(resources.getIFrame()){ + String http = "http://", https = "https://"; + if (!(resources.getPath().toLowerCase().startsWith(http)||resources.getPath().toLowerCase().startsWith(https))) { + throw new BadRequestException("外链必须以http://或者https://开头"); + } + } + Menu menu1 = menuRepository.findByTitle(resources.getTitle()); + + if(menu1 != null && !menu1.getId().equals(menu.getId())){ + throw new EntityExistException(Menu.class,"title",resources.getTitle()); + } + + if(resources.getPid().equals(0L)){ + resources.setPid(null); + } + + // 记录的父节点ID + Long oldPid = menu.getPid(); + Long newPid = resources.getPid(); + + if(StringUtils.isNotBlank(resources.getComponentName())){ + menu1 = menuRepository.findByComponentName(resources.getComponentName()); + if(menu1 != null && !menu1.getId().equals(menu.getId())){ + throw new EntityExistException(Menu.class,"componentName",resources.getComponentName()); + } + } + menu.setTitle(resources.getTitle()); + menu.setComponent(resources.getComponent()); + menu.setPath(resources.getPath()); + menu.setIcon(resources.getIcon()); + menu.setIFrame(resources.getIFrame()); + menu.setPid(resources.getPid()); + menu.setMenuSort(resources.getMenuSort()); + menu.setCache(resources.getCache()); + menu.setHidden(resources.getHidden()); + menu.setComponentName(resources.getComponentName()); + menu.setPermission(resources.getPermission()); + menu.setType(resources.getType()); + menuRepository.save(menu); + // 计算父级菜单节点数目 + updateSubCnt(oldPid); + updateSubCnt(newPid); + // 清理缓存 + delCaches(resources.getId()); + } + + @Override + public Set getChildMenus(List menuList, Set menuSet) { + for (Menu menu : menuList) { + menuSet.add(menu); + List menus = menuRepository.findByPid(menu.getId()); + if(menus!=null && menus.size()!=0){ + getChildMenus(menus, menuSet); + } + } + return menuSet; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set menuSet) { + for (Menu menu : menuSet) { + // 清理缓存 + delCaches(menu.getId()); + roleService.untiedMenu(menu.getId()); + menuRepository.deleteById(menu.getId()); + updateSubCnt(menu.getPid()); + } + } + + @Override + public List getMenus(Long pid) { + List menus; + if(pid != null && !pid.equals(0L)){ + menus = menuRepository.findByPid(pid); + } else { + menus = menuRepository.findByPidIsNull(); + } + return menuMapper.toDto(menus); + } + + @Override + public List getSuperior(MenuDto menuDto, List menus) { + if(menuDto.getPid() == null){ + menus.addAll(menuRepository.findByPidIsNull()); + return menuMapper.toDto(menus); + } + menus.addAll(menuRepository.findByPid(menuDto.getPid())); + return getSuperior(findById(menuDto.getPid()), menus); + } + + @Override + public List buildTree(List menuDtos) { + List trees = new ArrayList<>(); + Set ids = new HashSet<>(); + for (MenuDto menuDTO : menuDtos) { + if (menuDTO.getPid() == null) { + trees.add(menuDTO); + } + for (MenuDto it : menuDtos) { + if (menuDTO.getId().equals(it.getPid())) { + if (menuDTO.getChildren() == null) { + menuDTO.setChildren(new ArrayList<>()); + } + menuDTO.getChildren().add(it); + ids.add(it.getId()); + } + } + } + if(trees.size() == 0){ + trees = menuDtos.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList()); + } + return trees; + } + + @Override + public List buildMenus(List menuDtos) { + List list = new LinkedList<>(); + menuDtos.forEach(menuDTO -> { + if (menuDTO!=null){ + List menuDtoList = menuDTO.getChildren(); + MenuVo menuVo = new MenuVo(); + menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : menuDTO.getTitle()); + // 一级目录需要加斜杠,不然会报警告 + menuVo.setPath(menuDTO.getPid() == null ? "/" + menuDTO.getPath() :menuDTO.getPath()); + menuVo.setHidden(menuDTO.getHidden()); + // 如果不是外链 + if(!menuDTO.getIFrame()){ + if(menuDTO.getPid() == null){ + menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"Layout":menuDTO.getComponent()); + // 如果不是一级菜单,并且菜单类型为目录,则代表是多级菜单 + }else if(menuDTO.getType() == 0){ + menuVo.setComponent(StringUtils.isEmpty(menuDTO.getComponent())?"ParentView":menuDTO.getComponent()); + }else if(StringUtils.isNoneBlank(menuDTO.getComponent())){ + menuVo.setComponent(menuDTO.getComponent()); + } + } + menuVo.setMeta(new MenuMetaVo(menuDTO.getTitle(),menuDTO.getIcon(),!menuDTO.getCache())); + if(CollectionUtil.isNotEmpty(menuDtoList)){ + menuVo.setAlwaysShow(true); + menuVo.setRedirect("noredirect"); + menuVo.setChildren(buildMenus(menuDtoList)); + // 处理是一级菜单并且没有子菜单的情况 + } else if(menuDTO.getPid() == null){ + MenuVo menuVo1 = new MenuVo(); + menuVo1.setMeta(menuVo.getMeta()); + // 非外链 + if(!menuDTO.getIFrame()){ + menuVo1.setPath("index"); + menuVo1.setName(menuVo.getName()); + menuVo1.setComponent(menuVo.getComponent()); + } else { + menuVo1.setPath(menuDTO.getPath()); + } + menuVo.setName(null); + menuVo.setMeta(null); + menuVo.setComponent("Layout"); + List list1 = new ArrayList<>(); + list1.add(menuVo1); + menuVo.setChildren(list1); + } + list.add(menuVo); + } + } + ); + return list; + } + + @Override + public Menu findOne(Long id) { + Menu menu = menuRepository.findById(id).orElseGet(Menu::new); + ValidationUtil.isNull(menu.getId(),"Menu","id",id); + return menu; + } + + @Override + public void download(List menuDtos, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (MenuDto menuDTO : menuDtos) { + Map map = new LinkedHashMap<>(); + map.put("菜单标题", menuDTO.getTitle()); + map.put("菜单类型", menuDTO.getType() == null ? "目录" : menuDTO.getType() == 1 ? "菜单" : "按钮"); + map.put("权限标识", menuDTO.getPermission()); + map.put("外链菜单", menuDTO.getIFrame() ? "是" : "否"); + map.put("菜单可见", menuDTO.getHidden() ? "否" : "是"); + map.put("是否缓存", menuDTO.getCache() ? "是" : "否"); + map.put("创建日期", menuDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + private void updateSubCnt(Long menuId){ + if(menuId != null){ + int count = menuRepository.countByPid(menuId); + menuRepository.updateSubCntById(count, menuId); + } + } + + /** + * 清理缓存 + * @param id 菜单ID + */ + public void delCaches(Long id){ + List users = userRepository.findByMenuId(id); + redisUtils.del(CacheKey.MENU_ID + id); + redisUtils.delByKeys(CacheKey.MENU_USER, users.stream().map(User::getId).collect(Collectors.toSet())); + // 清除 Role 缓存 + List roles = roleService.findInMenuId(new ArrayList(){{ + add(id); + }}); + redisUtils.delByKeys(CacheKey.ROLE_ID, roles.stream().map(Role::getId).collect(Collectors.toSet())); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/MonitorServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/MonitorServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..974b639051bef66411dda6b8dd3f7dcbc3fcd5f2 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/MonitorServiceImpl.java @@ -0,0 +1,193 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import cn.hutool.core.date.BetweenFormater; +import cn.hutool.core.date.DateUtil; +import xiong.copy.modules.system.service.MonitorService; +import xiong.copy.utils.ElAdminConstant; +import xiong.copy.utils.FileUtil; +import xiong.copy.utils.StringUtils; +import org.springframework.stereotype.Service; +import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.GlobalMemory; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.hardware.VirtualMemory; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; +import oshi.util.FormatUtil; +import oshi.util.Util; + +import java.lang.management.ManagementFactory; +import java.text.DecimalFormat; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** +* @author Zheng Jie +* @date 2020-05-02 +*/ +@Service +public class MonitorServiceImpl implements MonitorService { + + private final DecimalFormat df = new DecimalFormat("0.00"); + + @Override + public Map getServers(){ + Map resultMap = new LinkedHashMap<>(8); + try { + SystemInfo si = new SystemInfo(); + OperatingSystem os = si.getOperatingSystem(); + HardwareAbstractionLayer hal = si.getHardware(); + // 系统信息 + resultMap.put("sys", getSystemInfo(os)); + // cpu 信息 + resultMap.put("cpu", getCpuInfo(hal.getProcessor())); + // 内存信息 + resultMap.put("memory", getMemoryInfo(hal.getMemory())); + // 交换区信息 + resultMap.put("swap", getSwapInfo(hal.getMemory())); + // 磁盘 + resultMap.put("disk", getDiskInfo(os)); + resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss")); + } catch (Exception e) { + e.printStackTrace(); + } + return resultMap; + } + + /** + * 获取磁盘信息 + * @return / + */ + private Map getDiskInfo(OperatingSystem os) { + Map diskInfo = new LinkedHashMap<>(); + FileSystem fileSystem = os.getFileSystem(); + List fsArray = fileSystem.getFileStores(); + String osName = System.getProperty("os.name"); + long available = 0, total = 0; + for (OSFileStore fs : fsArray){ + // windows 需要将所有磁盘分区累加,linux 和 mac 直接累加会出现磁盘重复的问题,待修复 + if(osName.toLowerCase().startsWith(ElAdminConstant.WIN)) { + available += fs.getUsableSpace(); + total += fs.getTotalSpace(); + } else { + available = fs.getUsableSpace(); + total = fs.getTotalSpace(); + break; + } + } + long used = total - available; + diskInfo.put("total", total > 0 ? FileUtil.getSize(total) : "?"); + diskInfo.put("available", FileUtil.getSize(available)); + diskInfo.put("used", FileUtil.getSize(used)); + if(total != 0){ + diskInfo.put("usageRate", df.format(used/(double)total * 100)); + } else { + diskInfo.put("usageRate", 0); + } + return diskInfo; + } + + /** + * 获取交换区信息 + * @param memory / + * @return / + */ + private Map getSwapInfo(GlobalMemory memory) { + Map swapInfo = new LinkedHashMap<>(); + VirtualMemory virtualMemory = memory.getVirtualMemory(); + long total = virtualMemory.getSwapTotal(); + long used = virtualMemory.getSwapUsed(); + swapInfo.put("total", FormatUtil.formatBytes(total)); + swapInfo.put("used", FormatUtil.formatBytes(used)); + swapInfo.put("available", FormatUtil.formatBytes(total - used)); + if(used == 0){ + swapInfo.put("usageRate", 0); + } else { + swapInfo.put("usageRate", df.format(used/(double)total * 100)); + } + return swapInfo; + } + + /** + * 获取内存信息 + * @param memory / + * @return / + */ + private Map getMemoryInfo(GlobalMemory memory) { + Map memoryInfo = new LinkedHashMap<>(); + memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal())); + memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable())); + memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable())); + memoryInfo.put("usageRate", df.format((memory.getTotal() - memory.getAvailable())/(double)memory.getTotal() * 100)); + return memoryInfo; + } + + /** + * 获取Cpu相关信息 + * @param processor / + * @return / + */ + private Map getCpuInfo(CentralProcessor processor) { + Map cpuInfo = new LinkedHashMap<>(); + cpuInfo.put("name", processor.getProcessorIdentifier().getName()); + cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理CPU"); + cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心"); + cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount()); + cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU"); + // CPU信息 + long[] prevTicks = processor.getSystemCpuLoadTicks(); + // 等待1秒... + Util.sleep(1000); + long[] ticks = processor.getSystemCpuLoadTicks(); + long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()]; + long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()]; + long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()]; + long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()]; + long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()]; + long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()]; + long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()]; + long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()]; + long totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal; + cpuInfo.put("used", df.format(100d * user / totalCpu + 100d * sys / totalCpu)); + cpuInfo.put("idle", df.format(100d * idle / totalCpu)); + return cpuInfo; + } + + /** + * 获取系统相关信息,系统、运行天数、系统IP + * @param os / + * @return / + */ + private Map getSystemInfo(OperatingSystem os){ + Map systemInfo = new LinkedHashMap<>(); + // jvm 运行时间 + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + Date date = new Date(time); + // 计算项目运行时间 + String formatBetween = DateUtil.formatBetween(date, new Date(),BetweenFormater.Level.HOUR); + // 系统信息 + systemInfo.put("os", os.toString()); + systemInfo.put("day", formatBetween); + systemInfo.put("ip", StringUtils.getLocalIp()); + return systemInfo; + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/RoleServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..55002a48e80541c085b5772a0cd9d4334bea5861 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/RoleServiceImpl.java @@ -0,0 +1,226 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import lombok.RequiredArgsConstructor; +import xiong.copy.exception.BadRequestException; +import xiong.copy.exception.EntityExistException; +import xiong.copy.modules.security.service.UserCacheClean; +import xiong.copy.modules.system.domain.Menu; +import xiong.copy.modules.system.domain.Role; +import xiong.copy.modules.system.domain.User; +import xiong.copy.modules.system.repository.RoleRepository; +import xiong.copy.modules.system.repository.UserRepository; +import xiong.copy.modules.system.service.RoleService; +import xiong.copy.modules.system.service.dto.RoleDto; +import xiong.copy.modules.system.service.dto.RoleQueryCriteria; +import xiong.copy.modules.system.service.dto.RoleSmallDto; +import xiong.copy.modules.system.service.dto.UserDto; +import xiong.copy.modules.system.service.mapstruct.RoleMapper; +import xiong.copy.modules.system.service.mapstruct.RoleSmallMapper; +import xiong.copy.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-12-03 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "role") +public class RoleServiceImpl implements RoleService { + + private final RoleRepository roleRepository; + private final RoleMapper roleMapper; + private final RoleSmallMapper roleSmallMapper; + private final RedisUtils redisUtils; + private final UserRepository userRepository; + private final UserCacheClean userCacheClean; + + @Override + public List queryAll() { + Sort sort = Sort.by(Sort.Direction.ASC, "level"); + return roleMapper.toDto(roleRepository.findAll(sort)); + } + + @Override + public List queryAll(RoleQueryCriteria criteria) { + return roleMapper.toDto(roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))); + } + + @Override + public Object queryAll(RoleQueryCriteria criteria, Pageable pageable) { + Page page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(roleMapper::toDto)); + } + + @Override + @Cacheable(key = "'id:' + #p0") + @Transactional(rollbackFor = Exception.class) + public RoleDto findById(long id) { + Role role = roleRepository.findById(id).orElseGet(Role::new); + ValidationUtil.isNull(role.getId(), "Role", "id", id); + return roleMapper.toDto(role); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(Role resources) { + if (roleRepository.findByName(resources.getName()) != null) { + throw new EntityExistException(Role.class, "username", resources.getName()); + } + roleRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Role resources) { + Role role = roleRepository.findById(resources.getId()).orElseGet(Role::new); + ValidationUtil.isNull(role.getId(), "Role", "id", resources.getId()); + + Role role1 = roleRepository.findByName(resources.getName()); + + if (role1 != null && !role1.getId().equals(role.getId())) { + throw new EntityExistException(Role.class, "username", resources.getName()); + } + role.setName(resources.getName()); + role.setDescription(resources.getDescription()); + role.setDataScope(resources.getDataScope()); + role.setDepts(resources.getDepts()); + role.setLevel(resources.getLevel()); + roleRepository.save(role); + // 更新相关缓存 + delCaches(role.getId(), null); + } + + @Override + public void updateMenu(Role resources, RoleDto roleDTO) { + Role role = roleMapper.toEntity(roleDTO); + List users = userRepository.findByRoleId(role.getId()); + // 更新菜单 + role.setMenus(resources.getMenus()); + delCaches(resources.getId(), users); + roleRepository.save(role); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void untiedMenu(Long menuId) { + // 更新菜单 + roleRepository.untiedMenu(menuId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + // 更新相关缓存 + delCaches(id, null); + } + roleRepository.deleteAllByIdIn(ids); + } + + @Override + public List findByUsersId(Long id) { + return roleSmallMapper.toDto(new ArrayList<>(roleRepository.findByUserId(id))); + } + + @Override + public Integer findByRoles(Set roles) { + if (roles.size() == 0) { + return Integer.MAX_VALUE; + } + Set roleDtos = new HashSet<>(); + for (Role role : roles) { + roleDtos.add(findById(role.getId())); + } + return Collections.min(roleDtos.stream().map(RoleDto::getLevel).collect(Collectors.toList())); + } + + @Override + @Cacheable(key = "'auth:' + #p0.id") + public List mapToGrantedAuthorities(UserDto user) { + Set permissions = new HashSet<>(); + // 如果是管理员直接返回 + if (user.getIsAdmin()) { + permissions.add("admin"); + return permissions.stream().map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + } + Set roles = roleRepository.findByUserId(user.getId()); + permissions = roles.stream().flatMap(role -> role.getMenus().stream()) + .filter(menu -> StringUtils.isNotBlank(menu.getPermission())) + .map(Menu::getPermission).collect(Collectors.toSet()); + return permissions.stream().map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + } + + @Override + public void download(List roles, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (RoleDto role : roles) { + Map map = new LinkedHashMap<>(); + map.put("角色名称", role.getName()); + map.put("角色级别", role.getLevel()); + map.put("描述", role.getDescription()); + map.put("创建日期", role.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public void verification(Set ids) { + if (userRepository.countByRoles(ids) > 0) { + throw new BadRequestException("所选角色存在用户关联,请解除关联再试!"); + } + } + + @Override + public List findInMenuId(List menuIds) { + return roleRepository.findInMenuId(menuIds); + } + + /** + * 清理缓存 + * @param id / + */ + public void delCaches(Long id, List users) { + users = CollectionUtil.isEmpty(users) ? userRepository.findByRoleId(id) : users; + if (CollectionUtil.isNotEmpty(users)) { + users.forEach(item -> userCacheClean.cleanUserCache(item.getUsername())); + Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); + redisUtils.delByKeys(CacheKey.DATA_USER, userIds); + redisUtils.delByKeys(CacheKey.MENU_USER, userIds); + redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds); + } + redisUtils.del(CacheKey.ROLE_ID + id); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/UserServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/UserServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..fd60bfa344ae088c6ecf26ea3bf9713ee311d56e --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/UserServiceImpl.java @@ -0,0 +1,258 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.impl; + +import lombok.RequiredArgsConstructor; +import xiong.copy.config.FileProperties; +import xiong.copy.exception.BadRequestException; +import xiong.copy.exception.EntityExistException; +import xiong.copy.exception.EntityNotFoundException; +import xiong.copy.modules.security.service.OnlineUserService; +import xiong.copy.modules.security.service.UserCacheClean; +import xiong.copy.modules.system.domain.User; +import xiong.copy.modules.system.repository.UserRepository; +import xiong.copy.modules.system.service.UserService; +import xiong.copy.modules.system.service.dto.JobSmallDto; +import xiong.copy.modules.system.service.dto.RoleSmallDto; +import xiong.copy.modules.system.service.dto.UserDto; +import xiong.copy.modules.system.service.dto.UserQueryCriteria; +import xiong.copy.modules.system.service.mapstruct.UserMapper; +import xiong.copy.utils.*; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotBlank; +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Service +@RequiredArgsConstructor +@CacheConfig(cacheNames = "user") +public class UserServiceImpl implements UserService { + + private final UserRepository userRepository; + private final UserMapper userMapper; + private final FileProperties properties; + private final RedisUtils redisUtils; + private final UserCacheClean userCacheClean; + private final OnlineUserService onlineUserService; + + @Override + public Object queryAll(UserQueryCriteria criteria, Pageable pageable) { + Page page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(userMapper::toDto)); + } + + @Override + public List queryAll(UserQueryCriteria criteria) { + List users = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)); + return userMapper.toDto(users); + } + + @Override + @Cacheable(key = "'id:' + #p0") + @Transactional(rollbackFor = Exception.class) + public UserDto findById(long id) { + User user = userRepository.findById(id).orElseGet(User::new); + ValidationUtil.isNull(user.getId(), "User", "id", id); + return userMapper.toDto(user); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(User resources) { + if (userRepository.findByUsername(resources.getUsername()) != null) { + throw new EntityExistException(User.class, "username", resources.getUsername()); + } + if (userRepository.findByEmail(resources.getEmail()) != null) { + throw new EntityExistException(User.class, "email", resources.getEmail()); + } + if (userRepository.findByPhone(resources.getPhone()) != null) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + userRepository.save(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(User resources) throws Exception { + User user = userRepository.findById(resources.getId()).orElseGet(User::new); + ValidationUtil.isNull(user.getId(), "User", "id", resources.getId()); + User user1 = userRepository.findByUsername(resources.getUsername()); + User user2 = userRepository.findByEmail(resources.getEmail()); + User user3 = userRepository.findByPhone(resources.getPhone()); + if (user1 != null && !user.getId().equals(user1.getId())) { + throw new EntityExistException(User.class, "username", resources.getUsername()); + } + if (user2 != null && !user.getId().equals(user2.getId())) { + throw new EntityExistException(User.class, "email", resources.getEmail()); + } + if (user3 != null && !user.getId().equals(user3.getId())) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + // 如果用户的角色改变 + if (!resources.getRoles().equals(user.getRoles())) { + redisUtils.del(CacheKey.DATA_USER + resources.getId()); + redisUtils.del(CacheKey.MENU_USER + resources.getId()); + redisUtils.del(CacheKey.ROLE_AUTH + resources.getId()); + } + // 如果用户被禁用,则清除用户登录信息 + if(!resources.getEnabled()){ + onlineUserService.kickOutForUsername(resources.getUsername()); + } + user.setUsername(resources.getUsername()); + user.setEmail(resources.getEmail()); + user.setEnabled(resources.getEnabled()); + user.setRoles(resources.getRoles()); + user.setDept(resources.getDept()); + user.setJobs(resources.getJobs()); + user.setPhone(resources.getPhone()); + user.setNickName(resources.getNickName()); + user.setGender(resources.getGender()); + userRepository.save(user); + // 清除缓存 + delCaches(user.getId(), user.getUsername()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateCenter(User resources) { + User user = userRepository.findById(resources.getId()).orElseGet(User::new); + User user1 = userRepository.findByPhone(resources.getPhone()); + if (user1 != null && !user.getId().equals(user1.getId())) { + throw new EntityExistException(User.class, "phone", resources.getPhone()); + } + user.setNickName(resources.getNickName()); + user.setPhone(resources.getPhone()); + user.setGender(resources.getGender()); + userRepository.save(user); + // 清理缓存 + delCaches(user.getId(), user.getUsername()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Set ids) { + for (Long id : ids) { + // 清理缓存 + UserDto user = findById(id); + delCaches(user.getId(), user.getUsername()); + } + userRepository.deleteAllByIdIn(ids); + } + + @Override + public UserDto findByName(String userName) { + User user = userRepository.findByUsername(userName); + if (user == null) { + throw new EntityNotFoundException(User.class, "name", userName); + } else { + return userMapper.toDto(user); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePass(String username, String pass) { + userRepository.updatePass(username, pass, new Date()); + flushCache(username); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Map updateAvatar(MultipartFile multipartFile) { + // 文件大小验证 + FileUtil.checkSize(properties.getAvatarMaxSize(), multipartFile.getSize()); + // 验证文件上传的格式 + String image = "gif jpg png jpeg"; + String fileType = FileUtil.getExtensionName(multipartFile.getOriginalFilename()); + if(fileType != null && !image.contains(fileType)){ + throw new BadRequestException("文件格式错误!, 仅支持 " + image +" 格式"); + } + User user = userRepository.findByUsername(SecurityUtils.getCurrentUsername()); + String oldPath = user.getAvatarPath(); + File file = FileUtil.upload(multipartFile, properties.getPath().getAvatar()); + user.setAvatarPath(Objects.requireNonNull(file).getPath()); + user.setAvatarName(file.getName()); + userRepository.save(user); + if (StringUtils.isNotBlank(oldPath)) { + FileUtil.del(oldPath); + } + @NotBlank String username = user.getUsername(); + flushCache(username); + return new HashMap(1) {{ + put("avatar", file.getName()); + }}; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateEmail(String username, String email) { + userRepository.updateEmail(username, email); + flushCache(username); + } + + @Override + public void download(List queryAll, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (UserDto userDTO : queryAll) { + List roles = userDTO.getRoles().stream().map(RoleSmallDto::getName).collect(Collectors.toList()); + Map map = new LinkedHashMap<>(); + map.put("用户名", userDTO.getUsername()); + map.put("角色", roles); + map.put("部门", userDTO.getDept().getName()); + map.put("岗位", userDTO.getJobs().stream().map(JobSmallDto::getName).collect(Collectors.toList())); + map.put("邮箱", userDTO.getEmail()); + map.put("状态", userDTO.getEnabled() ? "启用" : "禁用"); + map.put("手机号码", userDTO.getPhone()); + map.put("修改密码的时间", userDTO.getPwdResetTime()); + map.put("创建日期", userDTO.getCreateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + /** + * 清理缓存 + * + * @param id / + */ + public void delCaches(Long id, String username) { + redisUtils.del(CacheKey.USER_ID + id); + flushCache(username); + } + + /** + * 清理 登陆时 用户缓存信息 + * + * @param username / + */ + private void flushCache(String username) { + userCacheClean.cleanUserCache(username); + } +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/VerifyServiceImpl.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/VerifyServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..0b45cd5ba54989252dbe5c009cfca22e2203ed63 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/impl/VerifyServiceImpl.java @@ -0,0 +1,82 @@ +///* +// * Copyright 2019-2020 Zheng Jie +// * +// * Licensed 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. +// */ +//package xiong.copy.modules.system.service.impl; +// +//import cn.hutool.core.lang.Dict; +//import cn.hutool.core.util.RandomUtil; +//import cn.hutool.extra.template.Template; +//import cn.hutool.extra.template.TemplateConfig; +//import cn.hutool.extra.template.TemplateEngine; +//import cn.hutool.extra.template.TemplateUtil; +//import lombok.RequiredArgsConstructor; +//import xiong.copy.domain.vo.EmailVo; +//import xiong.copy.exception.BadRequestException; +//import xiong.copy.modules.system.service.VerifyService; +//import xiong.copy.utils.RedisUtils; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.stereotype.Service; +//import org.springframework.transaction.annotation.Transactional; +// +//import java.util.Collections; +// +///** +// * @author Zheng Jie +// * @date 2018-12-26 +// */ +//@Service +//@RequiredArgsConstructor +//public class VerifyServiceImpl implements VerifyService { +// +// @Value("${code.expiration}") +// private Long expiration; +// private final RedisUtils redisUtils; +// +// @Override +// @Transactional(rollbackFor = Exception.class) +// public EmailVo sendEmail(String email, String key) { +// EmailVo emailVo; +// String content; +// String redisKey = key + email; +// // 如果不存在有效的验证码,就创建一个新的 +// TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); +// Template template = engine.getTemplate("email/email.ftl"); +// Object oldCode = redisUtils.get(redisKey); +// if(oldCode == null){ +// String code = RandomUtil.randomNumbers (6); +// // 存入缓存 +// if(!redisUtils.set(redisKey, code, expiration)){ +// throw new BadRequestException("服务异常,请联系网站负责人"); +// } +// content = template.render(Dict.create().set("code",code)); +// emailVo = new EmailVo(Collections.singletonList(email),"EL-ADMIN后台管理系统",content); +// // 存在就再次发送原来的验证码 +// } else { +// content = template.render(Dict.create().set("code",oldCode)); +// emailVo = new EmailVo(Collections.singletonList(email),"EL-ADMIN后台管理系统",content); +// } +// return emailVo; +// } +// +// @Override +// public void validated(String key, String code) { +// Object value = redisUtils.get(key); +// if(value == null || !value.toString().equals(code)){ +// throw new BadRequestException("无效验证码"); +// } else { +// redisUtils.del(key); +// } +// } +//} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DeptMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DeptMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..5706491e72327da7f947695d71ce793184490162 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DeptMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Dept; +import xiong.copy.modules.system.service.dto.DeptDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeptMapper extends BaseMapper { +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DeptSmallMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DeptSmallMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..9cdb548501bd601c44420c09cf2ec4ab8c718b2b --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DeptSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Dept; +import xiong.copy.modules.system.service.dto.DeptSmallDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-03-25 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeptSmallMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictDetailMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictDetailMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..48829d57fd692819ccbd616764c0cdcb0d728441 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictDetailMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.DictDetail; +import xiong.copy.modules.system.service.dto.DictDetailDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Mapper(componentModel = "spring", uses = {DictSmallMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictDetailMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..2aee5180a3a2d7eef0529b706aebe842d70ce804 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Dict; +import xiong.copy.modules.system.service.dto.DictDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictSmallMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictSmallMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..452a23c9b9ced71e0f58c8658b9cd49d9a2a5933 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/DictSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Dict; +import xiong.copy.modules.system.service.dto.DictSmallDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-04-10 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DictSmallMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/JobMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/JobMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..d42f1602abd1cfdc0b48dcc09ed866ff216eaa3c --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/JobMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Job; +import xiong.copy.modules.system.service.dto.JobDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Mapper(componentModel = "spring",uses = {DeptMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JobMapper extends BaseMapper { +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/JobSmallMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/JobSmallMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..e2130cb6038897c5d998d7e655a5e95fed112f83 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/JobSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Job; +import xiong.copy.modules.system.service.dto.JobSmallDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author Zheng Jie +* @date 2019-03-29 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JobSmallMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/MenuMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/MenuMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..6bad3b21ba23a892294444c75b478c7a68d46866 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/MenuMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Menu; +import xiong.copy.modules.system.service.dto.MenuDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2018-12-17 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface MenuMapper extends BaseMapper { +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/RoleMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/RoleMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..a8c4ad5ad1a2dc54a5203ed25d134370e0d89eed --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/RoleMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Role; +import xiong.copy.modules.system.service.dto.RoleDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Mapper(componentModel = "spring", uses = {MenuMapper.class, DeptMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface RoleMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/RoleSmallMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/RoleSmallMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..ac035b86d810f6c47d50b3fd8c60acc610614fbd --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/RoleSmallMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.Role; +import xiong.copy.modules.system.service.dto.RoleSmallDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2019-5-23 + */ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface RoleSmallMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/UserMapper.java b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/UserMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..70a8dd274be66bdc9dbf5106994477de4973d020 --- /dev/null +++ b/eladmin-system/src/main/java/xiong/copy/modules/system/service/mapstruct/UserMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed 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. + */ +package xiong.copy.modules.system.service.mapstruct; + +import xiong.copy.base.BaseMapper; +import xiong.copy.modules.system.domain.User; +import xiong.copy.modules.system.service.dto.UserDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Zheng Jie + * @date 2018-11-23 + */ +@Mapper(componentModel = "spring",uses = {RoleMapper.class, DeptMapper.class, JobMapper.class},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface UserMapper extends BaseMapper { +} diff --git a/eladmin-system/src/main/resources/config/application-dev.yml b/eladmin-system/src/main/resources/config/application-dev.yml index 267740b5fff2d3b7d7208638858f31e23705a055..bd5fdab85d086fa36bb264f22e4b186567673e3b 100644 --- a/eladmin-system/src/main/resources/config/application-dev.yml +++ b/eladmin-system/src/main/resources/config/application-dev.yml @@ -13,10 +13,8 @@ spring: min-idle: 15 # 最大连接数 max-active: 30 - # 超时时间(以秒数为单位) - remove-abandoned-timeout: 180 # 获取连接超时时间 - max-wait: 3000 + max-wait: 5000 # 连接有效性检测时间 time-between-eviction-runs-millis: 60000 # 连接在池中最小生存的时间 @@ -36,8 +34,11 @@ spring: enabled: true stat-view-servlet: enabled: true + # 控制台管理用户名和密码 url-pattern: /druid/* reset-enable: false + login-username: admin + login-password: 123456 filter: stat: enabled: true @@ -67,41 +68,48 @@ login: height: 36 # 内容长度 length: 2 - # 字体名称,为空则使用默认字体 + # 字体名称,为空则使用默认字体,如遇到线上乱码,设置其他字体即可 font-name: # 字体大小 font-size: 25 -##jwt +#jwt jwt: header: Authorization # 令牌前缀 token-start-with: Bearer # 必须使用最少88位的Base64对该令牌进行编码 base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= - # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html - token-validity-in-seconds: 14400000 + # 令牌过期时间 此处单位/毫秒 ,默认2小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 7200000 # 在线用户key online-key: online-token- # 验证码 code-key: code-key- - # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + # token 续期检查时间范围(默认30分钟,单位默认毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 detect: 1800000 - # 续期时间范围,默认1小时,单位毫秒 + # 续期时间范围,默认 1小时,这里单位毫秒 renew: 3600000 +# IP 本地解析 +ip: + local-parsing: false + #是否允许生成代码,生产环境设置为false generator: enabled: true +#如果生产环境要开启swagger,需要配置请求地址 +#springfox: +# documentation: +# swagger: +# v2: +# host: # 接口域名或外网ip + #是否开启 swagger-ui swagger: enabled: true -# IP 本地解析 -ip: - local-parsing: true - # 文件存储路径 file: mac: diff --git a/eladmin-system/src/main/resources/config/application-prod.yml b/eladmin-system/src/main/resources/config/application-prod.yml index a3066edece0ff539fbd22e22a1650fbe3e388d27..bd5fdab85d086fa36bb264f22e4b186567673e3b 100644 --- a/eladmin-system/src/main/resources/config/application-prod.yml +++ b/eladmin-system/src/main/resources/config/application-prod.yml @@ -97,7 +97,7 @@ ip: #是否允许生成代码,生产环境设置为false generator: - enabled: false + enabled: true #如果生产环境要开启swagger,需要配置请求地址 #springfox: @@ -108,7 +108,7 @@ generator: #是否开启 swagger-ui swagger: - enabled: false + enabled: true # 文件存储路径 file: diff --git a/eladmin-system/src/main/resources/config/application.yml b/eladmin-system/src/main/resources/config/application.yml index a798f45902eb0b2816071d0488b9e1d88a3f2542..10244e305d2b0d4afa4863cedad3e1dbfc64393f 100644 --- a/eladmin-system/src/main/resources/config/application.yml +++ b/eladmin-system/src/main/resources/config/application.yml @@ -29,8 +29,6 @@ spring: port: ${REDIS_PORT:6379} password: ${REDIS_PWD:} timeout: 5000 - #连接超时时间 - @@ -48,10 +46,10 @@ task: # 队列容量 queue-capacity: 50 -#七牛云 -qiniu: - # 文件大小 /M - max-size: 15 +##七牛云 +#qiniu: +# # 文件大小 /M +# max-size: 15 #邮箱验证码有效时间/秒 code: diff --git a/eladmin-tools/eladmin-tools.iml b/eladmin-tools/eladmin-tools.iml index 4d5f4a630916eb78a7a7fbfa665618a355cde57b..77ff417c96bfc0f2cae80471bb6d0954bf50ab7e 100644 --- a/eladmin-tools/eladmin-tools.iml +++ b/eladmin-tools/eladmin-tools.iml @@ -22,123 +22,114 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + - - - - - + + - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -147,21 +138,39 @@ + - - - + + + + + + + + + + + + + + + + + + + + + + - - \ No newline at end of file diff --git a/learnEladmin.iml b/learnEladmin.iml index f3a7881636ce7481accf5a590057160586e9b20a..e83f14eade185d18a588e2cd216741f9affea585 100644 --- a/learnEladmin.iml +++ b/learnEladmin.iml @@ -8,123 +8,115 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + - - - - - + + - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -133,21 +125,39 @@ + - - - + + + + + + + + + + + + + + + + + + + + + + - - \ No newline at end of file diff --git a/lib/javax.annotation.jar b/lib/javax.annotation.jar new file mode 100644 index 0000000000000000000000000000000000000000..52dca7f561c5d579ca764cb25b96d3f539cf242a Binary files /dev/null and b/lib/javax.annotation.jar differ diff --git a/lib/javax.ejb.jar b/lib/javax.ejb.jar new file mode 100644 index 0000000000000000000000000000000000000000..4ebf5ecd4c9ab83540ef206f6c5a1906db008098 Binary files /dev/null and b/lib/javax.ejb.jar differ diff --git a/lib/javax.jms.jar b/lib/javax.jms.jar new file mode 100644 index 0000000000000000000000000000000000000000..d31451ada1ad9a4471d9bae383df647c9b4b5235 Binary files /dev/null and b/lib/javax.jms.jar differ diff --git a/lib/javax.persistence.jar b/lib/javax.persistence.jar new file mode 100644 index 0000000000000000000000000000000000000000..21d80e0ed3b5e20aa787087247a006398cda7679 Binary files /dev/null and b/lib/javax.persistence.jar differ diff --git a/lib/javax.resource.jar b/lib/javax.resource.jar new file mode 100644 index 0000000000000000000000000000000000000000..696a2345878907025784d2e6e49c6e6b41d1cfac Binary files /dev/null and b/lib/javax.resource.jar differ diff --git a/lib/javax.servlet.jar b/lib/javax.servlet.jar new file mode 100644 index 0000000000000000000000000000000000000000..0519e4a4e16c207f18527175c6a4425b2b1bacbd Binary files /dev/null and b/lib/javax.servlet.jar differ diff --git a/lib/javax.servlet.jsp.jar b/lib/javax.servlet.jsp.jar new file mode 100644 index 0000000000000000000000000000000000000000..9c0631cea0fd56031db19fc3edbb4db4bfbb923a Binary files /dev/null and b/lib/javax.servlet.jsp.jar differ diff --git a/lib/javax.servlet.jsp.jstl.jar b/lib/javax.servlet.jsp.jstl.jar new file mode 100644 index 0000000000000000000000000000000000000000..7be17cc742fde5e957696dd98f6d0cf6520ed294 Binary files /dev/null and b/lib/javax.servlet.jsp.jstl.jar differ diff --git a/lib/javax.transaction.jar b/lib/javax.transaction.jar new file mode 100644 index 0000000000000000000000000000000000000000..729c6952389cd4769d5d840b3d1a7941b3c0f63e Binary files /dev/null and b/lib/javax.transaction.jar differ diff --git a/pom.xml b/pom.xml index 7e2ac04502b5315902b6ceac042cffc571e83550..e514e7009072a6aee444fce3b52817bb7cfe1b08 100644 --- a/pom.xml +++ b/pom.xml @@ -20,8 +20,9 @@ org.springframework.boot spring-boot-starter-parent - 2.4.0 - + + 2.2.10.RELEASE + @@ -39,108 +40,60 @@ 1.3.1.Final - - - - - - - - org.mapstruct - mapstruct - ${mapstruct.version} - - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - provided - - - javax.inject - javax.inject - 1 - - - - - - org.bgee.log4jdbc-log4j2 - log4jdbc-log4j2-jdbc4.1 - ${log4jdbc.version} - - - - - mysql - mysql-connector-java - runtime - - + - org.springframework.security.oauth - spring-security-oauth2 - 2.3.4.RELEASE - provided + org.springframework.boot + spring-boot-starter-data-jpa - + org.springframework.boot spring-boot-starter-web + org.springframework.boot - spring-boot-starter-validation - 2.2.10.RELEASE - compile - - - tomcat-embed-el - org.apache.tomcat.embed - - - - - com.alibaba - druid-spring-boot-starter - ${druid.version} + spring-boot-starter-test + test - - org.projectlombok - lombok - true - + org.springframework.boot - spring-boot-starter-test - test + spring-boot-starter-security + org.springframework.boot - spring-boot-starter-data-jpa + spring-boot-starter-cache + org.springframework.boot spring-boot-starter-data-redis - - + - org.springframework.boot - spring-boot-starter-cache + org.apache.commons + commons-pool2 + ${commons-pool2.version} + + + org.apache.commons + commons-lang3 + - org.lionsoul - ip2region - 1.7.2 + org.bgee.log4jdbc-log4j2 + log4jdbc-log4j2-jdbc4.1 + ${log4jdbc.version} @@ -175,30 +128,47 @@ 1.5.21 - + - org.springframework.boot - spring-boot-starter-data-redis + mysql + mysql-connector-java + runtime - - + - org.apache.commons - commons-pool2 - ${commons-pool2.version} + com.alibaba + druid-spring-boot-starter + ${druid.version} - org.apache.commons - commons-lang3 + org.lionsoul + ip2region + 1.7.2 + + + org.projectlombok + lombok + true + - + - nl.basjes.parse.useragent - yauaa - 5.23 + org.apache.poi + poi + 3.17 + + + org.apache.poi + poi-ooxml + 3.17 + + + xerces + xercesImpl + 2.12.0 @@ -208,6 +178,37 @@ ${fastjson.version} + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + provided + + + javax.inject + javax.inject + 1 + + + + + com.github.whvcse + easy-captcha + 1.6.2 + + + + + nl.basjes.parse.useragent + yauaa + 5.23 + @@ -220,30 +221,264 @@ true - - - org.springframework.boot - spring-boot-maven-plugin - 1.3.0.RELEASE - - xiong.copy.EladminSystemApplication - ZIP - - - - - repackage - - - - - - - - + + + public + aliyun nexus + http://maven.aliyun.com/nexus/content/groups/public/ + + true + + + + + + + public + aliyun nexus + http://maven.aliyun.com/nexus/content/groups/public/ + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +