mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
Compare commits
1461 Commits
v3.4.3
...
springboot
| Author | SHA1 | Date | |
|---|---|---|---|
| a1486dae34 | |||
| 7d3ba49a66 | |||
| 7ba2527c67 | |||
| 526734c5a5 | |||
| 44b48ad916 | |||
| 1a3ae4f61c | |||
| 859c509f08 | |||
| 0704f187af | |||
| 199d2b439e | |||
| 5f898ed034 | |||
| 5a9cb05c86 | |||
| 98936680d5 | |||
| fc043fd5f3 | |||
| 54531002a7 | |||
| 728a95c00d | |||
| 13c9951c1f | |||
| 8dfaa3c3e1 | |||
| 050c478dce | |||
| 2688e8b6e2 | |||
| a9f30f0ca5 | |||
| 1bf4a0595a | |||
| 74cd57fd99 | |||
| c9ac4c9945 | |||
| 3b3371ee1a | |||
| 1d3bde9fe7 | |||
| 90b50a51a7 | |||
| 668ac59a5c | |||
| 5f01bdd29b | |||
| 82bfcc7b14 | |||
| ef210a2242 | |||
| 435445cb4e | |||
| fdf7cd1f6b | |||
| 92a38f41b0 | |||
| 7ed3bcc912 | |||
| 2706c0a519 | |||
| f4b80365a9 | |||
| 1108aa5288 | |||
| 9919ae2bc5 | |||
| 1f73837b7d | |||
| 9571e0b169 | |||
| 1a923596db | |||
| 62549e0a1c | |||
| 2740a2f419 | |||
| 899264250c | |||
| 0be7d00eb2 | |||
| d988a637b2 | |||
| 7152ae9e49 | |||
| 58b41db786 | |||
| 33cbc6e25b | |||
| d715c7a0ac | |||
| aca407e1ce | |||
| cfea79a187 | |||
| 7848d1fb33 | |||
| 91fa645878 | |||
| 5bcb649384 | |||
| c9fc948658 | |||
| b97d041e7f | |||
| 6492f2c99a | |||
| bf32385a06 | |||
| 6ef637c46f | |||
| bc6f336745 | |||
| 0d86df8e9e | |||
| 3db673b67d | |||
| 3ba5395d33 | |||
| e7eed37470 | |||
| 30ac3f7c72 | |||
| 03e6c97d80 | |||
| b9f6f6dc53 | |||
| 107e13c8af | |||
| 0512b41b2b | |||
| d6d880f887 | |||
| d02753ce50 | |||
| b0e974a418 | |||
| 388fa9b8c2 | |||
| bc04bd1433 | |||
| 35aba0784d | |||
| c3822ab702 | |||
| d4487356f0 | |||
| 0bfe5689cc | |||
| ae4363dc72 | |||
| 3e6c7651ee | |||
| c0ffd14b7a | |||
| 914875d6a1 | |||
| aa55c3a86c | |||
| 2298ee3eed | |||
| 2a8853b353 | |||
| b920c5b794 | |||
| d3fa38a9e6 | |||
| b0df78b06c | |||
| 6a6d29254b | |||
| 80749098bd | |||
| 19b7f2cb29 | |||
| 39f5c3a5be | |||
| 9ee3a36fbb | |||
| 8c5cf3a0d9 | |||
| 053552c123 | |||
| fc44deca83 | |||
| 5d5d9fc53d | |||
| 002bfe25f8 | |||
| 7cb2dc4fde | |||
| 9c244bd266 | |||
| ab151879b3 | |||
| 000ae1db30 | |||
| 63e066180d | |||
| 44c1079f87 | |||
| e825e0f912 | |||
| 132e89b0e1 | |||
| 881a637285 | |||
| 02e9f8984f | |||
| a4343fc2cb | |||
| 152e8c7aaa | |||
| d7dc81455d | |||
| aefdcd6315 | |||
| 1cf4054e76 | |||
| 7829cf18d7 | |||
| 69c3a9da9a | |||
| 4d34150479 | |||
| 29687c8908 | |||
| 2e93a92dde | |||
| d383f7458d | |||
| 700318e1c1 | |||
| d728d6b090 | |||
| 7abc2e4c9c | |||
| da2b0cc354 | |||
| a6751c22be | |||
| f087525a75 | |||
| 4f46213df6 | |||
| d76842ae07 | |||
| 8c64db46e5 | |||
| 81fb2ac3b2 | |||
| fa98817aeb | |||
| 1158977826 | |||
| 8b6def0ee3 | |||
| 39c0d5b3f5 | |||
| adeebee840 | |||
| 862aaa8632 | |||
| 6a11ff8a64 | |||
| 73059b8a53 | |||
| e377bf6990 | |||
| 434b42e9ed | |||
| f1ceb08e16 | |||
| d2eedacc85 | |||
| 8791384791 | |||
| fd60e49f5b | |||
| 5f1dc06067 | |||
| b67770ff14 | |||
| 1dae808cf1 | |||
| 70d8353219 | |||
| 208d9990ae | |||
| 3e208de18e | |||
| 4f3c71af5b | |||
| c4a87d7c58 | |||
| 70bd639206 | |||
| d245ef3037 | |||
| 7af8346b79 | |||
| 1b8a31f0d3 | |||
| 294ad5a6c9 | |||
| 065b255d90 | |||
| 56976e68b4 | |||
| db1ff0268b | |||
| b7519d7199 | |||
| 81ba07c853 | |||
| 92ed296e63 | |||
| c2aff84914 | |||
| e002cd3bf3 | |||
| 1de07ff3ff | |||
| 35852d41f1 | |||
| a2cb1d9f25 | |||
| 2002af54d0 | |||
| 89747403a2 | |||
| 3db0995c3f | |||
| 950621dd88 | |||
| 033cf51d69 | |||
| fb9f367517 | |||
| b2da45d803 | |||
| 2840f0d325 | |||
| 6ace7eae8a | |||
| 3d88147c59 | |||
| 47107a53c2 | |||
| 08f245bdf9 | |||
| 52cd43d17c | |||
| 8cc033b86f | |||
| 7ff70930ef | |||
| 45f83dff43 | |||
| 6b7542620b | |||
| ba0052d452 | |||
| 69fca254f0 | |||
| b3de596199 | |||
| f46273d15e | |||
| 0fe258dbc2 | |||
| de7f23c555 | |||
| fcbaed2f7f | |||
| 67d9865861 | |||
| d97e56b2f0 | |||
| c868496b78 | |||
| c5150baa69 | |||
| 3d9f59c69b | |||
| 420d6db3fb | |||
| 473a626039 | |||
| 0308b0597c | |||
| 4acd5b3464 | |||
| cd809a6573 | |||
| 2191f5d48c | |||
| 1158b0b6e7 | |||
| ead2cef1f4 | |||
| 83bb0a0a6a | |||
| b474e9e5a5 | |||
| 422373e300 | |||
| 1cf11a4c2a | |||
| e10df20e98 | |||
| ac446691c4 | |||
| 925f163784 | |||
| d0f85ccc7e | |||
| 0feb307e8d | |||
| 781d61e96e | |||
| d01c1d7d47 | |||
| 3576b54945 | |||
| a760f94b94 | |||
| d12fe9d8de | |||
| 223d374edd | |||
| e795e03365 | |||
| 342bdd2e38 | |||
| 7f011f199e | |||
| 873b8bd823 | |||
| 59ece16059 | |||
| 91208a4968 | |||
| 419e2bea0b | |||
| 443abc3ede | |||
| 358e46559f | |||
| 2f3aff9584 | |||
| 1f74cb538f | |||
| 128c2c97f6 | |||
| 424dc33bba | |||
| 2cce917ab2 | |||
| 1cb48b4f0c | |||
| ea59454f51 | |||
| 615a1bc4ff | |||
| d976f12c8f | |||
| 3783765161 | |||
| 8cc6810fdd | |||
| a902d9af19 | |||
| 37a116f2fb | |||
| 1564831f7e | |||
| 18c1cd00c1 | |||
| a988b05e72 | |||
| a9a6fd529d | |||
| 6586d3a880 | |||
| af354f9f5e | |||
| fd320be203 | |||
| 79b182819b | |||
| a638a93b65 | |||
| 6e5c0eebce | |||
| 621781d336 | |||
| f1cad333da | |||
| cae8e7e8d2 | |||
| e70844ce61 | |||
| e00ffa2670 | |||
| 676fffa2c8 | |||
| 23cc569a47 | |||
| dafacf153b | |||
| 7a9f357510 | |||
| ada97acb04 | |||
| 6c15b45a8c | |||
| f30a8c658a | |||
| e84d7726d2 | |||
| 0f39802698 | |||
| a014a3ed0e | |||
| 5720d1a01e | |||
| 5eed6ac6d2 | |||
| 0cfa1e223a | |||
| 219869f4c0 | |||
| e6edde963a | |||
| c44b66128e | |||
| 9356b04741 | |||
| d0a094f9a3 | |||
| 73eb625737 | |||
| 74880705b8 | |||
| 01547ef83e | |||
| f67cfa1bfb | |||
| 8d91caa4e6 | |||
| b3ed442b55 | |||
| 0d9f9a04cc | |||
| 9cca8f8719 | |||
| 90565fcf79 | |||
| 118775cf79 | |||
| 7b80ae3e68 | |||
| ae6069882f | |||
| cf4d888839 | |||
| 336e7851aa | |||
| 56b9131675 | |||
| 3c0cc49f0c | |||
| 69b2e97935 | |||
| 1c2a49d371 | |||
| 967197d224 | |||
| 396718bc5e | |||
| f0a5edaa49 | |||
| 37c62c3962 | |||
| f510578cb7 | |||
| 96b378bb7a | |||
| ab98b26cac | |||
| 2d7c51eadc | |||
| 9d440a4261 | |||
| 4870c43f39 | |||
| 9c21f621c0 | |||
| 8d382b76ad | |||
| 410f2539e1 | |||
| baee00921f | |||
| 216d4b9a1f | |||
| e00b25af42 | |||
| 44d6b37873 | |||
| 271712b050 | |||
| 3482b3a0db | |||
| 10bf5cf127 | |||
| 6cc74699aa | |||
| 0e8fdc2c5a | |||
| bd6051d972 | |||
| 9cfb9dd2b7 | |||
| 87b41ab36f | |||
| 378f42bcb7 | |||
| 6838888f5f | |||
| bb8281107e | |||
| e9d44bfc80 | |||
| 8057172f8c | |||
| c6dd83a262 | |||
| 7469474124 | |||
| dc9f36905d | |||
| 30486c5358 | |||
| 5b7a90c8bc | |||
| ac40596ad6 | |||
| 6e0edc093b | |||
| 2831996dd4 | |||
| 130793fffe | |||
| 5cabfe1655 | |||
| e99e29a523 | |||
| d64e8b0adb | |||
| 4108ba54c3 | |||
| e8ad887096 | |||
| 6c24b3cf30 | |||
| 208861f808 | |||
| f7fe1dfc58 | |||
| e2805050cf | |||
| b34bb84fc9 | |||
| 11beca16da | |||
| b0c9a2fd9e | |||
| 6b4e8695ae | |||
| e8ca74f2ab | |||
| eabf98533a | |||
| 7848881dcb | |||
| 553bee57f1 | |||
| b751570789 | |||
| e45d29c4ff | |||
| 8c8a448a71 | |||
| 0148f45979 | |||
| 3d414aaec8 | |||
| 7a4c66af57 | |||
| 444c7140f6 | |||
| 0fda30b5d2 | |||
| c8e33d43cb | |||
| 6c6af870ae | |||
| 79107599a6 | |||
| b6e8b37aee | |||
| 195ddd0421 | |||
| 9ddad931ff | |||
| fc05fe1aff | |||
| 7e325f68ca | |||
| f74da23d06 | |||
| e279915ba2 | |||
| bb6f077a95 | |||
| 7a031e6135 | |||
| 5972c74b43 | |||
| 64b3c9e42e | |||
| 157877f9a6 | |||
| 25a71fa66c | |||
| fdc02fa68a | |||
| ec3c34969a | |||
| 5a215525d5 | |||
| 450b93d916 | |||
| 2d62bad2a9 | |||
| 0b10096f1c | |||
| 8eb81493ce | |||
| d69cb121fc | |||
| 431ddb8fcb | |||
| ddf0f61ae5 | |||
| 044fc47586 | |||
| 10a9edd10b | |||
| 4042579167 | |||
| bbe18c582c | |||
| c71ff3fbcc | |||
| bd5fda5968 | |||
| fdbd9c30ac | |||
| b8b4d3f29d | |||
| 78212aa7c0 | |||
| b894125b53 | |||
| 08612d5bfa | |||
| 6dc3c6af2a | |||
| 2ecce8f02d | |||
| 62937f14fb | |||
| d6ccc4a326 | |||
| 1893108136 | |||
| 7980915bdc | |||
| b7a6812140 | |||
| 550997268b | |||
| 2e236703b2 | |||
| a771d24a57 | |||
| 69f5d12de7 | |||
| 5b5999e786 | |||
| 9e7d40a080 | |||
| fc3fe39d95 | |||
| 7efc51e30e | |||
| 2c38db456b | |||
| 48e23aafab | |||
| bd83b994bc | |||
| e52538d304 | |||
| e91cbd5cd8 | |||
| 8fb81f331c | |||
| fb188a83a1 | |||
| 70cec8b5c6 | |||
| d2365088ce | |||
| a679571a5a | |||
| b9c74e549f | |||
| 81c1724016 | |||
| 56d59eb589 | |||
| a00fcae3a3 | |||
| 9aea5de668 | |||
| 8979dd7ae9 | |||
| a56bd05389 | |||
| 9cf3328ea4 | |||
| 286d10a50f | |||
| 37c593e1d4 | |||
| 68f36cb1e5 | |||
| 78454d3434 | |||
| 56fbc2ed8f | |||
| 197d7adaaf | |||
| 49ba40e98a | |||
| e952518d71 | |||
| 0e184eaa64 | |||
| 86a3ed9dae | |||
| 1e259c805e | |||
| 8a82141c95 | |||
| 94bff11eb1 | |||
| 590d73dfe3 | |||
| fe9630d15c | |||
| 77ae25b86a | |||
| 3b34276cf8 | |||
| cffba084fc | |||
| d1589acc41 | |||
| 888a032266 | |||
| 0d18e536f0 | |||
| 21392c44f8 | |||
| 2730d8e06f | |||
| 0002606d41 | |||
| 8bd19484ee | |||
| 5d2db92613 | |||
| c1b39d21dd | |||
| e83c9b8190 | |||
| 309c76d268 | |||
| 9bd03f467d | |||
| f78eabfc66 | |||
| e032591366 | |||
| de767e07b4 | |||
| b77d3e36ab | |||
| 7885aaed3b | |||
| 6f4c2eb77c | |||
| 3f0597a0f6 | |||
| 04a3764f00 | |||
| 68464109de | |||
| 79866c5823 | |||
| d64b8ecaef | |||
| ec9f2b146a | |||
| 69fd2888a1 | |||
| 748331d649 | |||
| cb1d8e3527 | |||
| a89b299a4b | |||
| 7a15bfc161 | |||
| 65f7eb9542 | |||
| 92808f9164 | |||
| d3ed3f49d3 | |||
| da3d39c59c | |||
| f332758179 | |||
| 61a8904e52 | |||
| b70e709e53 | |||
| b032a415aa | |||
| 81821eeddc | |||
| 5288b1fe73 | |||
| 408f192b37 | |||
| 6a9f188282 | |||
| 168f15e1c2 | |||
| ae814a7e8b | |||
| 2ba17648c4 | |||
| 7160ea32cb | |||
| 19fc610ef5 | |||
| 44146f073e | |||
| 36caab37e2 | |||
| 8abce5ad9c | |||
| 6e721e4120 | |||
| 447e439612 | |||
| 088c79238e | |||
| ad72c807f6 | |||
| db3d95e1a7 | |||
| 1a16b5550f | |||
| c6fe809013 | |||
| 677b57ae09 | |||
| 02f21de8d5 | |||
| f7ca26fff0 | |||
| 6c6aa964e8 | |||
| b0bab050dd | |||
| 87197be8f7 | |||
| 75aa1fe5a0 | |||
| 3e434ce6b4 | |||
| e07508d29f | |||
| e18e980892 | |||
| a2f18fd0d9 | |||
| 9ad7ef5ab4 | |||
| 27a7046465 | |||
| 47a2a6fbac | |||
| 83b1c8692e | |||
| 73a5f64d7e | |||
| 1d18a54b8a | |||
| e877929a42 | |||
| 5f5970d7d5 | |||
| e05c9ddc08 | |||
| b77e9e25a3 | |||
| a8bf090352 | |||
| b6c9f9db68 | |||
| 8c406dcdea | |||
| 215b263d1a | |||
| 4247ffd082 | |||
| ec87621858 | |||
| bc6cf0e7b4 | |||
| 353ad058d1 | |||
| cf63b056d5 | |||
| 60eeef14c7 | |||
| 25b30153a0 | |||
| beff2a271e | |||
| f743622655 | |||
| 70a1f0b7db | |||
| e166d916da | |||
| b79ba97614 | |||
| 4f371672d0 | |||
| 80ae183b58 | |||
| b4cac11368 | |||
| 4936e140e9 | |||
| 9fd4c3b3d2 | |||
| 4f2f1d6265 | |||
| b878f6b6be | |||
| 507289ff6c | |||
| bb4cdf93b1 | |||
| 7d7fde63ec | |||
| c22fd21233 | |||
| d4d0c884f0 | |||
| e6fe3459e4 | |||
| 9ebc3c49ec | |||
| a17b403675 | |||
| 45e9b03e2d | |||
| 696b65240f | |||
| f4339677e7 | |||
| 0aaf0ad3ad | |||
| 0e5cd5bb3e | |||
| 24406a4cac | |||
| 1a1c840a3b | |||
| 2e257343a4 | |||
| 7871c465c8 | |||
| 714d9dc244 | |||
| f23b176cf4 | |||
| 494f5e21f5 | |||
| dea260cae3 | |||
| 0fcc08c204 | |||
| 632fd72d79 | |||
| 608d2e1318 | |||
| 7e436f2efd | |||
| 15fc262675 | |||
| c18fb68e81 | |||
| 299f63c6e9 | |||
| 20037ae02b | |||
| dcdbb5ac7a | |||
| cd9ba3bac9 | |||
| 060bf2282c | |||
| d88f2f81e9 | |||
| 18cc746fcf | |||
| fcc7842e89 | |||
| e91af8cfd3 | |||
| a57cc1fa3d | |||
| 80d37f9a03 | |||
| 502ef2f65d | |||
| 62daec9c16 | |||
| 9191a8b620 | |||
| 4fb53637aa | |||
| 178a2368cb | |||
| 0813dee0d4 | |||
| 9579a60abd | |||
| 5cd5bf7a0b | |||
| c0265981d1 | |||
| 2ec13165d3 | |||
| ac5ee60364 | |||
| 5ff1b56fe2 | |||
| ea914be3a6 | |||
| cb65e1796c | |||
| ff815f1ae6 | |||
| c8ebdc162f | |||
| 6768d65e1e | |||
| 657b84d3cf | |||
| 2021bf39f8 | |||
| 410ab7bcc3 | |||
| 76df4f8600 | |||
| a27b94c4c6 | |||
| 5ad06274cb | |||
| d38fa1901e | |||
| 174f1ae432 | |||
| fdeb37c3d0 | |||
| f9123208e1 | |||
| eef2f7e269 | |||
| 6a0ec66d3d | |||
| b4aab76057 | |||
| d87ffc11e7 | |||
| a67b3409b1 | |||
| e11d831114 | |||
| ec410456b2 | |||
| e9326cab8c | |||
| 61d2857ca7 | |||
| cba4847413 | |||
| bc56384325 | |||
| d7dc1b8dc7 | |||
| 11d9f2b4e4 | |||
| 163b0b531f | |||
| 64fcf7fcfc | |||
| e6ddeef18c | |||
| accb8f2f9f | |||
| d1af49a33f | |||
| c643994546 | |||
| 03265691e6 | |||
| 47a074d9cb | |||
| c32f0407e8 | |||
| 22bbc23069 | |||
| b2078d502a | |||
| ed165464c8 | |||
| 9cf66e7026 | |||
| 11f8038196 | |||
| d2105dc095 | |||
| 32287d98ac | |||
| 6934a0adee | |||
| de9cc2f30d | |||
| 31cf94ac7b | |||
| 93e32a7177 | |||
| 26887959cd | |||
| 0d28c92c83 | |||
| 1cc5cee92d | |||
| 26246eda7a | |||
| 10dd2a2dd0 | |||
| 5abc745496 | |||
| 353e8e2fb6 | |||
| 56661815ec | |||
| c9f5bb4409 | |||
| 03b6d20fcb | |||
| 7e15e81218 | |||
| 2388c8c46d | |||
| 45f905ddac | |||
| 55696efcaa | |||
| 3671b81f01 | |||
| 74ad7e6f92 | |||
| 49d55a79f4 | |||
| 8395d106a2 | |||
| d716111ded | |||
| 81b4cbbe35 | |||
| 86cfc18fe8 | |||
| 98ba72ae4b | |||
| 10b68858d6 | |||
| 8b0e0367c7 | |||
| da72e8f9c5 | |||
| 334f7dbb62 | |||
| 29248561d6 | |||
| ad74b78134 | |||
| bd716417e8 | |||
| e9ddd21286 | |||
| 73e86686dc | |||
| 1acb773adf | |||
| 5753f3d1d9 | |||
| 46fb1cce91 | |||
| d0487e7a9d | |||
| b8c096eee5 | |||
| c84f62e418 | |||
| c2107ee74a | |||
| 48a9ba6253 | |||
| 1a4abfc89c | |||
| 9550c15d56 | |||
| 229256738a | |||
| 781432c678 | |||
| a4fba72da5 | |||
| 65f90ea84a | |||
| b8ef121fe7 | |||
| d6c6a1c01f | |||
| 7257dfe5ba | |||
| 18166a3c69 | |||
| 54abb67303 | |||
| 84f46c2142 | |||
| 63d60092dc | |||
| dd9ec47cdb | |||
| 49ce9e0763 | |||
| a7089b7b16 | |||
| 53f8c0c076 | |||
| 6ad8c3d824 | |||
| 6947f47bd3 | |||
| 973804189e | |||
| 1942980154 | |||
| 64b852e1c6 | |||
| 0277a968f2 | |||
| 79ca5ebf96 | |||
| 84a7ce9b7a | |||
| ab2469ff98 | |||
| 8fc27bb261 | |||
| d9737c891f | |||
| 17dc1916aa | |||
| a00e4684b5 | |||
| a2a3ff6709 | |||
| 266f49e72f | |||
| 6be0f94ddc | |||
| 7159df8d18 | |||
| b4cd341abc | |||
| 327f034640 | |||
| 00b1250901 | |||
| 964e9b3851 | |||
| 9c5e71476f | |||
| 80a54746b1 | |||
| 9861e1a867 | |||
| 5b2ac82e94 | |||
| c5909cae34 | |||
| b0880c373b | |||
| 2b0bedd263 | |||
| ac30ed67bc | |||
| 458526075e | |||
| a1b55f0d40 | |||
| ee382c0a5b | |||
| f7f6d0ff88 | |||
| 4d058e1dce | |||
| 5c9c2dbebe | |||
| 44f7075316 | |||
| c88bfcf35a | |||
| 11d13c8305 | |||
| 0582436b9c | |||
| 00252f392f | |||
| ef16814216 | |||
| a626b6a4d0 | |||
| fca5d0e54e | |||
| 1c3b9a10f1 | |||
| b0c4194602 | |||
| 64b29f47e0 | |||
| 6198a3702f | |||
| 453acb9b4e | |||
| 565753e370 | |||
| e2aaf0f978 | |||
| 32c8370ef2 | |||
| a79004b924 | |||
| eb1612f8dd | |||
| f43d0d486b | |||
| 65bde3331b | |||
| 2f0a3bcd87 | |||
| a35555619c | |||
| b3e3951064 | |||
| 44ec26574e | |||
| 55a25caafd | |||
| 62f7b0d489 | |||
| b16fdef8dc | |||
| b5b667058b | |||
| 6c0c259742 | |||
| ca56c54aa0 | |||
| b60942aa86 | |||
| 197b267e71 | |||
| 30d3a9f17b | |||
| 74297af987 | |||
| fedb6b84b9 | |||
| fdc713339e | |||
| 03739f2837 | |||
| 79f7134bd5 | |||
| f28a2dbbeb | |||
| b81435aaca | |||
| 6d432bc186 | |||
| 415307eb9f | |||
| 48e20b2af5 | |||
| b7924b9ca8 | |||
| a10a2e0a9d | |||
| 4aa88189ed | |||
| fdb05443c2 | |||
| d9e8bd2bc8 | |||
| 81eef5a838 | |||
| f528f72903 | |||
| 918286c144 | |||
| 512234a804 | |||
| 48805484d4 | |||
| 7fecdf94e5 | |||
| a3997dfd16 | |||
| c868d90c2f | |||
| 77aebf5dd2 | |||
| e770524f3a | |||
| c5fee07cba | |||
| 9fd20fde9e | |||
| 2af9451b7f | |||
| 575baa8d49 | |||
| 48bc76cce7 | |||
| 58c0882329 | |||
| c400ec8482 | |||
| 2068bdc112 | |||
| ffe806352e | |||
| 167a6c458c | |||
| 872e6ed024 | |||
| cc9384abb6 | |||
| c346d0d6e6 | |||
| 2942d69fa1 | |||
| 7d7cc3fb08 | |||
| 0b84192c29 | |||
| 9fde47957d | |||
| ae753f60fd | |||
| 2d3b1418de | |||
| 15f1ca953d | |||
| 17180bfcd5 | |||
| c5ddea5c62 | |||
| 13cb18b707 | |||
| 17c68f6d53 | |||
| 39ca47d2ef | |||
| 824f3c2b90 | |||
| 70607dbe2b | |||
| 7e2b4c68ec | |||
| 5359fc4112 | |||
| c31a4e8ab4 | |||
| 2b773d6e6b | |||
| 996a56bd59 | |||
| 4d48f9b500 | |||
| 2570e454ed | |||
| 4fd8ae1f94 | |||
| 72829aa2af | |||
| 0cada33e49 | |||
| ca2a56248c | |||
| 6846e9fdef | |||
| 33be0079f0 | |||
| 31a865f5e0 | |||
| 114f59f712 | |||
| 65d737db6d | |||
| f04f7f9abf | |||
| 935e118d15 | |||
| e218367332 | |||
| 7eef470d28 | |||
| 3a3f3cf367 | |||
| ae9e85d3f6 | |||
| e9ac37d118 | |||
| 1d2b10c2a5 | |||
| 34442b7226 | |||
| c75e9bf05b | |||
| d1ac35108d | |||
| e0fb952146 | |||
| 4aa4c57db4 | |||
| 517600f9a4 | |||
| 1c9e76931f | |||
| d0f09480ca | |||
| e99deb1c33 | |||
| 099e745b8f | |||
| 5898656227 | |||
| 7dcf8f9b5a | |||
| 4753a74456 | |||
| 0a76623c53 | |||
| cd6bb2ca04 | |||
| 0e762b4157 | |||
| 819555e612 | |||
| 0148a0b45e | |||
| 7049e9974e | |||
| 1243fe1cad | |||
| b189e6de52 | |||
| 5dd3bdc23f | |||
| 7015eef621 | |||
| fd92d516ee | |||
| f4712baa39 | |||
| 7d8b653d6e | |||
| cf7f3f94be | |||
| 49f63b92ac | |||
| 606f079a93 | |||
| ab86013e7b | |||
| 11ac387559 | |||
| ec93d615f4 | |||
| fbebaf456b | |||
| 5670a15b20 | |||
| 7ea46609b1 | |||
| cacc59b8fd | |||
| e3cd6bfc97 | |||
| c744633139 | |||
| 8000d61ce0 | |||
| 4ac18b5d81 | |||
| 9e9ef20b7c | |||
| 0c034031d1 | |||
| 491a038b5a | |||
| 8a4fcb0023 | |||
| 0e4d304878 | |||
| 17a8964487 | |||
| 54676a4512 | |||
| 2d16d1c79c | |||
| 3c7da54c3c | |||
| 434d1cca61 | |||
| 7b14b5df4a | |||
| befa0f0603 | |||
| 0ad9942e89 | |||
| 41cfbd192c | |||
| 0d79cccc52 | |||
| d51127a9b7 | |||
| 4a6110c618 | |||
| b2bc848281 | |||
| 65a12c1156 | |||
| e93dcc1a7e | |||
| 383cbf250f | |||
| 9070b4a1c7 | |||
| 6b56be941c | |||
| 8064ea6abb | |||
| 850815b9c6 | |||
| f2c35552b8 | |||
| 068434a5ec | |||
| 68ab90915f | |||
| 9e987337c3 | |||
| 5d95a3277c | |||
| 9fe1450ac9 | |||
| 88b9b12998 | |||
| 5c4154941a | |||
| e7dfe5cdc3 | |||
| e016390f00 | |||
| f69dd81b8b | |||
| 2ec292e406 | |||
| aeac0549f8 | |||
| c53e217448 | |||
| f2dfad1b15 | |||
| 2bed764621 | |||
| 2eea01bd37 | |||
| c6f482b898 | |||
| 67b1e237bd | |||
| 3f74fc0778 | |||
| 9e25566271 | |||
| 8e54e06978 | |||
| 8ac6989d2c | |||
| c30218f17a | |||
| 21711e5f0c | |||
| 4368b4ce1e | |||
| 03f922376e | |||
| 0325e34dcb | |||
| e5c082ae13 | |||
| 96ab98ac3e | |||
| 402ab0ffc4 | |||
| 7778ede90e | |||
| bb918b742e | |||
| 1632c241ee | |||
| 06144206df | |||
| e9d05b0e75 | |||
| 6ade7e22f8 | |||
| 43d47c08cb | |||
| 3d3b5850ad | |||
| 816eeb9225 | |||
| 0b42efbbbf | |||
| 56da1a23c2 | |||
| d3c5a58db9 | |||
| d44945f688 | |||
| f370855683 | |||
| c582efd115 | |||
| c687c7a916 | |||
| 8e44080b00 | |||
| 56ca53cc93 | |||
| e616c5d8fe | |||
| 0075ec6751 | |||
| 7e31341f1a | |||
| d4ca2eb934 | |||
| 84946888ad | |||
| d276c3d8ad | |||
| 7dccaf2ec8 | |||
| ae1b8d4654 | |||
| 49f709a32a | |||
| 335c369546 | |||
| 1a446007c7 | |||
| 76f9575140 | |||
| fd7783644f | |||
| f6a3e11aa2 | |||
| c2768cea85 | |||
| 2d37b166a2 | |||
| cff5ec5a40 | |||
| 0947a199b6 | |||
| 2ecfe74b33 | |||
| 6147e923de | |||
| 3a07d5a983 | |||
| 2747868ea7 | |||
| dcc27d71b4 | |||
| 30c0482b6d | |||
| 641298b32d | |||
| 09a536f549 | |||
| 35ab818741 | |||
| e00358859c | |||
| aa24978d2b | |||
| ee497a8d1e | |||
| 935575576f | |||
| b45e75007b | |||
| 52ae0c359e | |||
| 06e6594b75 | |||
| 73d62b484c | |||
| 0ff93a220d | |||
| 2071b5bcc4 | |||
| e1378f4ee5 | |||
| a6b6e7c9d4 | |||
| 857fb53fa1 | |||
| 9db6c1a7ac | |||
| fd0461644e | |||
| 10263720d4 | |||
| cddf23c787 | |||
| 70a37309dd | |||
| 7548f3aa60 | |||
| 48555b5219 | |||
| 06d58f202f | |||
| 628870af9b | |||
| b8e0d4391d | |||
| ad3d2eb3fc | |||
| 72b34d082b | |||
| b46a6438e6 | |||
| 5488f99723 | |||
| 6bc1fe8d21 | |||
| d0406fcd83 | |||
| 9159b55096 | |||
| 7cac16320c | |||
| 24dbd1db39 | |||
| 7112649a21 | |||
| fbc312c35d | |||
| b8162a4a6d | |||
| faebdee755 | |||
| 2fc672dfab | |||
| 4dc4e87900 | |||
| 13d00a8bb4 | |||
| fb95cf7f2f | |||
| 78f048fda5 | |||
| 200adb8490 | |||
| f1496b5084 | |||
| 7b06715bff | |||
| 28404d2fd3 | |||
| 46b026b989 | |||
| 3091d5b6f0 | |||
| c117abb2d4 | |||
| 94c45f5e0f | |||
| c92c9be49a | |||
| dbc3f13c65 | |||
| ea6927a2a7 | |||
| b69a716b04 | |||
| 7e71fa26d7 | |||
| 58e85e0569 | |||
| 6fc34d8a39 | |||
| 4fed40ff7d | |||
| ee4ff35c90 | |||
| c9b92decaf | |||
| eed3bc346d | |||
| 6edef14f07 | |||
| ab49983759 | |||
| 5a09a6fb4a | |||
| ac93bf7d6b | |||
| 790df934b5 | |||
| c9c6dd5c1d | |||
| e3e1cd6b0d | |||
| 8aee4011a2 | |||
| 8950e19d4e | |||
| 99eb88f71c | |||
| 6e0277c60a | |||
| e923654161 | |||
| f3cf90bd28 | |||
| 06b41ae479 | |||
| 70847d17f1 | |||
| 2cfc39b23f | |||
| c8676b3040 | |||
| 73bd04d04a | |||
| 0ca4badb77 | |||
| 80b92ca132 | |||
| 824d7839d8 | |||
| 58865bef28 | |||
| 9fd40d0973 | |||
| c88f9d95d4 | |||
| 266ebd9122 | |||
| fee729e16c | |||
| 10a3e9c6ba | |||
| 990f79fdfe | |||
| 6360aee0ff | |||
| beb0bc2f64 | |||
| 685b81e5ec | |||
| e38e395436 | |||
| f741db874c | |||
| d684c09392 | |||
| 39af6e25ee | |||
| b15e6e0422 | |||
| 8f99a80352 | |||
| 364be22dd0 | |||
| 936a87e738 | |||
| 2af165b201 | |||
| 3d5efc07ad | |||
| 21e8d640d2 | |||
| b0ce456909 | |||
| b8e1306955 | |||
| 37a38ad288 | |||
| 9ee05c9510 | |||
| 275a68bb6a | |||
| f3f70e8549 | |||
| e15e9d80c4 | |||
| f7538c1ed8 | |||
| a9dba08a8d | |||
| 11af85d87a | |||
| 4caff75cce | |||
| 20efa3bf9a | |||
| c7977dda3d | |||
| 811861a957 | |||
| 24623ba4b0 | |||
| 7c68b46943 | |||
| c27c5a9a9b | |||
| 0ab280f812 | |||
| c3066dac17 | |||
| b650d512b3 | |||
| acf0713385 | |||
| 7c34161369 | |||
| bc52aa918d | |||
| cee872000a | |||
| 4a857680d0 | |||
| a47d0984dc | |||
| 925ec9447d | |||
| 411a73c1bf | |||
| 84077e6e24 | |||
| 184cf97304 | |||
| 9dfdd47b36 | |||
| 272a7540eb | |||
| ad796f079f | |||
| e7e7716d05 | |||
| 5f425b49b2 | |||
| 3ac8ee304a | |||
| e333b126b6 | |||
| 3618842f44 | |||
| c5d620d2b2 | |||
| cdea05ebb0 | |||
| fd8c848c9e | |||
| 09614a0239 | |||
| ca9a433f3c | |||
| 2be6052cd4 | |||
| 68ed67ee49 | |||
| d5903ba52a | |||
| 3ee635eddf | |||
| 21bc68fb53 | |||
| 6fe8f1d81a | |||
| 0bd7f715c4 | |||
| 0faac01bb7 | |||
| 74d88a8fcc | |||
| 041d88161e | |||
| 79a62aa056 | |||
| b86b4d9676 | |||
| aeaac80012 | |||
| e0ef20cf08 | |||
| f532e57862 | |||
| 169a66f5dd | |||
| 7e39b31123 | |||
| 18765450a6 | |||
| dff8c84d9c | |||
| d962c34846 | |||
| da08adbea1 | |||
| 46e3e62b59 | |||
| cd9794d818 | |||
| 5034b7cf18 | |||
| fdde84c68a | |||
| 4c54ff6f52 | |||
| de3285dc1b | |||
| 7f0c035c4c | |||
| 43593e8def | |||
| 48b0b608d8 | |||
| 69287a772b | |||
| 3656264f8a | |||
| 3361d48cd4 | |||
| ed86ea3da1 | |||
| 3deb0e5487 | |||
| 9e4792941e | |||
| b5fd5fe782 | |||
| 33c0104a02 | |||
| 81ed5100af | |||
| 87f9dc0064 | |||
| b311fedc6b | |||
| 337d5a9489 | |||
| cfeb81ee1e | |||
| 09f92f01aa | |||
| 6d1094936b | |||
| 8836a2793a | |||
| e321a0405f | |||
| c36ece8923 | |||
| a82213b90c | |||
| 98facdd2ee | |||
| d080b0b5ea | |||
| d8bc74794d | |||
| 338902ca0c | |||
| 732f05dc74 | |||
| 7ae6a11cf0 | |||
| cdbe1cb1a9 | |||
| 6ce92798c6 | |||
| f4454e9348 | |||
| d9134ae0c8 | |||
| 25180e41c8 | |||
| a99e3f2268 | |||
| d27c354bf1 | |||
| d818b1dd9d | |||
| bcdbec0091 | |||
| 098bb12b9e | |||
| 4a6c750b19 | |||
| d396e5304a | |||
| 9bed25be8c | |||
| 232037ec58 | |||
| b18c1120ab | |||
| f6a7831963 | |||
| 08a4473bbc | |||
| 9008ddafa4 | |||
| 7012ed4c2c | |||
| 1d8c8c30d0 | |||
| 7109b42092 | |||
| 1667b14194 | |||
| e9514873d2 | |||
| 090f790df4 | |||
| 82d051f388 | |||
| 5a3631c332 | |||
| c00b5526c3 | |||
| 2e35abd3a3 | |||
| 9bc3f6c56e | |||
| 5588912b62 | |||
| 37cf913d6d | |||
| 94ba767090 | |||
| a406c7cd81 | |||
| 480878a3db | |||
| a85499119d | |||
| 4cbe9cad8e | |||
| 2dfc06c679 | |||
| a591ad9fed | |||
| 5420e69b59 | |||
| f157c96f65 | |||
| 9588ace87f | |||
| cc57ac379b | |||
| 074920552a | |||
| 2a00a24058 | |||
| 06cc4ec0fe | |||
| decea393a5 | |||
| 65b0fab80d | |||
| 1d4098ae14 | |||
| 5c4f303a0d | |||
| 8dcc5bdf8a | |||
| b3e4a73a34 | |||
| 60b4a038f6 | |||
| 4e3738100a | |||
| 8216889078 | |||
| 0ee090664e | |||
| 4a9eda4ab0 | |||
| 2416c8b251 | |||
| 5b056f9dd6 | |||
| a93998dc56 | |||
| 268c27a782 | |||
| 23ace2712a | |||
| 157feeb925 | |||
| 4e25d4162f | |||
| 47a68f31e1 | |||
| 6ab4ee6a91 | |||
| a8dde73a8c | |||
| b2b11611c1 | |||
| 04c55fa3ba | |||
| 4957330c1c | |||
| ea9dfd6ea7 | |||
| 60f7191659 | |||
| 6f560c1cd7 | |||
| 524cd4a3d1 | |||
| f342c93eec | |||
| a364025bd2 | |||
| 5fa6a5e686 | |||
| 6d34164a16 | |||
| e15335ddab | |||
| b373a80498 | |||
| f0fb3ed5ff | |||
| 411deee8af | |||
| b2942e0323 | |||
| 78e371ab9f | |||
| ffeb607ad3 | |||
| 7dd68068a1 | |||
| 51d7f3b06b | |||
| a060db5530 | |||
| 30caf045ed | |||
| 6264b2ec70 | |||
| 9d1f73b3f7 | |||
| d557aa4cc0 | |||
| 81351aeb7a | |||
| ee1a568bed | |||
| e721668eb0 | |||
| 5edb30c51f | |||
| 9c5bd7193f | |||
| 3e9b7ccfc1 | |||
| f1717c7000 | |||
| 946d535f68 | |||
| 1a326cb70f | |||
| 5a9344b190 | |||
| 4eaebd658b | |||
| 581047c569 | |||
| 87677df925 | |||
| 56e81fbf7b | |||
| 473875a9d2 | |||
| 44952c79c2 | |||
| 58aebdbba4 | |||
| 2411d85af4 | |||
| 572ea6dd69 | |||
| 6e417a22ba | |||
| 3478e8f7bc | |||
| f9982a9132 | |||
| d3238205e1 | |||
| ff083361d4 | |||
| 9c038a979d | |||
| 5974a2e8a4 | |||
| 30151a2324 | |||
| 28293aba7d | |||
| d36caf8c69 | |||
| e6bd2d5009 | |||
| baf4b96b3f | |||
| acb48179ab | |||
| 20889e8724 | |||
| 751b81c7bf | |||
| 0bc7e0967d | |||
| 05181754bb | |||
| 5ab62d5d3b | |||
| 83d96bf89e | |||
| 0b2c966a72 | |||
| ffda530daa | |||
| 4c0641f374 | |||
| 54c7c034a4 | |||
| 7167668c2a | |||
| 1a722fcb07 | |||
| 648e66d5ef | |||
| e6e6902e85 | |||
| 04dd6b056f | |||
| 96b3ba6e9a | |||
| 8d22362fff | |||
| 436bfbced9 | |||
| 5273b81f94 | |||
| 6134db4984 | |||
| 6e7d9e8e5d | |||
| 741dc958f1 | |||
| 101ffd91af | |||
| cecbc3f628 | |||
| dd7bf104e7 | |||
| 6e85584c43 | |||
| c579dbb24d | |||
| 452132ca38 | |||
| ebc396340e | |||
| 5946aa79c3 | |||
| 2bc20aaa5e | |||
| 793295a8fe | |||
| eaf3e32fdd | |||
| ba40a797df | |||
| 545679f999 | |||
| 1a74dd1a2e | |||
| 9dd8b05fd7 | |||
| e273008b37 | |||
| 53684d224e | |||
| f9e843571c | |||
| 14e9adb3af | |||
| fedb7bf46f | |||
| ce520be8ca | |||
| 9d92c316c1 | |||
| f077cafcfe | |||
| fd7d0b7202 | |||
| 96586517bd | |||
| 5b5a2c0180 | |||
| b089bb96f1 | |||
| 9da4850bd7 | |||
| a6bcb376fc | |||
| 7abc07424b | |||
| e9f2bbca23 | |||
| b0ede05cf4 | |||
| ca1218f792 | |||
| 8ed2da601b | |||
| 08696dbb5f | |||
| 645ea40bfd | |||
| b970af00c1 | |||
| 5fe9508428 | |||
| a302fcd963 | |||
| 5258228d3b | |||
| 1c00be39f0 | |||
| cf1fe01d03 | |||
| 4c78bad14f | |||
| ebcddad130 | |||
| 42589cd1dc | |||
| d81fa1f908 | |||
| 217fe0dce4 | |||
| fffa7f327b | |||
| 5417f1285a | |||
| b75cbcc911 | |||
| a68f304307 | |||
| 0a00bd8a7c | |||
| e90efbb52f | |||
| 3c320a5769 | |||
| 98472b5c35 | |||
| 3f2354a8ac | |||
| 8a94c40e0e | |||
| 42eedcd3b3 | |||
| 3c2038ac0e | |||
| c8323540cc | |||
| ec80530afc | |||
| c76e7f344c | |||
| 5aca8260dc | |||
| c4baa2ecb8 | |||
| 420375ecab | |||
| f07e1c02e9 | |||
| eb054736a5 | |||
| 9d771b5d9b | |||
| d0a6282ce9 | |||
| d84cf92b03 | |||
| b679fb75ba | |||
| a3c0127a7a | |||
| c46ec2415b | |||
| f0e060f12e | |||
| 65a0d3b9df | |||
| 1a48fb86bc | |||
| 0fc374de47 | |||
| f94c5e1f3f | |||
| 352bd3e98f | |||
| 22fe4475d0 | |||
| 7a3d1f1a58 | |||
| 3159c822c7 | |||
| fa0ce6e7e1 | |||
| c29794d07b | |||
| 6ba5536554 | |||
| e6b93c2fca | |||
| b362147577 | |||
| 347b13beb4 | |||
| 16b8aac08f | |||
| b0b517e71e | |||
| cf3d746d63 | |||
| 0fdbf642d8 | |||
| 0ebd1df81d | |||
| 6f90a09558 | |||
| f3b77442fc | |||
| 47c6a9ba6a | |||
| 3e96c7e376 | |||
| 1a902d94c9 | |||
| fb1cef7cd3 | |||
| 83f909daca | |||
| 036b51cee6 | |||
| 8da82d8269 | |||
| c981c45a14 | |||
| 91848b98b7 | |||
| ec262cff53 | |||
| 9745b7e3ee | |||
| 97736e4b5d | |||
| 12991c83cb | |||
| 2a99fa2ecb | |||
| 4a1ed660ca | |||
| 8632a835c2 | |||
| 958cf01649 | |||
| 01602bd60a | |||
| 14c69fa533 | |||
| 9f6c89a983 | |||
| 51e2227bfe | |||
| ff77973a6c | |||
| f18ced524c | |||
| d34614c422 | |||
| c5e54f66a0 | |||
| 422dea8ddf | |||
| 31ba9e8343 | |||
| 5a303dfc4a | |||
| d7269976e9 | |||
| 3eab5ee9e6 | |||
| fb8afcda7d | |||
| feb7dddd65 | |||
| ab81c8d3a7 | |||
| 7c1daee18c | |||
| 578940aa40 | |||
| 92ea7282e6 | |||
| 4667e9db40 |
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -1,5 +1,6 @@
|
||||
*.js linguist-language=Java
|
||||
*.css linguist-language=Java
|
||||
*.html linguist-language=Java
|
||||
*.vue linguist-language=Java
|
||||
*.ts linguist-language=vue
|
||||
*.html linguist-language=vue
|
||||
*.sql linguist-language=Java
|
||||
*.ftl linguist-language=Java
|
||||
@ -1,21 +0,0 @@
|
||||
##### 版本号:
|
||||
|
||||
|
||||
##### 前端版本:vue3版?还是 vue2版?
|
||||
|
||||
|
||||
##### 问题描述:
|
||||
|
||||
|
||||
##### 截图&代码:
|
||||
|
||||
|
||||
|
||||
|
||||
#### 友情提示(为了提高issue处理效率):
|
||||
- 未按格式要求发帖,会被直接删掉;
|
||||
- 描述过于简单或模糊,导致无法处理的,会被直接删掉;
|
||||
- 请自己初判问题描述是否清楚,是否方便我们调查处理;
|
||||
- 针对问题请说明是Online在线功能(需说明用的主题模板),还是生成的代码功能;
|
||||
|
||||
|
||||
21
.github/ISSUE_TEMPLATE.md
vendored
21
.github/ISSUE_TEMPLATE.md
vendored
@ -1,21 +0,0 @@
|
||||
##### 版本号:
|
||||
|
||||
|
||||
##### 前端版本:vue3版?还是 vue2版?
|
||||
|
||||
|
||||
##### 问题描述:
|
||||
|
||||
|
||||
##### 截图&代码:
|
||||
|
||||
|
||||
|
||||
|
||||
#### 友情提示(为了提高issue处理效率):
|
||||
- 未按格式要求发帖,会被直接删掉;
|
||||
- 描述过于简单或模糊,导致无法处理的,会被直接删掉;
|
||||
- 请自己初判问题描述是否清楚,是否方便我们调查处理;
|
||||
- 针对问题请说明是Online在线功能(需说明用的主题模板),还是生成的代码功能;
|
||||
|
||||
|
||||
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
name: 提交 Bug
|
||||
about: 请告诉我框架存在的问题,我会协助你解决此问题!
|
||||
labels: bug
|
||||
assignees: getActivity
|
||||
|
||||
---
|
||||
|
||||
|
||||
##### 版本号:
|
||||
|
||||
|
||||
##### 分支:
|
||||
|
||||
|
||||
##### 问题描述:
|
||||
|
||||
|
||||
|
||||
##### 错误截图:
|
||||
|
||||
|
||||
|
||||
|
||||
#### 友情提示:
|
||||
- 未按格式要求发帖、描述过于简单的,会被直接删掉;
|
||||
- 描述问题请图文并茂,方便我们理解并快速定位问题;
|
||||
- 如果使用的不是master,请说明你使用的分支;
|
||||
27
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
name: 提交建议
|
||||
about: 请告诉我框架的不足之处,让我做得更好!
|
||||
labels: help wanted
|
||||
assignees: getActivity
|
||||
|
||||
---
|
||||
|
||||
##### 版本号:
|
||||
|
||||
|
||||
##### 分支:
|
||||
|
||||
|
||||
##### 问题描述:
|
||||
|
||||
|
||||
|
||||
##### 错误截图:
|
||||
|
||||
|
||||
|
||||
|
||||
#### 友情提示:
|
||||
- 未按格式要求发帖、描述过于简单的,会被直接删掉;
|
||||
- 描述问题请图文并茂,方便我们理解并快速定位问题;
|
||||
- 如果使用的不是master,请说明你使用的分支;
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@ -9,3 +9,10 @@ rebel.xml
|
||||
|
||||
## front
|
||||
**/*.lock
|
||||
os_del.cmd
|
||||
os_del_doc.cmd
|
||||
.svn
|
||||
derby.log
|
||||
*.log
|
||||
.cursor
|
||||
.history
|
||||
20
LICENSE
20
LICENSE
@ -201,13 +201,13 @@
|
||||
limitations under the License.
|
||||
|
||||
In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software.
|
||||
|
||||
开源协议补充
|
||||
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com
|
||||
本软件受适用的国家软件著作权法(包括国际条约)和双重保护许可。
|
||||
|
||||
1.允许基于本平台软件开展业务系统开发。
|
||||
2.不得基于该平台软件的基础,修改包装成一个与JeecgBoot平台软件功能类似的产品进行发布、销售,或与JeecgBoot参与同类软件产品市场的竞争。
|
||||
违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。
|
||||
解释权归:http://www.jeecg.com
|
||||
|
||||
|
||||
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com
|
||||
本软件受适用的国家软件著作权法(包括国际条约)和开源协议 双重保护许可。
|
||||
|
||||
开源协议中文释意如下:
|
||||
1.JeecgBoot开源版本无任何限制,在遵循本开源协议条款下,允许商用使用,不会造成侵权行为。
|
||||
2.允许基于本平台软件开展业务系统开发。
|
||||
3.在任何情况下,您不得使用本软件开发可能被认为与本软件竞争的软件。
|
||||
|
||||
最终解释权归:http://www.jeecg.com
|
||||
177
README-AI.md
Normal file
177
README-AI.md
Normal file
@ -0,0 +1,177 @@
|
||||
AIGC应用平台介绍
|
||||
===============
|
||||
|
||||
一个全栈式 AI 开发平台,旨在帮助开发者快速构建和部署个性化的 AI 应用。
|
||||
|
||||
> JDK说明:AI流程编排引擎暂时不支持jdk21,所以目前只能使用jdk8或者jdk17启动项目。
|
||||
|
||||
|
||||
JeecgBoot平台的AIGC功能模块,是一套类似`Dify`的`AIGC应用开发平台`+`知识库问答`,是一款基于LLM大语言模型AI应用平台和 RAG 的知识库问答系统。
|
||||
其直观的界面结合了 AI 流程编排、RAG 管道、知识库管理、模型管理、对接向量库、实时运行可观察等,让您可以快速从原型到生产,拥有AI服务能力。
|
||||
|
||||
|
||||
|
||||
### AI视频介绍
|
||||
|
||||
[](https://www.bilibili.com/video/BV1zmd7YFE4w)
|
||||
|
||||
|
||||
##### 功能大模块
|
||||
|
||||
- AI应用开发平台
|
||||
- AI知识库系统
|
||||
- AI大模型管理
|
||||
- AI流程编排
|
||||
- AI对话支持图片
|
||||
- AI对话助手(智能问答)
|
||||
- AI建表(Online表单)
|
||||
- AI写文章(CMS)
|
||||
- AI表单字段建议(表单设计器)
|
||||
|
||||
|
||||
|
||||
#### Dify `VS` JEECG AI
|
||||
|
||||
> JEECG AI与Dify相比,在多个方面展现出显著的优势,特别是在文档处理、格式和图片保持方面。以下是一些具体的优点:
|
||||
> - Markdown文档库导入:
|
||||
> JEECG AI允许用户直接导入整个Markdown文档库,这不仅保留markdown格式,还支持图片的导入,确保文档内容的完整性和可视化效果。
|
||||
> - 对话回复格式美观:
|
||||
> 在对话过程中,JEECG AI能够保持回复内容的原格式,也不丢失图片,使得输出的文章更加美观,不会出现格式错乱的情况,还支持图片的渲染。
|
||||
> - PDF文档导入与格式转换:
|
||||
> JEECG AI在处理PDF文档时,能够更好地保持原始格式和图片,确保转换后的内容与原始文档一致。这个功能在许多AI产品中表现不佳,而JEECG AI在这方面做出了显著的优化
|
||||
|
||||
|
||||
| 功能 | Dify | Jeecg AI |
|
||||
|------------|------------------|-----------------------------------------|
|
||||
| AI工作流 | 有 | 有 |
|
||||
| RAG 管道向量搜索 | 有 | 有 |
|
||||
| AI模型管理 | 有 | 有 |
|
||||
| AI应用管理 | 有 | 有 |
|
||||
| AI知识库 | 有 | 有 |
|
||||
| 产品方向 | 一款独立的 LLM 应用开发平台 | 低代码与AIGC应用二者结合的平台 |
|
||||
| 业务集成 | 业务集成能力弱 | 更方便与业务系统集成,调用系统接口和逻辑更加方便 |
|
||||
| AI业务流 | 侧重AI逻辑流程 | AI流程编排作为低代码的业务引擎,用户可以通过AI流程配置各种业务流和AI流程 |
|
||||
| 实现语言 | python + react | JAVA + vue3 |
|
||||
| 上传markdown文档库(支持图片) | 不支持 | 支持 |
|
||||
| AI对话支持发图和展示图片 | 支持 | 支持 |
|
||||
|
||||
|
||||
|
||||
### 技术文档
|
||||
|
||||
- [AIGC开发文档](https://help.jeecg.com/aigc)
|
||||
- [安装向量库 pgvector](https://help.jeecg.com/aigc/config)
|
||||
|
||||
|
||||
|
||||
## 功能特点
|
||||
|
||||
- AI流程: 提供强大的AI流程设计器引擎,支持编排 AI 工作过程,满足复杂业务场景,支持画布上构建和实时运行查看 AI流程运行情况。
|
||||
- AI流程即服务: 通过AI流程编排你需要的智能体,结合AI+自定义开发节点 实现功能性 API,让你瞬间拥有各种智能体API。
|
||||
- AI助手对话功能: 集成 ChatGPT、Deepseek、智普、私有大模型 等 AI 模型,提供智能对话和生成式 AI 功能,深度与知识库结合提供更精准的知识。
|
||||
- RAG 功能: 涵盖从文档摄入到检索的所有内容,支持从 PDF、PPT 和其他常见文档格式中提取文本,支持检索增强生成(RAG),将未训练数据与 AI 模型集成,提升智能交互能力。
|
||||
- AI 知识库: 通过导入文档或已有问答对进行训练,让 AI 模型能根据文档以交互式对话方式回答问题。
|
||||
- 模型管理:支持对接各种大模型,包括本地私有大模型(Deepseek/ Llama 3 / Qwen 2 等)、国内公共大模型(通义千问 / 腾讯混元 / 字节豆包 / 百度千帆 / 智谱 AI / Kimi 等)和国外公共大模型(OpenAI / Claude / Gemini 等);
|
||||
- 无缝嵌入:Iframe一键嵌入,支持将AI聊天助手快速嵌入到第三方系统,让系统快速拥有智能问答能力,提高用户满意度。
|
||||
|
||||
|
||||
|
||||
|
||||
#### 在线体验
|
||||
|
||||
- JeecgBoot演示: https://boot3.jeecg.com
|
||||
- 敲敲云在线搭建AI知识库:https://app.qiaoqiaoyun.com
|
||||
|
||||
|
||||
## 技术交流
|
||||
|
||||
- 开发文档:https://help.jeecg.com/aigc
|
||||
- QQ群:964611995、716488839(满)
|
||||
|
||||
|
||||
## 功能列表
|
||||
|
||||
- AI应用管理(普通应用、高级流程应用)
|
||||
- AI模型管理
|
||||
- AI知识库
|
||||
- AI应用平台(普通、对接AI流程)
|
||||
- AI流程编排
|
||||
- AI聊天支持嵌入第三方
|
||||
- AI向量库对接
|
||||
|
||||
|
||||
|
||||
## 支持AI模型
|
||||
|
||||
| AI大模型 | 支持 |
|
||||
|---------------| --- |
|
||||
| DeepSeek | √ |
|
||||
| ChatGTP | √ |
|
||||
| Qwq | √ |
|
||||
| 智库 | √ |
|
||||
| Ollama本地搭建大模型 | √ |
|
||||
| 等等。。 | √ |
|
||||
|
||||
|
||||
|
||||
|
||||
## AIGC能做什么
|
||||
|
||||
AIGC模块是一个基于AI的自动化流程编排工具和聊天应用搭建平台,它可以帮助用户快速生成AI流程接口和聊天应用,提高效率。
|
||||
以下是一些具体的应用场景和示例:
|
||||
|
||||
- 你可能需要一个翻译接口,可以通过AI流程编排搭建出来。
|
||||
- 你可能需要一个接口转换工具,可以通过AI流程编排搭建出来。(比如:jimureport所需要接口返回格式与你的系统不同,你通过AI接口实现自动转换)
|
||||
- 你可能需要一个聊天机器人,可以通过AI流程编排搭建出来。
|
||||
- 你可能需要一个自动化流程,可以通过AI流程编排搭建出来。
|
||||
- 你可能需要一个自动化处理文件的流程,可以通过AI流程结合python脚本实现操作电脑,文件等。
|
||||
|
||||
|
||||
## AI应用平台功能展示
|
||||
|
||||
AI模型列表
|
||||
|
||||

|
||||
|
||||
选择AI模型,配置你的参数
|
||||
|
||||

|
||||
|
||||
|
||||
AI知识库支持手工录入文本,导入pdf\\word\\excel等文档,支持问答对训练
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
AI流程,提供强大的AI流程设计器引擎,支持编排 AI 工作过程,满足复杂业务场景,支持画布上构建和实时运行查看 AI流程运行情况。
|
||||
|
||||

|
||||
|
||||
|
||||
目前支持的节点有:开始、结束、AI知识库节点、AI节点、分类节点、分支节点、JAVA节点、脚本节点、子流程节点、http请求节点、直接回复节点等节点
|
||||
|
||||

|
||||
|
||||
节点项配置
|
||||
|
||||

|
||||
|
||||
在线运行看结果
|
||||
|
||||

|
||||
|
||||
|
||||
AI应用配置,支持AI流程配置和简单的AI配置
|
||||
|
||||

|
||||
|
||||
可以关联多个知识库,右侧是AI智能回复,你可以搭建自己的智能体,比如搭建一个 “诗词达人” “翻译助手”
|
||||
|
||||

|
||||
|
||||
可以将创建的聊天应用,集成到第三方系统中
|
||||
|
||||

|
||||
424
README-EN.md
Normal file
424
README-EN.md
Normal file
@ -0,0 +1,424 @@
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
JEECG BOOT AI Low Code Platform
|
||||
===============
|
||||
|
||||
Current version: 3.9.0 (Release date: 2025-12-01)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
|
||||
|
||||
Project introduction
|
||||
-----------------------------------
|
||||
|
||||
<h3 align="center">Java AI Low Code Platform</h3>
|
||||
|
||||
JeecgBoot is a `AI low code platform` based on code `generators`! Front and back end separation architecture SpringBoot2.x, SpringCloud, Ant Design&Vue, Mybatis plus, Shiro, JWT, support for microservices. The powerful code generator makes the front and back end of the code generation, low code development! JeecgBoot leads a new low-code development paradigm (OnlineCoding-> Code Generator -> Manual MERGE) that helps resolve 70% of the duplication in Java projects and makes development more business-focused. Not only can quickly improve efficiency, save research and development costs, but also do not lose flexibility!
|
||||
|
||||
JeecgBoot provides a series of low code modules to make Online development truly zero code: Online form development, online reports, report configuration capabilities, online chart design, large screen design, mobile configuration capabilities, form designer, online design flow, process automation configuration, plug-in capabilities (pluggable) and more!
|
||||
|
||||
|
||||
The purpose of JEECG is: simple functions are implemented by OnlineCoding configuration, so that zero code development; Complex functions are generated by code generator and manually Merge to achieve low code development, which ensures both intelligence and flexibility. The implementation of low code development and support flexible coding at the same time, to solve the current low code products are generally not flexible drawbacks!
|
||||
|
||||
JEECG Business process: Using workflow to implement and extend the task interface for developing and writing business logic, forms provides a variety of solutions: form designer, online configuration form, and coding form. At the same time, the separation design of process and form (loose coupling) is realized, and the flexible configuration of task nodes is supported, which not only ensures the confidentiality of the company's process, but also reduces the workload of developers.
|
||||
|
||||
AI Empowering Low-Code: Currently, JeecgBoot supports AI large models such as ChatGPT and DeepSeek. The latest version defaults to using DeepSeek, which offers faster speed and higher quality. It now provides features such as AI chat assistant, AI table creation, and AI report generation.
|
||||
|
||||
Technical support
|
||||
-----------------------------------
|
||||
|
||||
Problems or bugs in use can be found in [Making on the Issues](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md)
|
||||
|
||||
|
||||
##### Project description
|
||||
|
||||
| Project | description |
|
||||
|--------------------|------------------------|
|
||||
| `jeecg-boot` | SpringBoot background source code (support microservices) |
|
||||
| `jeecgboot-vue3` | Vue3+TS new front-end source code|
|
||||
| `jeecg-uniapp` | [APP development framework, a code multi terminal adaptation, and support APP, small program, H5](https://github.com/jeecgboot/jeecg-uniapp) |
|
||||
|
||||
|
||||
### Video Introduction
|
||||
|
||||
[](https://www.bilibili.com/video/BV1Nk4y1o7Qc)
|
||||
|
||||
|
||||
|
||||
Download other source code
|
||||
-----------------------------------
|
||||
- APP SourceCode:https://github.com/jeecgboot/jeecg-uniapp
|
||||
|
||||
|
||||
|
||||
For the project
|
||||
-----------------------------------
|
||||
Jeecg-Boot AI low code platform can be applied in the development of any J2EE project, especially for SAAS projects, enterprise information management system (MIS), internal office system (OA), enterprise resource planning system (ERP), customer relationship management system (CRM), etc. Its semi-intelligent manual Merge development method, Can significantly improve the development efficiency of more than 70%, greatly reduce the development cost.
|
||||
|
||||
|
||||
Starts the project
|
||||
-----------------------------------
|
||||
|
||||
> Default account password: admin/123456
|
||||
|
||||
- [Development Environment setup](https://help.jeecg.com/java/setup/tools)
|
||||
- [IDEA Quick start(single model)](https://help.jeecg.com/java/setup/idea/startup)
|
||||
- [Docker Quick start(single model)](https://help.jeecg.com/java/docker/quick)
|
||||
- [IDEA Quick start(microservices model)](https://help.jeecg.com/java/springcloud/switchcloud/monomer)
|
||||
- [Docker Quick start(microservices model)](https://help.jeecg.com/java/docker/quickcloud)
|
||||
|
||||
|
||||
Technical documentation
|
||||
-----------------------------------
|
||||
|
||||
- Website: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
- Demo : [OnlineDemo](http://boot3.jeecg.com) | [APP](http://jeecg.com/appIndex)
|
||||
- Doc: [DocumentCenter](http://help.jeecg.com) | [AI Config](https://help.jeecg.com/java/ai/aichat)
|
||||
- Newbie guide: [Quick start](http://www.jeecg.com/doc/quickstart) | [Q&A ](http://www.jeecg.com/doc/qa) | [1 minute experience](https://my.oschina.net/jeecg/blog/3083313)
|
||||
- QQ group : 964611995、⑩716488839(满)、⑨808791225(满)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Star charts
|
||||
-----------------------------------
|
||||
|
||||
[](https://star-history.com/#jeecgboot/jeecg-boot)
|
||||
|
||||
|
||||
|
||||
|
||||
Background directory Structure
|
||||
-----------------------------------
|
||||
```
|
||||
project structure
|
||||
├─jeecg-boot-parent
|
||||
│ ├─jeecg-boot-base-core
|
||||
│ ├─jeecg-module-demo
|
||||
│ ├─jeecg-module-system
|
||||
│ │ ├─jeecg-system-biz
|
||||
│ │ ├─jeecg-system-start system (8080)
|
||||
│ │ ├─jeecg-system-api
|
||||
│ │ │ ├─jeecg-system-cloud-api
|
||||
│ │ │ ├─jeecg-system-local-api
|
||||
│ ├─jeecg-server-cloud
|
||||
├─jeecg-cloud-gateway (9999)
|
||||
├─jeecg-cloud-nacos --Nacos(8848)
|
||||
├─jeecg-system-cloud-start --System(7001)
|
||||
├─jeecg-demo-cloud-start --Demo(7002)
|
||||
├─jeecg-visual
|
||||
├─jeecg-cloud-monitor -- (9111)
|
||||
├─jeecg-cloud-xxljob -- (9080)
|
||||
├─jeecg-cloud-sentinel --sentinel (9000)
|
||||
├─jeecg-cloud-test
|
||||
├─jeecg-cloud-test-more
|
||||
├─jeecg-cloud-test-rabbitmq
|
||||
├─jeecg-cloud-test-seata
|
||||
├─jeecg-cloud-test-shardingsphere
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Why JeecgBoot?
|
||||
-----------------------------------
|
||||
* Adopt the latest mainstream front and back separation framework (Springboot+Mybatis+antd), easy to use; Code generator has low dependency, flexible expansion ability, and can quickly realize secondary development;
|
||||
* Support microservices SpringCloud Alibaba(Nacos, Gateway, Sentinel, Skywalking), and provide switching mechanism to support free switching between single and microservices
|
||||
* High development efficiency, using code generator, single table, tree list, one-to-many, one-to-one and other data models, add, delete, change and search function one-key generation, menu configuration directly use;
|
||||
* Code generator provides powerful template mechanism, support custom template, currently provide four sets of style template (single table two sets, tree model one set, one to many three sets)
|
||||
* Code generator is very intelligent, online business modeling, online configuration, WYSIWYG support 23 kinds of controls, a key to generate front and back end code, greatly improve the development efficiency, no longer worry about repeated work.
|
||||
* Low code ability: Online online form (without coding, through online configuration of the form, to achieve the addition, deletion, change and check of the form, support single table, tree, one-to-many, one-to-one model, to achieve everyone can code)
|
||||
* Low code ability: Online online report (without coding, through online configuration, to achieve data report, can quickly extract data, reduce development pressure, to achieve everyone can code)
|
||||
* Low code ability: Online online chart (without coding, through online configuration, to achieve graphs, bar graphs, data reports, etc., support custom layout, to achieve everyone can code)
|
||||
* Complete encapsulation of user, role, menu, organization, data dictionary, online scheduled tasks and other basic functions, support access authorization, button permission, data permission and other functions
|
||||
* Commonly used common package, various tools (scheduled task, SMS interface, email sending,Excel import and export, etc.), basically meeting 80% of project requirements
|
||||
* Easy Excel import and export, support single table export and one-to-many table mode export, generated code with import and export function
|
||||
* Integrated simple report tools, image report and data export is very convenient, can be extremely convenient to generate graphical reports, pdf, excel, word and other reports;
|
||||
* Before and after the separation technology, the page UI style is exquisite, for the commonly used components to do the encapsulation: time, row table control, interception display control, report component, editor and so on
|
||||
* Query filter: query function automatically generated, the background dynamic spell SQL additional query conditions; Supports multiple matching modes (full matching, fuzzy query, included query, and unmatched query).
|
||||
* Data permission (fine data permission control, control to row level, list level, form field level, realize different people see different data, different people operate different fields on the same page
|
||||
* Page verification automatically generated (must be input, digital verification, amount verification, time and space, etc.);
|
||||
* Support SAAS service model and provide SaaS multi-tenant architecture solution.
|
||||
* Distributed file service, integration of minio, Ali OSS and other excellent third parties, to provide convenient file upload and management, but also support local storage.
|
||||
* Mainstream database compatibility, a set of code is fully compatible with Mysql, Postgresql, Oracle, Sqlserver, MariaDB, dream and other mainstream databases.
|
||||
* Integrate workflow flowable and realize only the configuration of flow direction in the page, which can greatly simplify the development of bpm workflow; Using bpm's process designer to draw the flow direction, a workflow is basically complete with a small amount of java code;
|
||||
* Low code ability: online process design, using open source Activiti process engine, to achieve online drawing process, custom form, form attachment, business flow
|
||||
* Multi-data source: its simple way of use, online configuration of data source configuration, convenient to grab data from other data;
|
||||
* Provide single sign-on CAS integration solution, and complete docking code has been provided in the project
|
||||
* Low code ability: form designer, support user custom form layout, support single table, one to many forms, support select, radio, checkbox, textarea, date, popup, list, macro and other controls
|
||||
* Professional interface docking mechanism, unified using restful interface, integrated swagger-ui online interface documentation, Jwt token security verification, convenient client docking
|
||||
* Interface security mechanism, can be refined control interface authorization, very simple to realize different clients only see their own data control
|
||||
* Advanced combination query function, online configuration support primary and sub-table associated query, can save the query history
|
||||
* Provide a variety of system monitoring, real-time tracking system running conditions (monitoring Redis, Tomcat, jvm, server information, request tracking, SQL monitoring)
|
||||
* Message center (support SMS, email, wechat push, etc.)
|
||||
* Integrate Websocket message notification mechanism
|
||||
* Excellent mobile adaptive effect, providing APP release scheme:
|
||||
* Support multiple languages and provide internationalization solutions;
|
||||
* Data change record log, can record each change of data content, through the version comparison function to view historical changes
|
||||
* The platform UI is powerful and mobile adaptation is implemented
|
||||
* Platform home page style, provide a variety of combination mode, support custom style
|
||||
* Provide easy to use print plug-in, support Google, Firefox, IE11+ and other browsers
|
||||
* Rich sample code, provide a lot of learning case reference
|
||||
* Using maven module development method
|
||||
* Support dynamic menu routing
|
||||
* RBAC (Role-Based Access Control) is used for permission control.
|
||||
* Provide new row edit table JVXETable, easily meet a variety of complex ERP layout, with higher performance, more flexible extension, more powerful functions
|
||||
|
||||
|
||||
|
||||
|
||||
Technical Architecture:
|
||||
-----------------------------------
|
||||
|
||||
#### Development Environment
|
||||
|
||||
- Language: Java Default Jdk17(support jdk8、jdk21)
|
||||
|
||||
- IDE(JAVA) : IDEA (lombok plug-in must be installed)
|
||||
|
||||
- IDE(front-end) : Vscode, WebStorm, IDEA
|
||||
|
||||
- Dependency management: Maven
|
||||
|
||||
- Cache: Redis
|
||||
|
||||
- Database: MySQL5.7 + [More Databases](https://my.oschina.net/jeecg/blog/4905722)
|
||||
|
||||
|
||||
#### backend
|
||||
|
||||
- Basic framework: Spring Boot 2.7.18
|
||||
|
||||
- Microservice framework: Spring Cloud Alibaba 2021.0.6.2
|
||||
|
||||
- Persistence layer framework: MybatisPlus 3.5.3.2
|
||||
|
||||
- Report tool: JimuReport 1.9.5
|
||||
|
||||
- Security framework: Apache Shiro 1.13.0, Jwt 4.5.0
|
||||
|
||||
- Microservice technology stack: Spring Cloud Alibaba, Nacos, Gateway, Sentinel, Skywalking
|
||||
|
||||
- Database connection pool: Alibaba Druid 1.1.24
|
||||
|
||||
- Log printing: logback
|
||||
|
||||
- Others: autopoi, fastjson, poi, Swagger-ui, quartz, lombok (simplified code), etc.
|
||||
|
||||
|
||||
#### The front end
|
||||
|
||||
- TechnologyStack:`Vue3.0+TypeScript+Vite+AntDesignVue+pinia+echarts`
|
||||
|
||||
#### Front-end environment requirements
|
||||
|
||||
* `Node.js 、npm 、pnpm`
|
||||
* pnpm `v9+` is now required.
|
||||
* Node.js Version suggestion: `v20.15.0`
|
||||
` ( Since Vite6 Node.js 18/20 + is now required )`
|
||||
|
||||
|
||||
#### Support library
|
||||
|
||||
| database | support |
|
||||
| --- | --- |
|
||||
| MySQL | √ |
|
||||
| Oracle11g | √ |
|
||||
| Sqlserver2017 | √ |
|
||||
| PostgreSQL | √ |
|
||||
| MariaDB | √ |
|
||||
| 达梦 | √ |
|
||||
| 人大金仓 | √ |
|
||||
| TiDB | √ |
|
||||
|
||||
|
||||
#### AI Support
|
||||
|
||||
| AI Model | Supported |
|
||||
| --- | --- |
|
||||
| DeepSeek | √ |
|
||||
| ChatGPT | √ |
|
||||
| Qwq | √ |
|
||||
| 智库 | √ |
|
||||
| Ollama本地搭建大模型 | √ |
|
||||
| 等等。。 | √ |
|
||||
|
||||
|
||||
AI Config: https://help.jeecg.com/java/ai/aichat
|
||||
|
||||
AI APP: https://help.jeecg.com/aigc
|
||||
|
||||
|
||||
## Microservice solutions
|
||||
|
||||
- 1. Service registration and discovery Nacos √
|
||||
- 2. Nacos √
|
||||
- 3. Route gateway gateway(Three loading modes) √
|
||||
- 4. Distributed http feign √
|
||||
- 5. fuse degrade current limiting Sentinel √
|
||||
- 6. Distributed files Minio and Alioss √
|
||||
- 7. Unified permission control
|
||||
- 8. Service monitoring SpringBootAdmin√
|
||||
- 9. link tracking Skywalking [reference document](https://help.jeecg.com/java/springcloud/super/skywarking)
|
||||
- 10. Messaging middleware RabbitMQ √
|
||||
- 11. Distributed task xxl-job √
|
||||
- 12. Distributed Transaction Seata
|
||||
- 13. Distributed log Loki+grafana
|
||||
- 14. Support docker-compose, k8s, jenkins
|
||||
- 15. CAS SSO √
|
||||
- 16. Route traffic limiting √
|
||||
|
||||
|
||||
#### Microservice architecture diagram
|
||||

|
||||
|
||||
### Jeecg Boot product functionality blueprint
|
||||

|
||||
|
||||
### quick start
|
||||
- Microservice Development: [Monomer upgrade to microservice](https://help.jeecg.com/java/springcloud/switchcloud/monomer)
|
||||
- [Docker starts the micro-service background](https://help.jeecg.com/java/docker/springcloud)
|
||||
|
||||
|
||||
### Effect of system
|
||||
|
||||
##### ChatGPT AI Dialog
|
||||
> Go to the JeecgBoot background home page and click "AI Assistant" in the middle of the right side of the home page. The AI Assistant dialog screen is displayed.
|
||||

|
||||
|
||||
|
||||
##### PC
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### interactive
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### process Designer
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### min process
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### dashboard Designer
|
||||
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
##### report Designer
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### form Designer
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### bigscreen Designer
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### uniapp
|
||||

|
||||
|
||||

|
||||
|
||||
##### low app
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### app
|
||||

|
||||

|
||||
|
||||
##### PAD
|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
##### chart
|
||||

|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
##### swagger
|
||||

|
||||

|
||||
|
||||
|
||||
## donation
|
||||
|
||||
If so, buy the author a cup of coffee ☺
|
||||
|
||||

|
||||
126
README-Enterprise.md
Normal file
126
README-Enterprise.md
Normal file
@ -0,0 +1,126 @@
|
||||
|
||||
JeecgBoot低代码平台(商业版介绍)
|
||||
===============
|
||||
|
||||
|
||||
|
||||
项目介绍
|
||||
-----------------------------------
|
||||
|
||||
<h3 align="center">企业级AI低代码平台</h3>
|
||||
|
||||
|
||||
JeecgBoot是一款集成AI应用的,基于BPM流程的低代码平台,旨在帮助企业快速实现低代码开发和构建个性化AI应用,支持MCP和插件,实现聊天式业务操作(如 “一句话创建用户”)!
|
||||
|
||||
前后端分离架构Ant Design&Vue3,SpringBoot,SpringCloud Alibaba,Mybatis-plus,Shiro。强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE, 帮助Java项目解决80%的重复工作,让开发更多关注业务,提高效率、节省成本,同时又不失灵活性!低代码能力:Online表单、表单设计、流程设计、Online报表、大屏/仪表盘设计、报表设计; AI应用平台功能:AI知识库问答、AI模型管理、AI流程编排、AI聊天等,支持含ChatGPT、DeepSeek、Ollama等多种AI大模型
|
||||
|
||||
JeecgBoot 提供了一系列 `低代码能力`,实现`真正的零代码`在线开发:Online表单开发、Online报表、复杂报表设计、打印设计、在线图表设计、仪表盘设计、大屏设计、移动图表能力、表单设计器、在线设计流程、流程自动化配置、插件能力(可插拔)
|
||||
|
||||
`AI赋能低代码:` 目前提供了AI应用、AI模型管理、AI流程编排、AI对话助手,AI建表、AI写文章、AI知识库问答、AI字段建议等功能;支持各种AI大模型ChatGPT、DeepSeek、Ollama、智普、千问等.
|
||||
|
||||
`JEECG宗旨是:` 简单功能由OnlineCoding配置实现,做到`零代码开发`;复杂功能由代码生成器生成进行手工Merge 实现`低代码开发`,既保证了`智能`又兼顾`灵活`;实现了低代码开发的同时又支持灵活编码,解决了当前低代码产品普遍不灵活的弊端!
|
||||
|
||||
`JEECG业务流程:` 采用工作流来实现、扩展出任务接口,供开发编写业务逻辑,表单提供多种解决方案: 表单设计器、online配置表单、编码表单。同时实现了流程与表单的分离设计(松耦合)、并支持任务节点灵活配置,既保证了公司流程的保密性,又减少了开发人员的工作量。
|
||||
|
||||
|
||||
|
||||
#### JeecgBoot商业版与同类产品区别
|
||||
-----------------------------------
|
||||
|
||||
- 灵活性:jeecgboot基于开源技术栈,设计初考虑到可插拔性和集成灵活性,确保平台的智能性与灵活性,避免因平台过于庞大而导致的扩展困难。
|
||||
- 流程管理:支持一个表单挂接多个流程,同时一个流程可以连接多个表单,增强了流程的灵活性和复杂性管理。
|
||||
- 符合中国国情的流程:针对中国市场的特定需求,jeecgboot能够实现各种符合中国国情的业务流程。
|
||||
- 强大的表单设计器:jeecgboot的表单设计器与敲敲云共享,具备高质量和智能化的特点,能够满足零代码应用的需求,业内同类产品中不多见。
|
||||
- 报表功能:自主研发的报表工具,拥有独立知识产权,功能上比业内老牌产品如帆软更智能,操作简便。
|
||||
- BI产品整合:提供大屏、仪表盘、门户等功能,完美解决这些需求,并支持移动面板的设计与渲染。
|
||||
- 自主研发的模块:jeecgboot的所有模块均为自主研发,具有独立的知识产权。
|
||||
- 颗粒度和功能细致:在功能细致度和颗粒度上,jeecgboot远超同类产品,尤其在零代码能力方面表现突出。
|
||||
- 零代码应用管理:最新版支持与敲敲云的零代码应用管理能力的集成,使得jeecgboot既具备低代码,又具备零代码的应用能力,业内独一无二。
|
||||
- 强大的代码生成器:作为开源代码生成器的先锋,jeecgboot在代码生成的智能化和在线低代码与代码生成的结合方面,优势明显。
|
||||
- 精细化权限管理:提供行级和列级的数据权限控制,满足企业在ERP和OA领域对权限管理的严格需求。
|
||||
- 多平台支持的APP:目前采用uniapp3实现,支持小程序、H5、App及鸿蒙、鸿蒙Next、Electron桌面应用等多种终端。
|
||||
|
||||
> 综上所述,jeecgboot不仅在功能上具备丰富性和灵活性,还在技术架构、权限管理和用户体验等方面展现出明显的优势,是一个综合性能强大的低代码平台。
|
||||
|
||||
|
||||
|
||||
商业版演示
|
||||
-----------------------------------
|
||||
|
||||
JeecgBoot vs 敲敲云
|
||||
> - JeecgBoot是低代码产品拥有系列低代码能力,比如流程设计、表单设计、大屏设计,代码生成器,适合半开发模式(开发+低代码结合),也可以集成零代码应用管理模块.
|
||||
> - 敲敲云是零代码产品,完全不写代码,通过配置搭建业务系统,其在jeecgboot基础上研发而成,删除了online、代码生成、OA等需要编码功能,只保留应用管理功能和聊天、日程、文件三个OA组件.
|
||||
|
||||
|
||||
- JeecgBoot低代码: https://boot3.jeecg.com
|
||||
- 敲敲云零代码:https://app.qiaoqiaoyun.com
|
||||
- APP演示(多端): http://jeecg.com/appIndex
|
||||
|
||||
|
||||
### 流程视频介绍
|
||||
|
||||
[](https://www.bilibili.com/video/BV1Nk4y1o7Qc)
|
||||
|
||||
|
||||
|
||||
### 商业版功能简述
|
||||
|
||||
> 详细的功能介绍,[请联系官方](https://jeecg.com/vip)
|
||||
|
||||
```
|
||||
│─更多商业功能
|
||||
│ ├─流程设计器
|
||||
│ ├─简流设计器(类钉钉版)
|
||||
│ ├─门户设计(NEW)
|
||||
│ ├─表单设计器
|
||||
│ ├─大屏设计器
|
||||
│ └─我的任务
|
||||
│ └─历史流程
|
||||
│ └─历史流程
|
||||
│ └─流程实例管理
|
||||
│ └─流程监听管理
|
||||
│ └─流程表达式
|
||||
│ └─我发起的流程
|
||||
│ └─我的抄送
|
||||
│ └─流程委派、抄送、跳转
|
||||
│ └─OA办公组件
|
||||
│ └─零代码应用管理(无需编码,在线搭建应用系统)
|
||||
│ ├─积木报表企业版(含jimureport、jimubi)
|
||||
│ ├─AI流程设计器源码
|
||||
│ ├─Online全模块功能和源码
|
||||
│ ├─AI写文章(CMS)
|
||||
│ ├─AI表单字段建议(表单设计器)
|
||||
│ ├─OA办公协同组件
|
||||
│ ├─在线聊天功能
|
||||
│ ├─设计表单移动适配
|
||||
│ ├─设计表单支持外部填报
|
||||
│ ├─设计表单AI字段建议
|
||||
│ ├─设计表单视图功能(支持多种类型含日历、表格、看板、甘特图)
|
||||
│ └─。。。
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
##### 流程设计
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
##### 表单设计器
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
577
README.md
577
README.md
@ -1,228 +1,197 @@
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
JEECG BOOT 低代码开发平台
|
||||
JeecgBoot AI低代码平台
|
||||
===============
|
||||
|
||||
当前最新版本: 3.4.3(发布日期:2022-10-18)
|
||||
当前最新版本: 3.9.0(发布日期:2025-12-01)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/jeecgboot/JeecgBoot/blob/master/LICENSE)
|
||||
[](https://jeecg.com)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](https://github.com/jeecgboot/JeecgBoot)
|
||||
[](https://github.com/jeecgboot/JeecgBoot)
|
||||
[](https://github.com/jeecgboot/JeecgBoot)
|
||||
|
||||
|
||||
|
||||
项目介绍
|
||||
-----------------------------------
|
||||
|
||||
<h3 align="center">Java Low Code Platform for Enterprise web applications</h3>
|
||||
<h3 align="center">企业级AI低代码平台</h3>
|
||||
|
||||
JeecgBoot 是一款基于代码生成器的`低代码开发平台`!前后端分离架构 SpringBoot2.x,SpringCloud,Ant Design&Vue,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发! JeecgBoot 引领新的低代码开发模式(OnlineCoding-> 代码生成器-> 手工MERGE), 帮助解决Java项目70%的重复工作,让开发更多关注业务。既能快速提高效率,节省研发成本,同时又不失灵活性!
|
||||
JeecgBoot 是一款融合代码生成与AI应用的低代码开发平台,助力企业快速实现低代码开发和构建AI应用。平台支持MCP和插件扩展,提供聊天式业务操作(如“一句话创建用户”),大幅提升开发效率与用户便捷性。
|
||||
|
||||
JeecgBoot 提供了一系列`低代码模块`,实现在线开发`真正的零代码`:Online表单开发、Online报表、报表配置能力、在线图表设计、大屏设计、移动配置能力、表单设计器、在线设计流程、流程自动化配置、插件能力(可插拔)等等!
|
||||
采用前后端分离架构(Ant Design&Vue3,SpringBoot3,SpringCloud Alibaba,Mybatis-plus),强大代码生成器实现前后端一键生成,无需手写代码。
|
||||
平台引领AI低代码开发模式:AI生成→在线编码→代码生成→手工合并,解决Java项目80%重复工作,提升效率,节省成本,兼顾灵活性。
|
||||
具备强大且颗粒化的权限控制,支持按钮权限和数据权限设置,满足大型业务系统需求。功能涵盖在线表单、表单设计、流程设计、门户设计、报表与大屏设计、OA办公、AI应用、AI知识库、大模型管理、AI流程编排、AI聊天,支持ChatGPT、DeepSeek、Ollama等多种AI大模型。
|
||||
|
||||
`傻瓜式报表:` JimuReport是一款自主研发的强大开源企业级Web报表工具。它通过零编码的拖拽式操作,赋能用户如同搭积木般轻松构建各类复杂报表,全面满足企业数据可视化与分析需求,助力企业级数据产品的高效打造与应用。
|
||||
|
||||
`傻瓜式大屏:` JimuBI一款自主研发的强大的大屏和仪表盘设计工具。专注数字孪生与数据可视化,支持交互式大屏、仪表盘、门户和移动端,实现“一次开发,多端适配”。 大屏设计类Word风格,支持多屏切换,自由拖拽,轻松打造炫酷动态界面。
|
||||
|
||||
`成熟AI应用功能:` 提供一套完善AI应用平台: 涵盖AI应用管理、AI模型管理、智能对话助手、知识库问答、流程编排与设计器、AI建表、MCP插件配置等功能。平台兼容主流大模型,包括ChatGPT、DeepSeek、Ollama、智普、千问等,助力企业高效构建智能化应用,推动低代码开发与AI深度融合。
|
||||
|
||||
`JEECG宗旨是:` JEECG旨在通过OnlineCoding平台实现简单功能的零代码快速搭建,同时针对复杂功能采用代码生成器生成代码并手工合并,打造智能且灵活的低代码开发模式,有效解决了当前低代码产品普遍缺乏灵活性的问题,提升开发效率的同时兼顾系统的扩展性和定制化能力。
|
||||
|
||||
`JEECG业务流程:` JEECG业务流程采用BPM工作流引擎实现业务审批,扩展任务接口供开发人员编写业务逻辑,表单提供表单设计器、在线配置表单和编码表单等多种解决方案。通过流程与表单的分离设计(松耦合)及任务节点的灵活配置,既保障了企业流程的安全性与保密性,又大幅降低了开发人员的工作量。
|
||||
|
||||
|
||||
`JEECG宗旨是:` 简单功能由OnlineCoding配置实现,做到`零代码开发`;复杂功能由代码生成器生成进行手工Merge 实现`低代码开发`,既保证了`智能`又兼顾`灵活`;实现了低代码开发的同时又支持灵活编码,解决了当前低代码产品普遍不灵活的弊端!
|
||||
|
||||
`JEECG业务流程:` 采用工作流来实现、扩展出任务接口,供开发编写业务逻辑,表单提供多种解决方案: 表单设计器、online配置表单、编码表单。同时实现了流程与表单的分离设计(松耦合)、并支持任务节点灵活配置,既保证了公司流程的保密性,又减少了开发人员的工作量。
|
||||
|
||||
|
||||
项目源码
|
||||
-----------------------------------
|
||||
| 仓库 | 后端源码 |前端 Vue3版 | 前端 Vue2版 |
|
||||
|-|-|-|-|
|
||||
| Github | [jeecg-boot](https://github.com/jeecgboot/jeecg-boot) | [jeecgboot-vue3](https://github.com/jeecgboot/jeecgboot-vue3) | [ant-design-vue-jeecg](https://github.com/jeecgboot/ant-design-vue-jeecg) |
|
||||
| 码云 | [jeecg-boot](https://gitee.com/jeecg/jeecg-boot) | [jeecgboot-vue3](https://gitee.com/jeecg/jeecgboot-vue3) | [ant-design-vue-jeecg](https://gitee.com/jeecg/ant-design-vue-jeecg) |
|
||||
|
||||
|
||||
##### 项目说明
|
||||
|
||||
| 项目名 | 说明 |
|
||||
|--------------------|------------------------|
|
||||
| `jeecg-boot` | SpringBoot后台源码(支持微服务) |
|
||||
| `jeecgboot-vue3` | Vue3+Ts版前端源码 |
|
||||
| `ant-design-vue-jeecg` |Vue2版前端源码 |
|
||||
| `jeecg-uniapp` | [APP端开发框架(一份代码多终端适配,同时支持APP、小程序、H5) ](https://gitee.com/jeecg/jeecg-uniapp) |
|
||||
| `jeecg-boot-starter` | [stater依赖项目单独维护](https://gitee.com/jeecg/jeecg-boot-starter) |
|
||||
| `更多开源插件` | [更多源码下载](http://jeecg.com/download) |
|
||||
|
||||
|
||||
|
||||
|
||||
##### Star走势图
|
||||
|
||||
[](https://star-history.com/#jeecgboot/jeecg-boot)
|
||||
|
||||
|
||||
|
||||
适用项目
|
||||
-----------------------------------
|
||||
Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,尤其适合SAAS项目、企业信息管理系统(MIS)、内部办公系统(OA)、企业资源计划系统(ERP)、客户关系管理系统(CRM)等,其半智能手工Merge的开发方式,可以显著提高开发效率70%以上,极大降低开发成本。
|
||||
JeecgBoot低代码平台兼容所有J2EE项目开发,支持信创国产化,特别适用于SAAS、企业信息管理系统(MIS)、内部办公系统(OA)、企业资源计划系统(ERP)、客户关系管理系统(CRM)及AI知识库等场景。其半智能手工Merge开发模式,可显著提升70%以上的开发效率,极大降低开发成本。同时,JeecgBoot还是一款全栈式AI开发平台,助力企业快速构建和部署个性化AI应用。。
|
||||
|
||||
|
||||
技术支持
|
||||
**信创兼容说明**
|
||||
- 操作系统:国产麒麟、银河麒麟等国产系统几乎都是基于 Linux 内核,因此它们具有良好的兼容性。
|
||||
- 数据库:达梦、人大金仓、TiDB
|
||||
- 中间件:东方通 TongWeb、TongRDS,宝兰德 AppServer、CacheDB, [信创配置文档](https://help.jeecg.com/java/tongweb-deploy/)
|
||||
|
||||
|
||||
版本说明
|
||||
-----------------------------------
|
||||
|
||||
使用中遇到问题或者BUG可以在 [Github上提Issues](https://github.com/jeecgboot/jeecg-boot/issues/new)
|
||||
|下载 | SpringBoot3.5 + Shiro |SpringBoot3.5+ SpringAuthorizationServer | SpringBoot3.5 + Sa-Token | SpringBoot2.7(JDK17/JDK8) |
|
||||
|------|---------------------------------------------------------|----------------------------|-------------------|--------------------------------------------|
|
||||
| Github | [`main`](https://github.com/jeecgboot/JeecgBoot) | [`springboot3_sas`](https://github.com/jeecgboot/JeecgBoot/tree/springboot3_sas) 分支 | [`springboot3-satoken`](https://github.com/jeecgboot/JeecgBoot/tree/springboot3-satoken) 分支|[`springboot2`](https://github.com/jeecgboot/JeecgBoot/tree/springboot2) 分支|
|
||||
| Gitee | [`main`](https://github.com/jeecgboot/JeecgBoot) | [`springboot3_sas`](https://gitee.com/jeecg/JeecgBoot/tree/springboot3_sas) 分支| [`springboot3-satoken`](https://gitee.com/jeecg/JeecgBoot/tree/springboot3-satoken) 分支|[`springboot2`](https://github.com/jeecgboot/JeecgBoot/tree/springboot2) 分支 |
|
||||
|
||||
官方支持: http://jeecg.com/doc/help
|
||||
|
||||
- `jeecg-boot` 是后端JAVA源码项目Springboot3+Shiro+Mybatis+SpringCloudAlibaba(支持单体和微服务切换).
|
||||
- `jeecgboot-vue3` 是前端VUE3源码项目(vue3+vite6+ts最新技术栈).
|
||||
- `JeecgUniapp` 是[配套APP框架](https://github.com/jeecgboot/JeecgUniapp) 适配多个终端,支持APP、小程序、H5、鸿蒙、鸿蒙Next.
|
||||
- `jeecg-boot-starter` 是[jeecg-boot对应的底层封装starter](https://github.com/jeecgboot/jeecg-boot-starter) :微服务启动、xxljob、分布式锁starter、rabbitmq、分布式事务、分库分表shardingsphere等.
|
||||
- 参考 [文档](https://help.jeecg.com/ui/2dev/mini) 可以删除不需要的demo,制作一个精简版本
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
启动项目
|
||||
-----------------------------------
|
||||
|
||||
> 默认账号密码: admin/123456
|
||||
|
||||
- [开发环境搭建](https://help.jeecg.com/java/setup/tools)
|
||||
- [IDEA启动前后端(单体模式)](https://help.jeecg.com/java/setup/idea/startup)
|
||||
- [Docker一键启动(单体模式)](https://help.jeecg.com/java/docker/quick)
|
||||
- [IDEA启动前后端(微服务方式)](https://help.jeecg.com/java/springcloud/switchcloud/monomer)
|
||||
- [Docker一键启动(微服务方式)](https://help.jeecg.com/java/docker/quickcloud)
|
||||
|
||||
|
||||
技术文档
|
||||
-----------------------------------
|
||||
|
||||
- 技术官网: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
|
||||
- 在线演示 : [Vue3版本](http://boot3.jeecg.com) | [Vue2版本](http://boot.jeecg.com)
|
||||
|
||||
- 开发文档: [Vue3文档](http://vue3.jeecg.com) | [主项目文档](http://doc.jeecg.com)
|
||||
|
||||
- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [视频教程](https://space.bilibili.com/454617261/channel/series) | [常见问题 ](http://www.jeecg.com/doc/qa) | [技术支持](http://jeecg.com/doc/help) | [1分钟体验低代码](https://my.oschina.net/jeecg/blog/3083313)
|
||||
|
||||
- 微服务开发: [单体升级为微服务](http://doc.jeecg.com/3043471)
|
||||
|
||||
- QQ交流群 : ⑥730954414、VUE3群683903138、⑤860162132(满)、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满)
|
||||
> ` 提醒:【QQ群是自助服务群,建议给帮助您解决问题的同学发送指定红包,表示感谢!】 `
|
||||
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
- 在线演示: [平台演示](https://boot3.jeecg.com) | [APP演示](https://jeecg.com/appIndex)
|
||||
- 入门指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [代码生成使用](https://help.jeecg.com/java/codegen/online) | [开发文档](https://help.jeecg.com) | [AI应用手册](https://help.jeecg.com/aigc) | [视频教程](http://jeecg.com/doc/video)
|
||||
- AI编程实战视频: [JEECG低代码与Cursor+GitHub Copilot实现AI高效编程实战](https://www.bilibili.com/video/BV11XyaBVEoH)
|
||||
- 技术支持: [反馈问题](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md) | [低代码体验一分钟](https://jeecg.blog.csdn.net/article/details/106079007)
|
||||
- QQ交流群 : 964611995、⑩716488839(满)、⑨808791225(满)、其他(满)
|
||||
|
||||
|
||||
|
||||
|
||||
后台目录结构
|
||||
AI 应用平台介绍
|
||||
-----------------------------------
|
||||
```
|
||||
项目结构
|
||||
├─jeecg-boot-parent(父POM: 项目依赖、modules组织)
|
||||
│ ├─jeecg-boot-base-core(共通模块: 工具类、config、权限、查询过滤器、注解等)
|
||||
│ ├─jeecg-module-demo 示例代码
|
||||
│ ├─jeecg-module-system System系统管理目录
|
||||
│ │ ├─jeecg-system-biz System系统管理权限等功能
|
||||
│ │ ├─jeecg-system-start System单体启动项目(8080)
|
||||
│ │ ├─jeecg-system-api System系统管理模块对外api
|
||||
│ │ │ ├─jeecg-system-cloud-api System模块对外提供的微服务接口
|
||||
│ │ │ ├─jeecg-system-local-api System模块对外提供的单体接口
|
||||
│ ├─jeecg-server-cloud --微服务模块
|
||||
├─jeecg-cloud-gateway --微服务网关模块(9999)
|
||||
├─jeecg-cloud-nacos --Nacos服务模块(8848)
|
||||
├─jeecg-system-cloud-start --System微服务启动项目(7001)
|
||||
├─jeecg-demo-cloud-start --Demo微服务启动项目(7002)
|
||||
├─jeecg-visual
|
||||
├─jeecg-cloud-monitor --微服务监控模块 (9111)
|
||||
├─jeecg-cloud-xxljob --微服务xxljob定时任务服务端 (9080)
|
||||
├─jeecg-cloud-sentinel --sentinel服务端 (9000)
|
||||
├─jeecg-cloud-test -- 微服务测试示例(各种例子)
|
||||
├─jeecg-cloud-test-more -- 微服务测试示例(feign、熔断降级、xxljob、分布式锁)
|
||||
├─jeecg-cloud-test-rabbitmq -- 微服务测试示例(rabbitmq)
|
||||
├─jeecg-cloud-test-seata -- 微服务测试示例(seata分布式事务)
|
||||
├─jeecg-cloud-test-shardingsphere -- 微服务测试示例(分库分表)
|
||||
```
|
||||
|
||||
Docker启动项目
|
||||
-----------------------------------
|
||||
- [Docker启动单体后台](http://doc.jeecg.com/2043889)
|
||||
- [Docker启动微服务后台](http://doc.jeecg.com/3043472)
|
||||
- [Docker启动Vue3前端](http://vue3.jeecg.com/3028878)
|
||||
- [Docker启动Vue2前端](http://doc.jeecg.com/3043612)
|
||||
一个全栈式 AI 开发平台,旨在帮助开发者快速构建和部署个性化的 AI 应用。
|
||||
|
||||
JeecgBoot平台提供了一套完善的AI应用管理系统模块,是一套类似`Dify`的`AIGC应用开发平台`+`知识库问答`,是一款基于LLM大语言模型AI应用平台和 RAG 的知识库问答系统。
|
||||
其直观的界面结合了 AI 流程编排、RAG 管道、知识库管理、模型管理、对接向量库、实时运行可观察等,让您可以快速从原型到生产,拥有AI服务能力。
|
||||
|
||||
- [详细专题介绍,请点击查看](README-AI.md)
|
||||
|
||||
- AI视频介绍
|
||||
|
||||
[](https://www.bilibili.com/video/BV1zmd7YFE4w)
|
||||
|
||||
|
||||
为什么选择JeecgBoot?
|
||||
-----------------------------------
|
||||
* 1.采用最新主流前后分离框架(Springboot+Mybatis+antd),容易上手; 代码生成器依赖性低,灵活的扩展能力,可快速实现二次开发;
|
||||
* 2.支持微服务SpringCloud Alibaba(Nacos、Gateway、Sentinel、Skywalking),提供切换机制支持单体和微服务自由切换
|
||||
* 3.开发效率高,采用代码生成器,单表、树列表、一对多、一对一等数据模型,增删改查功能一键生成,菜单配置直接使用;
|
||||
* 4.代码生成器提供强大模板机制,支持自定义模板,目前提供四套风格模板(单表两套、树模型一套、一对多三套)
|
||||
* 5.代码生成器非常智能,在线业务建模、在线配置、所见即所得支持23种类控件,一键生成前后端代码,大幅度提升开发效率,不再为重复工作发愁。
|
||||
* 6.低代码能力:Online在线表单(无需编码,通过在线配置表单,实现表单的增删改查,支持单表、树、一对多、一对一等模型,实现人人皆可编码)
|
||||
* 7.低代码能力:Online在线报表(无需编码,通过在线配置方式,实现数据报表,可以快速抽取数据,减轻开发压力,实现人人皆可编码)
|
||||
* 8.低代码能力:Online在线图表(无需编码,通过在线配置方式,实现曲线图,柱状图,数据报表等,支持自定义排版布局,实现人人皆可编码)
|
||||
* 9.封装完善的用户、角色、菜单、组织机构、数据字典、在线定时任务等基础功能,支持访问授权、按钮权限、数据权限等功能
|
||||
* 10.常用共通封装,各种工具类(定时任务,短信接口,邮件发送,Excel导入导出等),基本满足80%项目需求
|
||||
* 11.简易Excel导入导出,支持单表导出和一对多表模式导出,生成的代码自带导入导出功能
|
||||
* 12.集成简易报表工具,图像报表和数据导出非常方便,可极其方便的生成图形报表、pdf、excel、word等报表;
|
||||
* 13.采用前后分离技术,页面UI风格精美,针对常用组件做了封装:时间、行表格控件、截取显示控件、报表组件,编辑器等等
|
||||
* 14.查询过滤器:查询功能自动生成,后台动态拼SQL追加查询条件;支持多种匹配方式(全匹配/模糊查询/包含查询/不匹配查询);
|
||||
* 15.数据权限(精细化数据权限控制,控制到行级,列表级,表单字段级,实现不同人看不同数据,不同人对同一个页面操作不同字段
|
||||
* 16.页面校验自动生成(必须输入、数字校验、金额校验、时间空间等);
|
||||
* 17.支持SAAS服务模式,提供SaaS多租户架构方案。
|
||||
* 18.分布式文件服务,集成minio、阿里OSS等优秀的第三方,提供便捷的文件上传与管理,同时也支持本地存储。
|
||||
* 19.主流数据库兼容,一套代码完全兼容Mysql、Postgresql、Oracle、Sqlserver、MariaDB、达梦等主流数据库。
|
||||
* 20.集成工作流activiti,并实现了只需在页面配置流程转向,可极大的简化bpm工作流的开发;用bpm的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的java代码;
|
||||
* 21.低代码能力:在线流程设计,采用开源Activiti流程引擎,实现在线画流程,自定义表单,表单挂靠,业务流转
|
||||
* 22.多数据源:及其简易的使用方式,在线配置数据源配置,便捷的从其他数据抓取数据;
|
||||
* 23.提供单点登录CAS集成方案,项目中已经提供完善的对接代码
|
||||
* 24.低代码能力:表单设计器,支持用户自定义表单布局,支持单表,一对多表单、支持select、radio、checkbox、textarea、date、popup、列表、宏等控件
|
||||
* 25.专业接口对接机制,统一采用restful接口方式,集成swagger-ui在线接口文档,Jwt token安全验证,方便客户端对接
|
||||
* 26.接口安全机制,可细化控制接口授权,非常简便实现不同客户端只看自己数据等控制
|
||||
* 27.高级组合查询功能,在线配置支持主子表关联查询,可保存查询历史
|
||||
* 28.提供各种系统监控,实时跟踪系统运行情况(监控 Redis、Tomcat、jvm、服务器信息、请求追踪、SQL监控)
|
||||
* 29.消息中心(支持短信、邮件、微信推送等等)
|
||||
* 30.集成Websocket消息通知机制
|
||||
* 31.移动自适应效果优秀,提供APP发布方案:
|
||||
* 32.支持多语言,提供国际化方案;
|
||||
* 33.数据变更记录日志,可记录数据每次变更内容,通过版本对比功能查看历史变化
|
||||
* 34.平台UI强大,实现了移动自适应
|
||||
* 35.平台首页风格,提供多种组合模式,支持自定义风格
|
||||
* 36.提供简单易用的打印插件,支持谷歌、火狐、IE11+ 等各种浏览器
|
||||
* 37.示例代码丰富,提供很多学习案例参考
|
||||
* 38.采用maven分模块开发方式
|
||||
* 39.支持菜单动态路由
|
||||
* 40.权限控制采用 RBAC(Role-Based Access Control,基于角色的访问控制)
|
||||
* 41.提供新行编辑表格JVXETable,轻松满足各种复杂ERP布局,拥有更高的性能、更灵活的扩展、更强大的功能
|
||||
- 1.采用最新主流前后分离框架(Spring Boot3 + MyBatis + Shiro/SpringAuthorizationServer + Ant Design4 + Vue3),容易上手;代码生成器依赖性低,灵活的扩展能力,可快速实现二次开发。
|
||||
- 2.前端大版本换代,最新版采用 Vue3.0 + TypeScript + Vite6 + Ant Design Vue4 等新技术方案。
|
||||
- 3.支持微服务Spring Cloud Alibaba(Nacos、Gateway、Sentinel、Skywalking),提供简易机制,支持单体和微服务自由切换(这样可以满足各类项目需求)。
|
||||
- 4.开发效率高,支持在线建表和AI建表,提供强大代码生成器,单表、树列表、一对多、一对一等数据模型,增删改查功能一键生成,菜单配置直接使用。
|
||||
- 5.代码生成器提供强大模板机制,支持自定义模板,目前提供四套风格模板(单表两套、树模型一套、一对多三套)。
|
||||
- 6.提供强大的报表和大屏可视化工具,支持丰富的数据源连接,能够通过拖拉拽方式快速制作报表、大屏和门户设计;支持多种图表类型:柱形图、折线图、散点图、饼图、环形图、面积图、漏斗图、进度图、仪表盘、雷达图、地图等。
|
||||
- 7.低代码能力:在线表单(无需编码,通过在线配置表单,实现表单的增删改查,支持单表、树、一对多、一对一等模型,实现人人皆可编码),在线配置零代码开发、所见即所得支持23种类控件。
|
||||
- 8.低代码能力:在线报表、在线图表(无需编码,通过在线配置方式,实现数据报表和图形报表,可以快速抽取数据,减轻开发压力,实现人人皆可编码)。
|
||||
- 9.Online支持在线增强开发,提供在线代码编辑器,支持代码高亮、代码提示等功能,支持多种语言(Java、SQL、JavaScript等)。
|
||||
- 10.封装完善的用户、角色、菜单、组织机构、数据字典、在线定时任务等基础功能,支持访问授权、按钮权限、数据权限等功能。
|
||||
- 11.前端UI提供丰富的组件库,支持各种常用组件,如表格、树形控件、下拉框、日期选择器等,满足各种复杂的业务需求 [UI组件库文档](https://help.jeecg.com/category/ui%E7%BB%84%E4%BB%B6%E5%BA%93)。
|
||||
- 12.提供APP配套框架,一份多代码多终端适配,一份代码多终端适配,小程序、H5、安卓、iOS、鸿蒙Next。
|
||||
- 13.新版APP框架采用Uniapp、Vue3.0、Vite、Wot-design-uni、TypeScript等最新技术栈,包括二次封装组件、路由拦截、请求拦截等功能。实现了与JeecgBoot完美对接:目前已经实现登录、用户信息、通讯录、公告、移动首页、九宫格、聊天、Online表单、仪表盘等功能,提供了丰富的组件。
|
||||
- 14.提供了一套成熟的AI应用平台功能,从AI模型、知识库到AI应用搭建,助力企业快速落地AI服务,加速智能化升级。
|
||||
- 15.AI能力:目前JeecgBoot支持AI大模型chatgpt和deepseek,现在最新版默认使用deepseek,速度更快质量更高。目前提供了AI对话助手、AI知识库、AI应用、AI建表、AI报表等功能。
|
||||
- 16.提供新行编辑表格JVXETable,轻松满足各种复杂ERP布局,拥有更高的性能、更灵活的扩展、更强大的功能。
|
||||
- 17.平台首页风格,提供多种组合模式,支持自定义风格;支持门户设计,支持自定义首页。
|
||||
- 18.常用共通封装,各种工具类(定时任务、短信接口、邮件发送、Excel导入导出等),基本满足80%项目需求。
|
||||
- 19.简易Excel导入导出,支持单表导出和一对多表模式导出,生成的代码自带导入导出功能。
|
||||
- 20.集成智能报表工具,报表打印、图像报表和数据导出非常方便,可极其方便地生成PDF、Excel、Word等报表。
|
||||
- 21.采用前后分离技术,页面UI风格精美,针对常用组件做了封装:时间、行表格控件、截取显示控件、报表组件、编辑器等。
|
||||
- 22.查询过滤器:查询功能自动生成,后台动态拼SQL追加查询条件;支持多种匹配方式(全匹配/模糊查询/包含查询/不匹配查询)。
|
||||
- 23.数据权限(精细化数据权限控制,控制到行级、列表级、表单字段级,实现不同人看不同数据,不同人对同一个页面操作不同字段)。
|
||||
- 24.接口安全机制,可细化控制接口授权,非常简便实现不同客户端只看自己数据等控制;也提供了基于AK和SK认证鉴权的OpenAPI功能。
|
||||
- 25.活跃的社区支持;近年来,随着网络威胁的日益增加,团队在安全和漏洞管理方面积累了丰富的经验,能够为企业提供全面的安全解决方案。
|
||||
- 26.权限控制采用RBAC(Role-Based Access Control,基于角色的访问控制)。
|
||||
- 27.页面校验自动生成(必须输入、数字校验、金额校验、时间空间等)。
|
||||
- 28.支持SaaS服务模式,提供SaaS多租户架构方案。
|
||||
- 29.分布式文件服务,集成MinIO、阿里OSS等优秀的第三方,提供便捷的文件上传与管理,同时也支持本地存储。
|
||||
- 30.主流数据库兼容,一套代码完全兼容MySQL、PostgreSQL、Oracle、SQL Server、MariaDB、达梦、人大金仓等主流数据库。
|
||||
- 31.集成工作流Flowable,并实现了只需在页面配置流程转向,可极大简化BPM工作流的开发;用BPM的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的Java代码。
|
||||
- 32.低代码能力:在线流程设计,采用开源Flowable流程引擎,实现在线画流程、自定义表单、表单挂靠、业务流转。
|
||||
- 33.多数据源:极其简易的使用方式,在线配置数据源配置,便捷地从其他数据抓取数据。
|
||||
- 34.提供单点登录CAS集成方案,项目中已经提供完善的对接代码。
|
||||
- 35.低代码能力:表单设计器,支持用户自定义表单布局,支持单表、一对多表单,支持select、radio、checkbox、textarea、date、popup、列表、宏等控件。
|
||||
- 36.专业接口对接机制,统一采用RESTful接口方式,集成Swagger-UI在线接口文档,JWT token安全验证,方便客户端对接。
|
||||
- 37.高级组合查询功能,在线配置支持主子表关联查询,可保存查询历史。
|
||||
- 38.提供各种系统监控,实时跟踪系统运行情况(监控Redis、Tomcat、JVM、服务器信息、请求追踪、SQL监控)。
|
||||
- 39.消息中心(支持短信、邮件、微信推送等);集成WebSocket消息通知机制。
|
||||
- 40.支持多语言,提供国际化方案。
|
||||
- 41.数据变更记录日志,可记录数据每次变更内容,通过版本对比功能查看历史变化。
|
||||
- 42.提供简单易用的打印插件,支持谷歌、火狐、IE11+等各种浏览器。
|
||||
- 43.后端采用Maven分模块开发方式;前端支持菜单动态路由。
|
||||
- 44.提供丰富的示例代码,涵盖了常用的业务场景,便于学习和参考。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
技术架构:
|
||||
-----------------------------------
|
||||
#### 开发环境
|
||||
|
||||
- 语言:Java 8+ (小于17)
|
||||
#### 前端
|
||||
|
||||
- IDE(JAVA): IDEA (必须安装lombok插件 )
|
||||
- 前端环境要求:Node.js要求`Node 20+` 版本以上、pnpm 要求`9+` 版本以上
|
||||
|
||||
- IDE(前端): Vscode、WebStorm、IDEA
|
||||
` ( Vite 不再支持已结束生命周期(EOL)的 Node.js 18。现在需要使用 Node.js 20.19+ 或 22.12+)`
|
||||
|
||||
- 依赖管理:Maven
|
||||
|
||||
- 缓存:Redis
|
||||
|
||||
- 数据库脚本:MySQL5.7+ & Oracle 11g & Sqlserver2017(其他数据库,[需要自己转](https://my.oschina.net/jeecg/blog/4905722))
|
||||
- 依赖管理:node、npm、pnpm
|
||||
- 前端IDE建议:IDEA、WebStorm、Vscode
|
||||
- 采用 Vue3.0+TypeScript+Vite6+Ant-Design-Vue4等新技术方案,包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能
|
||||
- 最新技术栈:Vue3.0 + TypeScript + Vite6 + ant-design-vue4 + pinia + echarts + unocss + vxe-table + qiankun + es6
|
||||
|
||||
|
||||
#### 后端
|
||||
|
||||
- 基础框架:Spring Boot 2.6.6
|
||||
|
||||
- 微服务框架: Spring Cloud Alibaba 2021.0.1.0
|
||||
|
||||
- 持久层框架:MybatisPlus 3.5.1
|
||||
|
||||
- 报表工具: JimuReport 1.5.2
|
||||
|
||||
- 安全框架:Apache Shiro 1.8.0,Jwt 3.11.0
|
||||
|
||||
- IDE建议: IDEA (必须安装lombok插件 )
|
||||
- 语言:Java 默认jdk17(jdk21、jdk24)
|
||||
- 依赖管理:Maven
|
||||
- 基础框架:Spring Boot 3.5.5
|
||||
- 微服务框架: Spring Cloud Alibaba 2023.0.3.3
|
||||
- 持久层框架:MybatisPlus 3.5.12
|
||||
- 报表工具: JimuReport 2.1.3
|
||||
- 安全框架:Apache Shiro 2.0.4,Jwt 4.5.0
|
||||
- 微服务技术栈:Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywalking
|
||||
|
||||
- 数据库连接池:阿里巴巴Druid 1.1.22
|
||||
|
||||
- 数据库连接池:阿里巴巴Druid 1.2.24
|
||||
- AI大模型:支持 `ChatGPT` `DeepSeek` `千问`等各种常规模式
|
||||
- 日志打印:logback
|
||||
|
||||
- 缓存:Redis
|
||||
- 其他:autopoi, fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。
|
||||
- 默认提供MySQL5.7+数据库脚本
|
||||
|
||||
#### 数据库支持
|
||||
|
||||
#### 前端
|
||||
|
||||
- Vue2版本:`Vue2.6+@vue/cli+AntDesignVue+Viser-vue+Vuex等` [详细查看](https://github.com/jeecgboot/ant-design-vue-jeecg)
|
||||
- Vue3版本:`Vue3.0+TypeScript+Vite+AntDesignVue+pinia+echarts等新方案` [详细查看](https://github.com/jeecgboot/jeecgboot-vue3)
|
||||
|
||||
#### 支持库
|
||||
> jeecgboot平台支持以下数据库,默认我们只提供mysql脚本,其他数据库可以参考[转库文档](https://my.oschina.net/jeecg/blog/4905722)自己转。
|
||||
|
||||
| 数据库 | 支持 |
|
||||
| --- | --- |
|
||||
@ -231,61 +200,70 @@ Docker启动项目
|
||||
| Sqlserver2017 | √ |
|
||||
| PostgreSQL | √ |
|
||||
| MariaDB | √ |
|
||||
| 达梦、人大金仓 | √ |
|
||||
| 达梦 | √ |
|
||||
| 人大金仓 | √ |
|
||||
| TiDB | √ |
|
||||
| kingbase8 | √ |
|
||||
|
||||
|
||||
|
||||
|
||||
## 微服务解决方案
|
||||
|
||||
- 1、服务注册和发现 Nacos √
|
||||
- 2、统一配置中心 Nacos √
|
||||
- 3、路由网关 gateway(三种加载方式) √
|
||||
- 4、分布式 http feign √
|
||||
- 5、熔断降级限流 Sentinel √
|
||||
- 6、分布式文件 Minio、阿里OSS √
|
||||
- 7、统一权限控制 JWT + Shiro √
|
||||
- 8、服务监控 SpringBootAdmin√
|
||||
- 9、链路跟踪 Skywalking [参考文档](https://help.jeecg.com/java/springcloud/super/skywarking)
|
||||
- 10、消息中间件 RabbitMQ √
|
||||
- 11、分布式任务 xxl-job √
|
||||
- 12、分布式事务 Seata
|
||||
- 13、轻量分布式日志 Loki+grafana套件
|
||||
- 14、支持 docker-compose、k8s、jenkins
|
||||
- 15、CAS 单点登录 √
|
||||
- 16、路由限流 √
|
||||
|
||||
1、服务注册和发现 Nacos √
|
||||
|
||||
2、统一配置中心 Nacos √
|
||||
|
||||
3、路由网关 gateway(三种加载方式) √
|
||||
|
||||
4、分布式 http feign √
|
||||
|
||||
5、熔断降级限流 Sentinel √
|
||||
|
||||
6、分布式文件 Minio、阿里OSS √
|
||||
|
||||
7、统一权限控制 JWT + Shiro √
|
||||
|
||||
8、服务监控 SpringBootAdmin√
|
||||
|
||||
9、链路跟踪 Skywalking [参考文档](http://doc.jeecg.com/2350293)
|
||||
|
||||
10、消息中间件 RabbitMQ √
|
||||
|
||||
11、分布式任务 xxl-job √
|
||||
|
||||
12、分布式事务 Seata
|
||||
|
||||
13、分布式日志 elk + kafka
|
||||
|
||||
14、支持 docker-compose、k8s、jenkins
|
||||
|
||||
15、CAS 单点登录 √
|
||||
|
||||
16、路由限流 √
|
||||
|
||||
|
||||
#### 微服务架构图
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
开源版与企业版区别?
|
||||
-----------------------------------
|
||||
|
||||
- JeecgBoot开源版采用 [Apache-2.0 license](LICENSE) 协议附加补充条款:允许商用使用,不会造成侵权行为,允许基于本平台软件开展业务系统开发(但在任何情况下,您不得使用本软件开发可能被认为与本软件竞争的软件).
|
||||
- 商业版与开源版主要区别在于商业版提供了技术支持 和 更多的企业级功能(例如:Online图表、流程监控、流程设计、流程审批、表单设计器、表单视图、积木报表企业版、OA办公、商业APP、零代码应用、Online模块源码等功能). [更多商业功能介绍,点击查看](README-Enterprise.md)
|
||||
- JeecgBoot未来发展方向是:零代码平台的建设,也就是团队的另外一款产品 [敲敲云零代码](https://www.qiaoqiaoyun.com) ,无需编码即可通过拖拽快速搭建企业级应用,与JeecgBoot低代码平台形成互补,满足从简单业务到复杂系统的全场景开发需求,目前已经开源,[欢迎下载](https://qiaoqiaoyun.com/downloadCode)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Jeecg Boot 产品功能蓝图
|
||||

|
||||
|
||||
|
||||
|
||||
#### 系统功能架构图
|
||||
|
||||
### 功能模块
|
||||

|
||||
|
||||
|
||||
|
||||
### 开源版功能清单
|
||||
```
|
||||
├─系统管理
|
||||
│ ├─用户管理
|
||||
│ ├─角色管理
|
||||
│ ├─菜单管理
|
||||
│ ├─首页配置
|
||||
│ ├─权限设置(支持按钮权限、数据权限)
|
||||
│ ├─表单权限(控制字段禁用、隐藏)
|
||||
│ ├─部门管理
|
||||
@ -295,7 +273,37 @@ Docker启动项目
|
||||
│ └─系统公告
|
||||
│ └─职务管理
|
||||
│ └─通讯录
|
||||
│ └─多租户管理
|
||||
│ ├─多数据源管理
|
||||
│ ├─白名单管理
|
||||
│ ├─第三方配置(对接钉钉和企业微信)
|
||||
│ └─多租户管理(租户管理、租户角色、我的租户、租户默认套餐管理)
|
||||
├─Online在线开发(低代码)
|
||||
│ ├─Online在线表单
|
||||
│ ├─Online代码生成器
|
||||
│ ├─Online在线报表
|
||||
│ ├─仪表盘设计器
|
||||
│ ├─系统编码规则
|
||||
│ ├─系统校验规则
|
||||
│ ├─APP版本管理
|
||||
├─AI应用平台
|
||||
│ ├─AI知识库问答系统
|
||||
│ ├─AI大模型管理
|
||||
│ ├─AI流程编排
|
||||
│ ├─AI流程设计器
|
||||
│ ├─AI对话支持图片
|
||||
│ ├─AI对话助手(智能问答)
|
||||
│ ├─AI建表(Online表单)
|
||||
│ ├─AI聊天窗口支持嵌入第三方
|
||||
│ ├─AI聊天窗口支持移动端
|
||||
│ ├─支持常见大模型ChatGPT和DeepSeek、ollama等等
|
||||
│ ├─AI OCR示例
|
||||
├─数据可视化
|
||||
│ ├─报表设计器(支持打印设计)
|
||||
│ ├─大屏设和仪表盘设计
|
||||
├─OpenAPI(基于AK和SK认证鉴权)
|
||||
│ ├─接口管理
|
||||
│ ├─接口授权
|
||||
│ ├─接口文档
|
||||
├─消息中心
|
||||
│ ├─消息管理
|
||||
│ ├─模板管理
|
||||
@ -307,8 +315,12 @@ Docker启动项目
|
||||
│ ├─高级查询器(弹窗自动组合查询条件)
|
||||
│ ├─Excel导入导出工具集成(支持单表,一对多 导入导出)
|
||||
│ ├─平台移动自适应支持
|
||||
│ ├─提供新版uniapp3的代码生成器模板
|
||||
├─系统监控
|
||||
│ ├─Gateway路由网关
|
||||
│ ├─基于AK和SK认证鉴权OpenAPI功能
|
||||
│ ├─定时任务
|
||||
│ ├─数据源管理
|
||||
│ ├─性能扫描监控
|
||||
│ │ ├─监控 Redis
|
||||
│ │ ├─Tomcat
|
||||
@ -316,13 +328,11 @@ Docker启动项目
|
||||
│ │ ├─服务器信息
|
||||
│ │ ├─请求追踪
|
||||
│ │ ├─磁盘监控
|
||||
│ ├─定时任务
|
||||
│ ├─系统日志
|
||||
│ ├─消息中心(支持短信、邮件、微信推送等等)
|
||||
│ ├─数据日志(记录数据快照,可对比快照,查看数据变更情况)
|
||||
│ ├─系统通知
|
||||
│ ├─SQL监控
|
||||
│ ├─swagger-ui(在线接口文档)
|
||||
│ ├─在线用户
|
||||
│─报表示例
|
||||
│ ├─曲线图
|
||||
│ └─饼状图
|
||||
@ -384,82 +394,78 @@ Docker启动项目
|
||||
│ └─异常页面
|
||||
│ └─个人页面
|
||||
├─高级功能
|
||||
│ ├─系统编码规则
|
||||
│ ├─提供单点登录CAS集成方案
|
||||
│ ├─提供APP发布方案
|
||||
│ ├─集成Websocket消息通知机制
|
||||
├─Online在线开发(低代码)
|
||||
│ ├─Online在线表单 - 功能已开放
|
||||
│ ├─Online代码生成器 - 功能已开放
|
||||
│ ├─Online在线报表 - 功能已开放
|
||||
│ ├─Online在线图表(未开源)
|
||||
│ ├─Online图表模板配置(未开源)
|
||||
│ ├─Online布局设计(未开源)
|
||||
│ ├─多数据源管理 - 功能已开放
|
||||
├─积木报表设计器(低代码)
|
||||
│ ├─打印设计器
|
||||
│ ├─数据报表设计
|
||||
│ ├─图形报表设计(支持echart)
|
||||
│ ├─大屏设计器(未开源)
|
||||
│─流程模块功能 (未开源)
|
||||
│ ├─流程设计器
|
||||
│ ├─表单设计器
|
||||
├─大屏设计器
|
||||
├─门户设计/仪表盘设计器
|
||||
│ └─我的任务
|
||||
│ └─历史流程
|
||||
│ └─历史流程
|
||||
│ └─流程实例管理
|
||||
│ └─流程监听管理
|
||||
│ └─流程表达式
|
||||
│ └─我发起的流程
|
||||
│ └─我的抄送
|
||||
│ └─流程委派、抄送、跳转
|
||||
│ └─。。。
|
||||
│─OA办公组件 (未开源)
|
||||
│ ├─更多功能
|
||||
│ └─。。。
|
||||
└─其他模块
|
||||
└─更多功能开发中。。
|
||||
|
||||
│ ├─支持electron桌面应用打包(支持windows、linux、macOS三大平台)
|
||||
│ ├─docker容器支持
|
||||
│ ├─提供移动APP框架及源码(Uniapp3版本)支持H5、小程序、APP、鸿蒙Next
|
||||
│ ├─提供移动APP低代码设计(Online表单、仪表盘)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
系统效果
|
||||
----
|
||||
##### 大屏模板
|
||||

|
||||
|
||||

|
||||
### 系统效果
|
||||
|
||||
##### PC端
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
##### 系统交互
|
||||

|
||||
|
||||
##### 在线接口文档
|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
##### 报表
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
##### AI功能
|
||||
|
||||
##### 流程
|
||||

|
||||

|
||||

|
||||

|
||||
AI聊天助手
|
||||
|
||||

|
||||
|
||||
AI建表
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
AI写文章
|
||||
|
||||

|
||||
|
||||
|
||||
##### 仪表盘设计器
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### 报表设计器
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### 手机端
|
||||
@ -469,10 +475,45 @@ Docker启动项目
|
||||
##### PAD端
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
##### 图表示例
|
||||

|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
##### 在线接口文档
|
||||

|
||||

|
||||
|
||||
|
||||
##### UNIAPP效果
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
##### 大屏设计器
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 捐赠
|
||||
|
||||
如果觉得还不错,请作者喝杯咖啡吧 ☺
|
||||
|
||||
216
check_jeecgenv.py
Normal file
216
check_jeecgenv.py
Normal file
@ -0,0 +1,216 @@
|
||||
import os
|
||||
import subprocess
|
||||
import re
|
||||
import sys
|
||||
from typing import Tuple, Optional
|
||||
|
||||
def run_command(cmd: str) -> Tuple[int, str]:
|
||||
"""执行命令并返回退出码和输出"""
|
||||
try:
|
||||
result = subprocess.run(cmd, shell=True, check=False,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
text=True)
|
||||
return result.returncode, result.stdout.strip()
|
||||
except Exception as e:
|
||||
return -1, str(e)
|
||||
|
||||
def check_java() -> bool:
|
||||
"""检查JDK 17+是否安装"""
|
||||
print("\n检查JDK 17+...")
|
||||
rc, output = run_command("java -version 2>&1")
|
||||
if rc != 0:
|
||||
print("❌ 未检测到Java,请安装JDK 17+")
|
||||
return False
|
||||
|
||||
version_pattern = r'"(\d+)(?:\.\d+)*(?:_\d+)?'
|
||||
match = re.search(version_pattern, output)
|
||||
if not match:
|
||||
print("❌ 无法解析Java版本")
|
||||
return False
|
||||
|
||||
version = int(match.group(1))
|
||||
if version >= 17:
|
||||
print(f"✅ JDK版本 {version} (满足17+要求)")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ JDK版本 {version} (需要17+)")
|
||||
return False
|
||||
|
||||
def check_maven() -> bool:
|
||||
"""检查Maven是否安装"""
|
||||
print("\n检查Maven...")
|
||||
rc, output = run_command("mvn -v")
|
||||
if rc == 0:
|
||||
print("✅ Maven已安装")
|
||||
return True
|
||||
else:
|
||||
print("❌ Maven未安装")
|
||||
return False
|
||||
|
||||
def check_node() -> bool:
|
||||
"""检查Node.js 20+是否安装"""
|
||||
print("\n检查Node.js 20+...")
|
||||
rc, output = run_command("node -v")
|
||||
if rc != 0:
|
||||
print("❌ Node.js未安装")
|
||||
return False
|
||||
|
||||
version_pattern = r'v(\d+)\.\d+\.\d+'
|
||||
match = re.search(version_pattern, output)
|
||||
if not match:
|
||||
print("❌ 无法解析Node.js版本")
|
||||
return False
|
||||
|
||||
version = int(match.group(1))
|
||||
if version >= 20:
|
||||
print(f"✅ Node.js版本 {version} (满足20+要求)")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ Node.js版本 {version} (需要20+)")
|
||||
return False
|
||||
|
||||
def check_pnpm() -> bool:
|
||||
"""检查PNPM 9+是否安装"""
|
||||
print("\n检查PNPM 9+...")
|
||||
rc, output = run_command("pnpm -v")
|
||||
if rc != 0:
|
||||
print("❌ PNPM未安装")
|
||||
return False
|
||||
|
||||
try:
|
||||
# 处理可能的版本号格式:v9.0.0 或 9.0.0 或 9
|
||||
version_str = output.strip().lstrip('v').split('.')[0]
|
||||
version = int(version_str)
|
||||
|
||||
if version >= 9:
|
||||
print(f"✅ PNPM版本 {output.strip()} (满足9+要求)")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ PNPM版本 {output.strip()} (需要9+)")
|
||||
return False
|
||||
except (ValueError, IndexError):
|
||||
print(f"❌ 无法解析PNPM版本: {output.strip()}")
|
||||
return False
|
||||
|
||||
def check_redis_connection() -> bool:
|
||||
"""检查Redis连接"""
|
||||
print("\n检查Redis连接...")
|
||||
print("⚠️ 请确保已配置Redis连接信息并在jeecg-boot项目中正确配置")
|
||||
print("⚠️ 此检查需要根据实际项目配置进行验证")
|
||||
print("⚠️ 配置文件位置: jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml")
|
||||
return True
|
||||
|
||||
def check_mysql_connection() -> bool:
|
||||
"""检查MySQL连接"""
|
||||
print("\n检查MySQL连接...")
|
||||
print("⚠️ 请确保已配置MySQL连接信息并在jeecg-boot项目中正确配置")
|
||||
print("⚠️ 此检查需要根据实际项目配置进行验证")
|
||||
print("⚠️ 配置文件位置: jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml")
|
||||
return True
|
||||
|
||||
def print_mysql_config():
|
||||
"""打印MySQL配置并提示需要修改的位置"""
|
||||
print("\nMySQL配置参考 (请检查以下配置是否正确):")
|
||||
print("""
|
||||
spring.datasource.dynamic.datasource:
|
||||
master:
|
||||
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
|
||||
username: root # ← 可能需要修改
|
||||
password: root # ← 可能需要修改
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
""")
|
||||
|
||||
def check_ai_vector_db() -> bool:
|
||||
"""检查AI向量库(pgvector)配置"""
|
||||
print("\n检查AI知识库向量库配置...")
|
||||
print("⚠️ 如果需要使用AI知识库功能,请配置pgvector向量库")
|
||||
print("⚠️ 配置文件位置: jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml")
|
||||
print("\n配置参考:")
|
||||
print("""
|
||||
jeecg.ai-rag:
|
||||
embed-store:
|
||||
host: 127.0.0.1 # ← 可能需要修改
|
||||
port: 5432 # ← 可能需要修改
|
||||
database: postgres # ← 可能需要修改
|
||||
user: postgres # ← 可能需要修改
|
||||
password: postgres # ← 可能需要修改
|
||||
table: embeddings # ← 可能需要修改
|
||||
""")
|
||||
print("⚠️ 注意: 请确保已安装PostgreSQL并添加pgvector扩展!docker安装参考:https://help.jeecg.com/aigc/config")
|
||||
return True
|
||||
|
||||
def check_ai_config() -> bool:
|
||||
"""检查AI账号配置"""
|
||||
print("\n检查AI功能配置...")
|
||||
print("⚠️ 如果需要使用AI聊天功能,请配置AI账号信息")
|
||||
print("⚠️ 配置文件位置: jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml")
|
||||
print("\n配置参考:")
|
||||
print("""
|
||||
jeecg:
|
||||
# AI集成
|
||||
ai-chat:
|
||||
enabled: true # ← 启用AI功能
|
||||
model: deepseek-chat # ← 模型名称
|
||||
apiKey: ?? # ← 必须修改为您的API Key
|
||||
apiHost: https://api.deepseek.com/v1 # ← API地址
|
||||
timeout: 60 # ← 超时时间(秒)
|
||||
""")
|
||||
print("⚠️ 注意: 请确保已获取有效的API Key并正确配置!AI账号注册获取参考: https://help.jeecg.com/java/deepSeekSupport")
|
||||
return True
|
||||
|
||||
|
||||
def print_redis_config():
|
||||
"""打印Redis配置并提示需要修改的位置"""
|
||||
print("\nRedis配置参考 (请检查以下配置是否正确):")
|
||||
print("""
|
||||
spring.redis:
|
||||
database: 0
|
||||
host: 127.0.0.1 # ← 可能需要修改
|
||||
port: 6379 # ← 可能需要修改
|
||||
password: '' # ← 如果需要密码请修改
|
||||
""")
|
||||
|
||||
def main():
|
||||
print("="*50)
|
||||
print("JeecgBoot 运行环境检查脚本")
|
||||
print("="*50)
|
||||
|
||||
all_checks_passed = True
|
||||
|
||||
# 检查各项依赖
|
||||
if not check_java():
|
||||
all_checks_passed = False
|
||||
|
||||
if not check_maven():
|
||||
all_checks_passed = False
|
||||
|
||||
if not check_node():
|
||||
all_checks_passed = False
|
||||
|
||||
if not check_pnpm():
|
||||
all_checks_passed = False
|
||||
|
||||
# 数据库提示
|
||||
print("="*50)
|
||||
check_redis_connection()
|
||||
print_redis_config()
|
||||
print("="*50)
|
||||
check_mysql_connection()
|
||||
print_mysql_config()
|
||||
print("="*50)
|
||||
check_ai_config()
|
||||
print("="*50)
|
||||
check_ai_vector_db()
|
||||
|
||||
print("\n" + "="*50)
|
||||
if all_checks_passed:
|
||||
print("✅ 所有基础环境检查通过")
|
||||
print("⚠️ 注意: 请确保Redis和MySQL、AI账号、向量库pgvector 已正确配置并连接成功")
|
||||
else:
|
||||
print("❌ 部分环境检查未通过,请根据上述提示解决问题")
|
||||
|
||||
print("="*50)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
input("\n按回车键退出...") # 等待用户输入
|
||||
@ -1,13 +0,0 @@
|
||||
FROM mysql:8.0.19
|
||||
|
||||
MAINTAINER jeecgos@163.com
|
||||
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
COPY ./tables_nacos.sql /docker-entrypoint-initdb.d
|
||||
|
||||
COPY ./jeecgboot-mysql-5.7.sql /docker-entrypoint-initdb.d
|
||||
|
||||
COPY ./tables_xxl_job.sql /docker-entrypoint-initdb.d
|
||||
File diff suppressed because one or more lines are too long
@ -1,311 +0,0 @@
|
||||
CREATE database if NOT EXISTS `nacos` default character set utf8mb4 collate utf8mb4_general_ci;
|
||||
use `nacos`;
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : mysql5.7
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 50738
|
||||
Source Host : 127.0.0.1:3306
|
||||
Source Schema : nacos-os
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 50738
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 06/08/2022 15:12:35
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for config_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `config_info`;
|
||||
CREATE TABLE `config_info` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
|
||||
`group_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
|
||||
`md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
|
||||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
|
||||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
|
||||
`src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
|
||||
`src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
|
||||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
|
||||
`c_desc` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`c_use` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`effect` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`type` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`c_schema` text CHARACTER SET utf8 COLLATE utf8_bin NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_configinfo_datagrouptenant`(`data_id`, `group_id`, `tenant_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 43 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of config_info
|
||||
-- ----------------------------
|
||||
INSERT INTO `config_info` VALUES (1, 'jeecg-dev.yaml', 'DEFAULT_GROUP', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', 'edb0e79d570edf341755caf3853f11e4', '2021-03-03 13:01:11', '2022-08-06 07:10:17', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '');
|
||||
INSERT INTO `config_info` VALUES (2, 'jeecg.yaml', 'DEFAULT_GROUP', 'server:\n tomcat:\n max-swallow-size: -1\n error:\n include-exception: true\n include-stacktrace: ALWAYS\n include-message: ALWAYS\n compression:\n enabled: true\n min-response-size: 1024\n mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*\nmanagement:\n health:\n mail:\n enabled: false\n endpoints:\n web:\n exposure:\n include: \"*\"\n health:\n sensitive: true\n endpoint:\n health:\n show-details: ALWAYS\nspring:\n servlet:\n multipart:\n max-file-size: 10MB\n max-request-size: 10MB\n mail:\n host: smtp.163.com\n username: jeecgos@163.com\n password: ??\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n quartz:\n job-store-type: jdbc\n initialize-schema: embedded\n auto-startup: false\n startup-delay: 1s\n overwrite-existing-jobs: true\n properties:\n org:\n quartz:\n scheduler:\n instanceName: MyScheduler\n instanceId: AUTO\n jobStore:\n class: org.springframework.scheduling.quartz.LocalDataSourceJobStore\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n misfireThreshold: 12000\n clusterCheckinInterval: 15000\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 10\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n time-zone: GMT+8\n aop:\n proxy-target-class: true\n activiti:\n check-process-definitions: false\n async-executor-activate: false\n job-executor-activate: false\n jpa:\n open-in-view: false\n freemarker:\n suffix: .ftl\n content-type: text/html\n charset: UTF-8\n cache: false\n prefer-file-system-access: false\n template-loader-path:\n - classpath:/templates\n mvc:\n static-path-pattern: /**\n pathmatch:\n matching-strategy: ant_path_matcher\n resource:\n static-locations: classpath:/static/,classpath:/public/\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\nmybatis-plus:\n mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: ASSIGN_ID\n table-underline: true\n configuration:\n call-setters-on-nulls: true', '2117a96ba08e8fd0f66825e87416af27', '2021-03-03 13:01:42', '2022-08-05 13:12:21', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '');
|
||||
INSERT INTO `config_info` VALUES (3, 'jeecg-gateway-router.json', 'DEFAULT_GROUP', '[{\n \"id\": \"jeecg-system\",\n \"order\": 0,\n \"predicates\": [{\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/sys/**\",\n \"_genkey_1\": \"/jmreport/**\",\n \"_genkey_3\": \"/online/**\",\n \"_genkey_4\": \"/generic/**\"\n }\n }],\n \"filters\": [],\n \"uri\": \"lb://jeecg-system\"\n}, {\n \"id\": \"jeecg-demo\",\n \"order\": 1,\n \"predicates\": [{\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/mock/**\",\n \"_genkey_1\": \"/test/**\",\n \"_genkey_2\": \"/bigscreen/template1/**\",\n \"_genkey_3\": \"/bigscreen/template2/**\"\n }\n }],\n \"filters\": [],\n \"uri\": \"lb://jeecg-demo\"\n}, {\n \"id\": \"jeecg-system-websocket\",\n \"order\": 2,\n \"predicates\": [{\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/websocket/**\",\n \"_genkey_1\": \"/newsWebsocket/**\"\n }\n }],\n \"filters\": [],\n \"uri\": \"lb:ws://jeecg-system\"\n}, {\n \"id\": \"jeecg-demo-websocket\",\n \"order\": 3,\n \"predicates\": [{\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/vxeSocket/**\"\n }\n }],\n \"filters\": [],\n \"uri\": \"lb:ws://jeecg-demo\"\n}]', 'be6548051d99309d7fa5ac4398404201', '2021-03-03 13:02:14', '2022-02-23 11:49:01', NULL, '0:0:0:0:0:0:0:1', '', '', '', '', '', 'json', '');
|
||||
INSERT INTO `config_info` VALUES (20, 'jeecg-gateway-dev.yaml', 'DEFAULT_GROUP', 'jeecg:\n route:\n config:\n #type:database nacos yml\n data-type: database\n group: DEFAULT_GROUP\n data-id: jeecg-gateway-router\nspring:\n redis:\n database: 0\n host: jeecg-boot-redis\n port: 6379\n password:', '0fc619d2d5e304f18bc4ea8be99f68a4', '2022-08-04 16:36:11', '2022-08-06 07:11:34', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', '');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for config_info_aggr
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `config_info_aggr`;
|
||||
CREATE TABLE `config_info_aggr` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
|
||||
`group_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
|
||||
`datum_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'datum_id',
|
||||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '内容',
|
||||
`gmt_modified` datetime NOT NULL COMMENT '修改时间',
|
||||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_configinfoaggr_datagrouptenantdatum`(`data_id`, `group_id`, `tenant_id`, `datum_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '增加租户字段' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of config_info_aggr
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for config_info_beta
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `config_info_beta`;
|
||||
CREATE TABLE `config_info_beta` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
|
||||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
|
||||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
|
||||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
|
||||
`beta_ips` varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'betaIps',
|
||||
`md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
|
||||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
|
||||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
|
||||
`src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
|
||||
`src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
|
||||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_configinfobeta_datagrouptenant`(`data_id`, `group_id`, `tenant_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info_beta' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of config_info_beta
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for config_info_tag
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `config_info_tag`;
|
||||
CREATE TABLE `config_info_tag` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
|
||||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
|
||||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
|
||||
`tag_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'tag_id',
|
||||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
|
||||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
|
||||
`md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
|
||||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
|
||||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
|
||||
`src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
|
||||
`src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_configinfotag_datagrouptenanttag`(`data_id`, `group_id`, `tenant_id`, `tag_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info_tag' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of config_info_tag
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for config_tags_relation
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `config_tags_relation`;
|
||||
CREATE TABLE `config_tags_relation` (
|
||||
`id` bigint(20) NOT NULL COMMENT 'id',
|
||||
`tag_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'tag_name',
|
||||
`tag_type` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'tag_type',
|
||||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
|
||||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
|
||||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
|
||||
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`nid`) USING BTREE,
|
||||
UNIQUE INDEX `uk_configtagrelation_configidtag`(`id`, `tag_name`, `tag_type`) USING BTREE,
|
||||
INDEX `idx_tenant_id`(`tenant_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_tag_relation' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of config_tags_relation
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for group_capacity
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `group_capacity`;
|
||||
CREATE TABLE `group_capacity` (
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
|
||||
`quota` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '配额,0表示使用默认值',
|
||||
`usage` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用量',
|
||||
`max_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
|
||||
`max_aggr_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '聚合子配置最大个数,,0表示使用默认值',
|
||||
`max_aggr_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
|
||||
`max_history_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大变更历史数量',
|
||||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
|
||||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_group_id`(`group_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '集群、各Group容量信息表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of group_capacity
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for his_config_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `his_config_info`;
|
||||
CREATE TABLE `his_config_info` (
|
||||
`id` bigint(20) UNSIGNED NOT NULL,
|
||||
`nid` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
|
||||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
`md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
|
||||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
|
||||
`src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL,
|
||||
`src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`op_type` char(10) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
|
||||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
|
||||
PRIMARY KEY (`nid`) USING BTREE,
|
||||
INDEX `idx_gmt_create`(`gmt_create`) USING BTREE,
|
||||
INDEX `idx_gmt_modified`(`gmt_modified`) USING BTREE,
|
||||
INDEX `idx_did`(`data_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 91 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '多租户改造' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of his_config_info
|
||||
-- ----------------------------
|
||||
INSERT INTO `his_config_info` VALUES (20, 70, 'jeecg-gateway-dev.yaml', 'DEFAULT_GROUP', '', 'jeecg:\n route:\n config:\n #mode: database、nacos、yml\n data-type: database\n #nacos: jeecg-gateway-router.json\n group: DEFAULT_GROUP\n data-id: jeecg-gateway-router\nspring:\n redis:\n database: 0\n host: jeecg-boot-redis\n port: 6379\n password:', '26fff601e10bbc8bc5ff1fa2b192087b', '2010-05-05 00:00:00', '2022-08-05 10:45:21', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 71, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao :\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg :\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path :\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: 127.0.0.1:9200\n check-enabled: false\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\n\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n # agent-app-secret: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '17b0553ae2ade6474301e3d4eca6f05e', '2010-05-05 00:00:00', '2022-08-05 10:54:54', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 72, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: 127.0.0.1:9200\n check-enabled: false\n desform:\n theme-color: \'#1890ff\'\n upload-type: system\n map:\n baidu: ??\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '70922f6374bf2e4ccf0de8c089445811', '2010-05-05 00:00:00', '2022-08-05 10:57:40', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 73, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n desform:\n theme-color: \'#1890ff\'\n upload-type: system\n map:\n baidu: ??\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '035fff10fc0e5a38abf3c357afff7c67', '2010-05-05 00:00:00', '2022-08-05 10:59:02', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 74, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '87ec968621f8ac532e2fc50f98dd4f57', '2010-05-05 00:00:00', '2022-08-05 11:00:08', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 75, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', 'edb0e79d570edf341755caf3853f11e4', '2010-05-05 00:00:00', '2022-08-05 11:01:10', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 76, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '53b1c1130dff673311ad863b4ce67c8e', '2010-05-05 00:00:00', '2022-08-05 11:02:49', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 77, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '32d655df70c77beb8e39c5d3d8c69c9c', '2010-05-05 00:00:00', '2022-08-05 11:03:31', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 78, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\nsignUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', 'd3b15d3bb35c4baed32f75eabb2bf864', '2010-05-05 00:00:00', '2022-08-05 11:04:54', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 79, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '53b1c1130dff673311ad863b4ce67c8e', '2010-05-05 00:00:00', '2022-08-05 13:02:54', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 80, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true', '92ced3a81dece861666606c44cd4f630', '2010-05-05 00:00:00', '2022-08-05 13:03:28', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 81, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp', '364814ff81fb2a38c869f7bb5aa92f45', '2010-05-05 00:00:00', '2022-08-05 13:03:55', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 82, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379', '064d0471e33d707a5b70e0807f8f0d93', '2010-05-05 00:00:00', '2022-08-05 13:04:39', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (2, 83, 'jeecg.yaml', 'DEFAULT_GROUP', '', 'server:\n tomcat:\n max-swallow-size: -1\n error:\n include-exception: true\n include-stacktrace: ALWAYS\n include-message: ALWAYS\n compression:\n enabled: true\n min-response-size: 1024\n mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*\nmanagement:\n health:\n mail:\n enabled: false\n endpoints:\n web:\n exposure:\n include: \"*\"\n health:\n sensitive: true\n endpoint:\n health:\n show-details: ALWAYS\nspring:\n servlet:\n multipart:\n max-file-size: 10MB\n max-request-size: 10MB\n mail:\n host: smtp.163.com\n username: jeecgos@163.com\n password: ??\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n quartz:\n job-store-type: jdbc\n initialize-schema: embedded\n auto-startup: false\n startup-delay: 1s\n overwrite-existing-jobs: true\n properties:\n org:\n quartz:\n scheduler:\n instanceName: MyScheduler\n instanceId: AUTO\n jobStore:\n class: org.springframework.scheduling.quartz.LocalDataSourceJobStore\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n misfireThreshold: 12000\n clusterCheckinInterval: 15000\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 10\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n time-zone: GMT+8\n aop:\n proxy-target-class: true\n activiti:\n check-process-definitions: false\n async-executor-activate: false\n job-executor-activate: false\n jpa:\n open-in-view: false\n freemarker:\n suffix: .ftl\n content-type: text/html\n charset: UTF-8\n cache: false\n prefer-file-system-access: false\n template-loader-path:\n - classpath:/templates\n mvc:\n static-path-pattern: /**\n pathmatch:\n matching-strategy: ant_path_matcher\n resource:\n static-locations: classpath:/static/,classpath:/public/\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\nmybatis-plus:\n mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: ASSIGN_ID\n table-underline: true\n configuration:\n call-setters-on-nulls: true', '2117a96ba08e8fd0f66825e87416af27', '2010-05-05 00:00:00', '2022-08-05 13:05:34', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 84, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n dynamic:\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379', 'a12eaf6e6c090b303590f1e83c22ac3f', '2010-05-05 00:00:00', '2022-08-05 13:07:33', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 85, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n dynamic:\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379', '5e33b9dc9022eee8a1652e473dadbc42', '2010-05-05 00:00:00', '2022-08-05 13:09:30', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (2, 86, 'jeecg.yaml', 'DEFAULT_GROUP', '', 'server:\n tomcat:\n max-swallow-size: -1', '4525d8351d9498a8e5f43373ee6367a1', '2010-05-05 00:00:00', '2022-08-05 13:09:55', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (2, 87, 'jeecg.yaml', 'DEFAULT_GROUP', '', 'server:\n tomcat:\n max-swallow-size: -1\n error:\n include-exception: true\n include-stacktrace: ALWAYS\n include-message: ALWAYS\n compression:\n enabled: true\n min-response-size: 1024\n mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*\nmanagement:\n health:\n mail:\n enabled: false\n endpoints:\n web:\n exposure:\n include: \"*\"\n health:\n sensitive: true\n endpoint:\n health:\n show-details: ALWAYS\nspring:\n servlet:\n multipart:\n max-file-size: 10MB\n max-request-size: 10MB\n mail:\n host: smtp.163.com\n username: jeecgos@163.com\n password: ??\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n quartz:\n job-store-type: jdbc\n initialize-schema: embedded\n auto-startup: false\n startup-delay: 1s\n overwrite-existing-jobs: true\n properties:\n org:\n quartz:\n scheduler:\n instanceName: MyScheduler\n instanceId: AUTO\n jobStore:\n class: org.springframework.scheduling.quartz.LocalDataSourceJobStore\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n misfireThreshold: 12000\n clusterCheckinInterval: 15000\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 10\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n time-zone: GMT+8\n aop:\n proxy-target-class: true\n activiti:\n check-process-definitions: false\n async-executor-activate: false\n job-executor-activate: false\n jpa:\n open-in-view: false\n freemarker:\n suffix: .ftl\n content-type: text/html\n charset: UTF-8\n cache: false\n prefer-file-system-access: false\n template-loader-path:\n - classpath:/templates\n mvc:\n static-path-pattern: /**\n pathmatch:\n matching-strategy: ant_path_matcher\n resource:\n static-locations: classpath:/static/,classpath:/public/\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\nmybatis-plus:\n mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: ASSIGN_ID\n table-underline: true\n configuration:\n call-setters-on-nulls: true', '2117a96ba08e8fd0f66825e87416af27', '2010-05-05 00:00:00', '2022-08-05 13:10:58', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (2, 88, 'jeecg.yaml', 'DEFAULT_GROUP', '', 'server:\n tomcat:\n max-swallow-size: -1\n error:\n include-exception: true\n include-stacktrace: ALWAYS\n include-message: ALWAYS\n compression:\n enabled: true\n min-response-size: 1024\n mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*\nmanagement:\n health:\n mail:\n enabled: false\n endpoints:\n web:\n exposure:\n include: \"*\"\n health:\n sensitive: true\n endpoint:\n health:\n show-details: ALWAYS\nspring:\n servlet:\n multipart:\n max-file-size: 10MB\n max-request-size: 10MB\n mail:\n host: smtp.163.com\n username: jeecgos@163.com\n password: ??\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n quartz:\n job-store-type: jdbc\n initialize-schema: embedded\n auto-startup: false\n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n time-zone: GMT+8\n aop:\n proxy-target-class: true\n activiti:\n check-process-definitions: false\n async-executor-activate: false\n job-executor-activate: false\n jpa:\n open-in-view: false\n freemarker:\n suffix: .ftl\n content-type: text/html\n charset: UTF-8\n cache: false\n prefer-file-system-access: false\n template-loader-path:\n - classpath:/templates\n mvc:\n static-path-pattern: /**\n pathmatch:\n matching-strategy: ant_path_matcher\n resource:\n static-locations: classpath:/static/,classpath:/public/\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\nmybatis-plus:\n mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: ASSIGN_ID\n table-underline: true\n configuration:\n call-setters-on-nulls: true', 'a1effef2c22a7d2846f84728aa29ecd4', '2010-05-05 00:00:00', '2022-08-05 13:12:21', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (1, 89, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '53b1c1130dff673311ad863b4ce67c8e', '2010-05-05 00:00:00', '2022-08-06 07:10:17', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
INSERT INTO `his_config_info` VALUES (20, 90, 'jeecg-gateway-dev.yaml', 'DEFAULT_GROUP', '', 'jeecg:\n route:\n config:\n #mode:database nacos yml\n data-type: database\n group: DEFAULT_GROUP\n data-id: jeecg-gateway-router\nspring:\n redis:\n database: 0\n host: jeecg-boot-redis\n port: 6379\n password:', 'b08a4c456f508fdd0fc347305da39a9e', '2010-05-05 00:00:00', '2022-08-06 07:11:34', 'nacos', '0:0:0:0:0:0:0:1', 'U', '');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for permissions
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `permissions`;
|
||||
CREATE TABLE `permissions` (
|
||||
`role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`resource` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`action` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
UNIQUE INDEX `uk_role_permission`(`role`, `resource`, `action`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of permissions
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for roles
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `roles`;
|
||||
CREATE TABLE `roles` (
|
||||
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
UNIQUE INDEX `uk_username_role`(`username`, `role`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of roles
|
||||
-- ----------------------------
|
||||
INSERT INTO `roles` VALUES ('nacos', 'ROLE_ADMIN');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tenant_capacity
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `tenant_capacity`;
|
||||
CREATE TABLE `tenant_capacity` (
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Tenant ID',
|
||||
`quota` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '配额,0表示使用默认值',
|
||||
`usage` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用量',
|
||||
`max_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
|
||||
`max_aggr_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '聚合子配置最大个数',
|
||||
`max_aggr_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
|
||||
`max_history_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大变更历史数量',
|
||||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
|
||||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_tenant_id`(`tenant_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '租户容量信息表' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tenant_capacity
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for tenant_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `tenant_info`;
|
||||
CREATE TABLE `tenant_info` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`kp` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'kp',
|
||||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
|
||||
`tenant_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_name',
|
||||
`tenant_desc` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'tenant_desc',
|
||||
`create_source` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'create_source',
|
||||
`gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
|
||||
`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_tenant_info_kptenantid`(`kp`, `tenant_id`) USING BTREE,
|
||||
INDEX `idx_tenant_id`(`tenant_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'tenant_info' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of tenant_info
|
||||
-- ----------------------------
|
||||
INSERT INTO `tenant_info` VALUES (1, '1', 'ac14ab82-51f8-4f0c-aa5b-25fb8384bfb6', 'jeecg', 'jeecg 测试命名空间', 'nacos', 1653291038942, 1653291038942);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for users
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
CREATE TABLE `users` (
|
||||
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`password` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`enabled` tinyint(1) NOT NULL,
|
||||
PRIMARY KEY (`username`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of users
|
||||
-- ----------------------------
|
||||
INSERT INTO `users` VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', 1);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@ -1,119 +0,0 @@
|
||||
#
|
||||
# XXL-JOB v2.2.0
|
||||
# Copyright (c) 2015-present, xuxueli.
|
||||
|
||||
CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_general_ci;
|
||||
use `xxl_job`;
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE TABLE `xxl_job_info` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
|
||||
`job_cron` varchar(128) NOT NULL COMMENT '任务执行CRON',
|
||||
`job_desc` varchar(255) NOT NULL,
|
||||
`add_time` datetime DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
`author` varchar(64) DEFAULT NULL COMMENT '作者',
|
||||
`alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
|
||||
`executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
|
||||
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
|
||||
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
|
||||
`executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
|
||||
`executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
|
||||
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
|
||||
`glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
|
||||
`glue_source` mediumtext COMMENT 'GLUE源代码',
|
||||
`glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
|
||||
`glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
|
||||
`child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
|
||||
`trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
|
||||
`trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
|
||||
`trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `xxl_job_log` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
|
||||
`job_id` int(11) NOT NULL COMMENT '任务,主键ID',
|
||||
`executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
|
||||
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
|
||||
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
|
||||
`executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
|
||||
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
|
||||
`trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
|
||||
`trigger_code` int(11) NOT NULL COMMENT '调度-结果',
|
||||
`trigger_msg` text COMMENT '调度-日志',
|
||||
`handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
|
||||
`handle_code` int(11) NOT NULL COMMENT '执行-状态',
|
||||
`handle_msg` text COMMENT '执行-日志',
|
||||
`alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `I_trigger_time` (`trigger_time`),
|
||||
KEY `I_handle_code` (`handle_code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `xxl_job_log_report` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`trigger_day` datetime DEFAULT NULL COMMENT '调度-时间',
|
||||
`running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
|
||||
`suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
|
||||
`fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `xxl_job_logglue` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`job_id` int(11) NOT NULL COMMENT '任务,主键ID',
|
||||
`glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
|
||||
`glue_source` mediumtext COMMENT 'GLUE源代码',
|
||||
`glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
|
||||
`add_time` datetime DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `xxl_job_registry` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`registry_group` varchar(50) NOT NULL,
|
||||
`registry_key` varchar(255) NOT NULL,
|
||||
`registry_value` varchar(255) NOT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `xxl_job_group` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
|
||||
`title` varchar(12) NOT NULL COMMENT '执行器名称',
|
||||
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
|
||||
`address_list` varchar(512) DEFAULT NULL COMMENT '执行器地址列表,多地址逗号分隔',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `xxl_job_user` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(50) NOT NULL COMMENT '账号',
|
||||
`password` varchar(50) NOT NULL COMMENT '密码',
|
||||
`role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',
|
||||
`permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `i_username` (`username`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `xxl_job_lock` (
|
||||
`lock_name` varchar(50) NOT NULL COMMENT '锁名称',
|
||||
PRIMARY KEY (`lock_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL);
|
||||
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_cron`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`) VALUES (1, 1, '0 0 0 * * ? *', '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '');
|
||||
INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
|
||||
INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock');
|
||||
|
||||
commit;
|
||||
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +0,0 @@
|
||||
oracle导出编码: export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
|
||||
|
||||
导出用户: jeecgboot
|
||||
|
||||
导入命令: imp scott/tiger@orcl file=jeecgboot-oracle11g.dmp
|
||||
@ -1,6 +0,0 @@
|
||||
ALTER TABLE `onl_cgform_field`
|
||||
MODIFY COLUMN `field_show_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '表单控件类型' AFTER `dict_text`;
|
||||
|
||||
ALTER TABLE `onl_cgform_field`
|
||||
ADD COLUMN `db_is_persist` tinyint(1) NULL COMMENT '是否需要同步数据库字段, 1是0否' AFTER `db_is_null`;
|
||||
update onl_cgform_field set db_is_persist = 1;
|
||||
@ -1,10 +0,0 @@
|
||||
版本升级方法?
|
||||
|
||||
JeecgBoot属于平台级产品,每次升级改动内容较多,目前做不到平滑升级。
|
||||
|
||||
这里给用户的升级建议是这样的:
|
||||
1.代码升级 => 本地版本通过svn或者git做好主干,在分支上做业务开发,jeecg每次版本发布,可以手工覆盖主干的代码,对比代码进行提交;
|
||||
2.数据库升级 => 针对数据库我们每次发布会提供增量升级SQL,可以通过增量SQL实现数据库的升级。
|
||||
3.兼容问题 => 每次版本发布会针对不兼容地方标注说明,需要手工修改不兼容的代码。
|
||||
|
||||
注意: 升级sql目前只提供mysql版本,执行完脚步后,新菜单需要手工进行角色授权,刷新首页才会出现。
|
||||
154
docker-compose-cloud.yml
Normal file
154
docker-compose-cloud.yml
Normal file
@ -0,0 +1,154 @@
|
||||
version: '2'
|
||||
services:
|
||||
jeecg-boot-mysql:
|
||||
build:
|
||||
context: ./jeecg-boot/db
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_ROOT_HOST: '%'
|
||||
TZ: Asia/Shanghai
|
||||
restart: always
|
||||
container_name: jeecg-boot-mysql
|
||||
image: jeecg-boot-mysql
|
||||
command:
|
||||
--character-set-server=utf8mb4
|
||||
--collation-server=utf8mb4_general_ci
|
||||
--explicit_defaults_for_timestamp=true
|
||||
--lower_case_table_names=1
|
||||
--max_allowed_packet=128M
|
||||
--default-authentication-plugin=caching_sha2_password
|
||||
ports:
|
||||
- 13306:3306
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-redis:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/redis:5.0
|
||||
# ports:
|
||||
# - 6379:6379
|
||||
restart: always
|
||||
hostname: jeecg-boot-redis
|
||||
container_name: jeecg-boot-redis
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-pgvector:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/pgvector
|
||||
container_name: jeecg-boot-pgvector
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: vector_db
|
||||
ports:
|
||||
- 5432:5432
|
||||
restart: always
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-nacos:
|
||||
restart: always
|
||||
build:
|
||||
context: ./jeecg-boot/jeecg-server-cloud/jeecg-cloud-nacos
|
||||
ports:
|
||||
- 8848:8848
|
||||
container_name: jeecg-boot-nacos
|
||||
depends_on:
|
||||
- jeecg-boot-mysql
|
||||
hostname: jeecg-boot-nacos
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-system:
|
||||
depends_on:
|
||||
- jeecg-boot-nacos
|
||||
build:
|
||||
context: ./jeecg-boot/jeecg-server-cloud/jeecg-system-cloud-start
|
||||
container_name: jeecg-system-start
|
||||
hostname: jeecg-boot-system
|
||||
restart: on-failure
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-demo:
|
||||
depends_on:
|
||||
- jeecg-boot-nacos
|
||||
build:
|
||||
context: ./jeecg-boot/jeecg-server-cloud/jeecg-demo-cloud-start
|
||||
container_name: jeecg-demo-start
|
||||
hostname: jeecg-boot-demo
|
||||
restart: on-failure
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-gateway:
|
||||
restart: on-failure
|
||||
build:
|
||||
context: ./jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway
|
||||
ports:
|
||||
- 9999:9999
|
||||
depends_on:
|
||||
- jeecg-boot-nacos
|
||||
- jeecg-boot-system
|
||||
container_name: jeecg-boot-gateway
|
||||
hostname: jeecg-boot-gateway
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
# jeecg-boot-rabbitmq:
|
||||
# image: rabbitmq:3.7.7-management
|
||||
# ports:
|
||||
# - 5672:5672
|
||||
# - 15672:15672
|
||||
# restart: always
|
||||
# container_name: jeecg-boot-rabbitmq
|
||||
# hostname: jeecg-boot-rabbitmq
|
||||
# environment:
|
||||
# RABBITMQ_DEFAULT_USER: guest
|
||||
# RABBITMQ_DEFAULT_PASS: guest
|
||||
|
||||
jeecg-boot-sentinel:
|
||||
restart: on-failure
|
||||
build:
|
||||
context: ./jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-sentinel
|
||||
ports:
|
||||
- 9000:9000
|
||||
depends_on:
|
||||
- jeecg-boot-nacos
|
||||
- jeecg-boot-demo
|
||||
- jeecg-boot-system
|
||||
- jeecg-boot-gateway
|
||||
container_name: jeecg-boot-sentinel
|
||||
hostname: jeecg-boot-sentinel
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-xxljob:
|
||||
build:
|
||||
context: ./jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob
|
||||
ports:
|
||||
- 9080:9080
|
||||
container_name: jeecg-boot-xxljob
|
||||
hostname: jeecg-boot-xxljob
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-vue:
|
||||
build:
|
||||
context: ./jeecgboot-vue3
|
||||
dockerfile: Dockerfile.cloud
|
||||
container_name: jeecgboot-vue3-nginx
|
||||
image: jeecgboot-vue3
|
||||
depends_on:
|
||||
- jeecg-boot-system
|
||||
networks:
|
||||
- jeecg-boot
|
||||
ports:
|
||||
- 80:80
|
||||
|
||||
networks:
|
||||
jeecg-boot:
|
||||
name: jeecg_boot
|
||||
@ -2,7 +2,7 @@ version: '2'
|
||||
services:
|
||||
jeecg-boot-mysql:
|
||||
build:
|
||||
context: ./db
|
||||
context: ./jeecg-boot/db
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_ROOT_HOST: '%'
|
||||
@ -18,19 +18,36 @@ services:
|
||||
--max_allowed_packet=128M
|
||||
--default-authentication-plugin=caching_sha2_password
|
||||
ports:
|
||||
- 3306:3306
|
||||
- 13306:3306
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-redis:
|
||||
image: redis:5.0
|
||||
ports:
|
||||
- 6379:6379
|
||||
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/redis:5.0
|
||||
# ports:
|
||||
# - 3792:6379
|
||||
restart: always
|
||||
hostname: jeecg-boot-redis
|
||||
container_name: jeecg-boot-redis
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-pgvector:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/pgvector
|
||||
container_name: jeecg-boot-pgvector
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: vector_db
|
||||
ports:
|
||||
- 5432:5432
|
||||
restart: always
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-system:
|
||||
build:
|
||||
context: ./jeecg-module-system/jeecg-system-start
|
||||
context: ./jeecg-boot/jeecg-module-system/jeecg-system-start
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
- jeecg-boot-mysql
|
||||
@ -39,4 +56,21 @@ services:
|
||||
image: jeecg-boot-system
|
||||
hostname: jeecg-boot-system
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 8080:8080
|
||||
networks:
|
||||
- jeecg-boot
|
||||
jeecg-vue:
|
||||
build:
|
||||
context: ./jeecgboot-vue3
|
||||
container_name: jeecgboot-vue3-nginx
|
||||
image: jeecgboot-vue3
|
||||
depends_on:
|
||||
- jeecg-boot-system
|
||||
networks:
|
||||
- jeecg-boot
|
||||
ports:
|
||||
- 80:80
|
||||
|
||||
networks:
|
||||
jeecg-boot:
|
||||
name: jeecg_boot
|
||||
|
||||
@ -1,214 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.4.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!--jeecg-tools-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-common</artifactId>
|
||||
</dependency>
|
||||
<!--集成springmvc框架并实现自动配置 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- websocket -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<!--springboot2.3+ 需引入validation对应的包-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<!--springboot2.6+解决metrics端点不显示jvm信息的问题-->
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- commons -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>${commons.version}</version>
|
||||
</dependency>
|
||||
<!-- freemarker -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis-plus -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- druid -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 动态数据源 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
<version>${dynamic-datasource-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据库驱动 -->
|
||||
<!--mysql-->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql-connector-java.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- sqlserver-->
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>sqljdbc4</artifactId>
|
||||
<version>${sqljdbc4.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- oracle驱动 -->
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
<version>${ojdbc6.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- postgresql驱动 -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgresql.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Quartz定时任务 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--JWT-->
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>${java-jwt.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--shiro-->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring-boot-starter</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<!-- shiro-redis -->
|
||||
<dependency>
|
||||
<groupId>org.crazycake</groupId>
|
||||
<artifactId>shiro-redis</artifactId>
|
||||
<version>${shiro-redis.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- knife4j -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>${knife4j-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成器 -->
|
||||
<!-- 如下载失败,请参考此文档 http://doc.jeecg.com/2043876 -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>codegenerate</artifactId>
|
||||
<version>${codegenerate.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- AutoPoi Excel工具类-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>autopoi-web</artifactId>
|
||||
<version>${autopoi-web.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- mini文件存储服务 -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里云短信 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
|
||||
<version>${aliyun-java-sdk-dysmsapi.version}</version>
|
||||
</dependency>
|
||||
<!-- aliyun oss -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>${aliyun.oss.version}</version>
|
||||
</dependency>
|
||||
<!-- 第三方登录 -->
|
||||
<dependency>
|
||||
<groupId>com.xkcoding.justauth</groupId>
|
||||
<artifactId>justauth-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
<!-- 解决okhttp引用了kotlin,应用启动有警告日志问题 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -1,130 +0,0 @@
|
||||
package org.jeecg.common.api;
|
||||
|
||||
import org.jeecg.common.system.vo.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 通用api
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface CommonAPI {
|
||||
|
||||
/**
|
||||
* 1查询用户角色信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryUserRoles(String username);
|
||||
|
||||
|
||||
/**
|
||||
* 2查询用户权限信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryUserAuths(String username);
|
||||
|
||||
/**
|
||||
* 3根据 id 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceId
|
||||
* @return
|
||||
*/
|
||||
DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId);
|
||||
|
||||
/**
|
||||
* 4根据 code 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceCode
|
||||
* @return
|
||||
*/
|
||||
DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode);
|
||||
|
||||
/**
|
||||
* 5根据用户账号查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public LoginUser getUserByName(String username);
|
||||
|
||||
|
||||
/**
|
||||
* 6字典表的 翻译
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
String translateDictFromTable(String table, String text, String code, String key);
|
||||
|
||||
/**
|
||||
* 7普通字典的翻译
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
String translateDict(String code, String key);
|
||||
|
||||
/**
|
||||
* 8查询数据权限
|
||||
* @param component 组件
|
||||
* @param username 用户名
|
||||
* @param requestPath 前段请求地址
|
||||
* @return
|
||||
*/
|
||||
List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username);
|
||||
|
||||
|
||||
/**
|
||||
* 9查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
SysUserCacheInfo getCacheUser(String username);
|
||||
|
||||
/**
|
||||
* 10获取数据字典
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryDictItemsByCode(String code);
|
||||
|
||||
/**
|
||||
* 获取有效的数据字典项
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryEnableDictItemsByCode(String code);
|
||||
|
||||
/**
|
||||
* 13获取表数据字典
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> queryTableDictItemsByCode(String table, String text, String code);
|
||||
|
||||
/**
|
||||
* 14 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
|
||||
* @param dictCodes 例如:user_status,sex
|
||||
* @param keys 例如:1,2,0
|
||||
* @return
|
||||
*/
|
||||
Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys);
|
||||
|
||||
/**
|
||||
* 15 字典表的 翻译,可批量
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys 多个用逗号分割
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys);
|
||||
|
||||
}
|
||||
@ -1,109 +0,0 @@
|
||||
package org.jeecg.common.api.dto.message;
|
||||
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 普通消息
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Data
|
||||
public class MessageDTO implements Serializable {
|
||||
private static final long serialVersionUID = -5690444483968058442L;
|
||||
|
||||
/**
|
||||
* 发送人(用户登录账户)
|
||||
*/
|
||||
protected String fromUser;
|
||||
|
||||
/**
|
||||
* 发送给(用户登录账户)
|
||||
*/
|
||||
protected String toUser;
|
||||
|
||||
/**
|
||||
* 发送给所有人
|
||||
*/
|
||||
protected Boolean toAll;
|
||||
|
||||
/**
|
||||
* 消息主题
|
||||
*/
|
||||
protected String title;
|
||||
|
||||
/**
|
||||
* 消息内容
|
||||
*/
|
||||
protected String content;
|
||||
|
||||
/**
|
||||
* 消息类型 1:消息 2:系统消息
|
||||
*/
|
||||
protected String category;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
//update-begin---author:taoyan ---date:20220705 for:支持自定义推送类型,邮件、钉钉、企业微信、系统消息-----------
|
||||
|
||||
/**
|
||||
* 模板消息对应的模板编码
|
||||
*/
|
||||
protected String templateCode;
|
||||
/**
|
||||
* 消息类型:org.jeecg.common.constant.enums.MessageTypeEnum
|
||||
* XT("system", "系统消息")
|
||||
* YJ("email", "邮件消息")
|
||||
* DD("dingtalk", "钉钉消息")
|
||||
* QYWX("wechat_enterprise", "企业微信")
|
||||
*/
|
||||
protected String type;
|
||||
|
||||
/**
|
||||
* 是否发送Markdown格式的消息
|
||||
*/
|
||||
protected boolean isMarkdown;
|
||||
|
||||
/**
|
||||
* 解析模板内容 对应的数据
|
||||
*/
|
||||
protected Map<String, Object> data;
|
||||
//update-end---author:taoyan ---date::20220705 for:支持自定义推送类型,邮件、钉钉、企业微信、系统消息-----------
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
|
||||
public MessageDTO(){
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造器1 系统消息
|
||||
*/
|
||||
public MessageDTO(String fromUser,String toUser,String title, String content){
|
||||
this.fromUser = fromUser;
|
||||
this.toUser = toUser;
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
//默认 都是2系统消息
|
||||
this.category = CommonConstant.MSG_CATEGORY_2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造器2 支持设置category 1:消息 2:系统消息
|
||||
*/
|
||||
public MessageDTO(String fromUser,String toUser,String title, String content, String category){
|
||||
this.fromUser = fromUser;
|
||||
this.toUser = toUser;
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public boolean isMarkdown() {
|
||||
return this.isMarkdown;
|
||||
}
|
||||
|
||||
public void setIsMarkdown(boolean isMarkdown) {
|
||||
this.isMarkdown = isMarkdown;
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
package org.jeecg.common.aspect.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import org.jeecg.common.constant.enums.LowAppAopEnum;
|
||||
|
||||
/**
|
||||
* 自动注入low_app_id
|
||||
*
|
||||
* @Author scott
|
||||
* @email jeecgos@163.com
|
||||
* @Date 2022年01月05日
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface AutoLowApp {
|
||||
|
||||
/**
|
||||
* 切面类型(add、delete、db_import等其他操作)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
LowAppAopEnum action();
|
||||
|
||||
/**
|
||||
* 业务类型(cgform等)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String bizType();
|
||||
|
||||
}
|
||||
@ -1,428 +0,0 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
/**
|
||||
* @Description: 通用常量
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface CommonConstant {
|
||||
|
||||
/**
|
||||
* 正常状态
|
||||
*/
|
||||
Integer STATUS_NORMAL = 0;
|
||||
|
||||
/**
|
||||
* 禁用状态
|
||||
*/
|
||||
Integer STATUS_DISABLE = -1;
|
||||
|
||||
/**
|
||||
* 删除标志
|
||||
*/
|
||||
Integer DEL_FLAG_1 = 1;
|
||||
|
||||
/**
|
||||
* 未删除
|
||||
*/
|
||||
Integer DEL_FLAG_0 = 0;
|
||||
|
||||
/**
|
||||
* 系统日志类型: 登录
|
||||
*/
|
||||
int LOG_TYPE_1 = 1;
|
||||
|
||||
/**
|
||||
* 系统日志类型: 操作
|
||||
*/
|
||||
int LOG_TYPE_2 = 2;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 查询
|
||||
*/
|
||||
int OPERATE_TYPE_1 = 1;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 添加
|
||||
*/
|
||||
int OPERATE_TYPE_2 = 2;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 更新
|
||||
*/
|
||||
int OPERATE_TYPE_3 = 3;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 删除
|
||||
*/
|
||||
int OPERATE_TYPE_4 = 4;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 倒入
|
||||
*/
|
||||
int OPERATE_TYPE_5 = 5;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 导出
|
||||
*/
|
||||
int OPERATE_TYPE_6 = 6;
|
||||
|
||||
|
||||
/** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
|
||||
Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
|
||||
/** {@code 200 OK} (HTTP/1.0 - RFC 1945) */
|
||||
Integer SC_OK_200 = 200;
|
||||
|
||||
/**访问权限认证未通过 510*/
|
||||
Integer SC_JEECG_NO_AUTHZ=510;
|
||||
|
||||
/** 登录用户Shiro权限缓存KEY前缀 */
|
||||
public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:";
|
||||
/** 登录用户Token令牌缓存KEY前缀 */
|
||||
String PREFIX_USER_TOKEN = "prefix_user_token_";
|
||||
// /** Token缓存时间:3600秒即一小时 */
|
||||
// int TOKEN_EXPIRE_TIME = 3600;
|
||||
|
||||
/** 登录二维码 */
|
||||
String LOGIN_QRCODE_PRE = "QRCODELOGIN:";
|
||||
String LOGIN_QRCODE = "LQ:";
|
||||
/** 登录二维码token */
|
||||
String LOGIN_QRCODE_TOKEN = "LQT:";
|
||||
|
||||
|
||||
/**
|
||||
* 0:一级菜单
|
||||
*/
|
||||
Integer MENU_TYPE_0 = 0;
|
||||
/**
|
||||
* 1:子菜单
|
||||
*/
|
||||
Integer MENU_TYPE_1 = 1;
|
||||
/**
|
||||
* 2:按钮权限
|
||||
*/
|
||||
Integer MENU_TYPE_2 = 2;
|
||||
|
||||
/**通告对象类型(USER:指定用户,ALL:全体用户)*/
|
||||
String MSG_TYPE_UESR = "USER";
|
||||
String MSG_TYPE_ALL = "ALL";
|
||||
|
||||
/**发布状态(0未发布,1已发布,2已撤销)*/
|
||||
String NO_SEND = "0";
|
||||
String HAS_SEND = "1";
|
||||
String HAS_CANCLE = "2";
|
||||
|
||||
/**阅读状态(0未读,1已读)*/
|
||||
String HAS_READ_FLAG = "1";
|
||||
String NO_READ_FLAG = "0";
|
||||
|
||||
/**优先级(L低,M中,H高)*/
|
||||
String PRIORITY_L = "L";
|
||||
String PRIORITY_M = "M";
|
||||
String PRIORITY_H = "H";
|
||||
|
||||
/**
|
||||
* 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板
|
||||
*/
|
||||
String SMS_TPL_TYPE_0 = "0";
|
||||
String SMS_TPL_TYPE_1 = "1";
|
||||
String SMS_TPL_TYPE_2 = "2";
|
||||
|
||||
/**
|
||||
* 状态(0无效1有效)
|
||||
*/
|
||||
String STATUS_0 = "0";
|
||||
String STATUS_1 = "1";
|
||||
|
||||
/**
|
||||
* 同步工作流引擎1同步0不同步
|
||||
*/
|
||||
Integer ACT_SYNC_1 = 1;
|
||||
Integer ACT_SYNC_0 = 0;
|
||||
|
||||
/**
|
||||
* 消息类型1:通知公告2:系统消息
|
||||
*/
|
||||
String MSG_CATEGORY_1 = "1";
|
||||
String MSG_CATEGORY_2 = "2";
|
||||
|
||||
/**
|
||||
* 是否配置菜单的数据权限 1是0否
|
||||
*/
|
||||
Integer RULE_FLAG_0 = 0;
|
||||
Integer RULE_FLAG_1 = 1;
|
||||
|
||||
/**
|
||||
* 是否用户已被冻结 1正常(解冻) 2冻结
|
||||
*/
|
||||
Integer USER_UNFREEZE = 1;
|
||||
Integer USER_FREEZE = 2;
|
||||
|
||||
/**字典翻译文本后缀*/
|
||||
String DICT_TEXT_SUFFIX = "_dictText";
|
||||
|
||||
/**
|
||||
* 表单设计器主表类型
|
||||
*/
|
||||
Integer DESIGN_FORM_TYPE_MAIN = 1;
|
||||
|
||||
/**
|
||||
* 表单设计器子表表类型
|
||||
*/
|
||||
Integer DESIGN_FORM_TYPE_SUB = 2;
|
||||
|
||||
/**
|
||||
* 表单设计器URL授权通过
|
||||
*/
|
||||
Integer DESIGN_FORM_URL_STATUS_PASSED = 1;
|
||||
|
||||
/**
|
||||
* 表单设计器URL授权未通过
|
||||
*/
|
||||
Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
|
||||
|
||||
/**
|
||||
* 表单设计器新增 Flag
|
||||
*/
|
||||
String DESIGN_FORM_URL_TYPE_ADD = "add";
|
||||
/**
|
||||
* 表单设计器修改 Flag
|
||||
*/
|
||||
String DESIGN_FORM_URL_TYPE_EDIT = "edit";
|
||||
/**
|
||||
* 表单设计器详情 Flag
|
||||
*/
|
||||
String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
|
||||
/**
|
||||
* 表单设计器复用数据 Flag
|
||||
*/
|
||||
String DESIGN_FORM_URL_TYPE_REUSE = "reuse";
|
||||
/**
|
||||
* 表单设计器编辑 Flag (已弃用)
|
||||
*/
|
||||
String DESIGN_FORM_URL_TYPE_VIEW = "view";
|
||||
|
||||
/**
|
||||
* online参数值设置(是:Y, 否:N)
|
||||
*/
|
||||
String ONLINE_PARAM_VAL_IS_TURE = "Y";
|
||||
String ONLINE_PARAM_VAL_IS_FALSE = "N";
|
||||
|
||||
/**
|
||||
* 文件上传类型(本地:local,Minio:minio,阿里云:alioss)
|
||||
*/
|
||||
String UPLOAD_TYPE_LOCAL = "local";
|
||||
String UPLOAD_TYPE_MINIO = "minio";
|
||||
String UPLOAD_TYPE_OSS = "alioss";
|
||||
|
||||
/**
|
||||
* 文档上传自定义桶名称
|
||||
*/
|
||||
String UPLOAD_CUSTOM_BUCKET = "eoafile";
|
||||
/**
|
||||
* 文档上传自定义路径
|
||||
*/
|
||||
String UPLOAD_CUSTOM_PATH = "eoafile";
|
||||
/**
|
||||
* 文件外链接有效天数
|
||||
*/
|
||||
Integer UPLOAD_EFFECTIVE_DAYS = 1;
|
||||
|
||||
/**
|
||||
* 员工身份 (1:普通员工 2:上级)
|
||||
*/
|
||||
Integer USER_IDENTITY_1 = 1;
|
||||
Integer USER_IDENTITY_2 = 2;
|
||||
|
||||
/** sys_user 表 username 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
|
||||
/** sys_user 表 work_no 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no";
|
||||
/** sys_user 表 phone 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
|
||||
/** 达梦数据库升提示。违反表[SYS_USER]唯一性约束 */
|
||||
String SQL_INDEX_UNIQ_SYS_USER = "唯一性约束";
|
||||
|
||||
/** sys_user 表 email 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
|
||||
/** sys_quartz_job 表 job_class_name 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name";
|
||||
/** sys_position 表 code 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_CODE = "uniq_code";
|
||||
/** sys_role 表 code 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
|
||||
/** sys_depart 表 code 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
|
||||
/** sys_category 表 code 唯一键索引 */
|
||||
String SQL_INDEX_UNIQ_CATEGORY_CODE = "idx_sc_code";
|
||||
/**
|
||||
* 在线聊天 是否为默认分组
|
||||
*/
|
||||
String IM_DEFAULT_GROUP = "1";
|
||||
/**
|
||||
* 在线聊天 图片文件保存路径
|
||||
*/
|
||||
String IM_UPLOAD_CUSTOM_PATH = "biz/user_imgs";
|
||||
/**
|
||||
* 在线聊天 用户状态
|
||||
*/
|
||||
String IM_STATUS_ONLINE = "online";
|
||||
|
||||
/**
|
||||
* 在线聊天 SOCKET消息类型
|
||||
*/
|
||||
String IM_SOCKET_TYPE = "chatMessage";
|
||||
|
||||
/**
|
||||
* 在线聊天 是否开启默认添加好友 1是 0否
|
||||
*/
|
||||
String IM_DEFAULT_ADD_FRIEND = "1";
|
||||
|
||||
/**
|
||||
* 在线聊天 用户好友缓存前缀
|
||||
*/
|
||||
String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_";
|
||||
|
||||
/**
|
||||
* 考勤补卡业务状态 (1:同意 2:不同意)
|
||||
*/
|
||||
String SIGN_PATCH_BIZ_STATUS_1 = "1";
|
||||
String SIGN_PATCH_BIZ_STATUS_2 = "2";
|
||||
|
||||
/**
|
||||
* 公文文档上传自定义路径
|
||||
*/
|
||||
String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc";
|
||||
/**
|
||||
* 公文文档下载自定义路径
|
||||
*/
|
||||
String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown";
|
||||
|
||||
/**
|
||||
* WPS存储值类别(1 code文号 2 text(WPS模板还是公文发文模板))
|
||||
*/
|
||||
String WPS_TYPE_1="1";
|
||||
String WPS_TYPE_2="2";
|
||||
|
||||
|
||||
/**===============================================================================================*/
|
||||
/**
|
||||
* ::非常重要::
|
||||
* 注意:这四个常量值如果修改,需要与 jeecg-boot-starter/jeecg-boot-common/org.jeecg.config.FeignConfig 类中的值保持一致。
|
||||
*/
|
||||
String X_ACCESS_TOKEN = "X-Access-Token";
|
||||
String X_SIGN = "X-Sign";
|
||||
String X_TIMESTAMP = "X-TIMESTAMP";
|
||||
/** 租户 请求头*/
|
||||
String TENANT_ID = "tenant-id";
|
||||
/**===============================================================================================*/
|
||||
|
||||
String TOKEN_IS_INVALID_MSG = "Token失效,请重新登录!";
|
||||
String X_FORWARDED_SCHEME = "X-Forwarded-Scheme";
|
||||
|
||||
|
||||
/**
|
||||
* 微服务读取配置文件属性 服务地址
|
||||
*/
|
||||
String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr";
|
||||
|
||||
/**
|
||||
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
|
||||
*/
|
||||
String THIRD_LOGIN_CODE = "third_login_code";
|
||||
|
||||
/**
|
||||
* 第三方APP同步方向:本地 --> 第三方APP
|
||||
*/
|
||||
String THIRD_SYNC_TO_APP = "SYNC_TO_APP";
|
||||
/**
|
||||
* 第三方APP同步方向:第三方APP --> 本地
|
||||
*/
|
||||
String THIRD_SYNC_TO_LOCAL = "SYNC_TO_LOCAL";
|
||||
|
||||
/** 系统通告消息状态:0=未发布 */
|
||||
String ANNOUNCEMENT_SEND_STATUS_0 = "0";
|
||||
/** 系统通告消息状态:1=已发布 */
|
||||
String ANNOUNCEMENT_SEND_STATUS_1 = "1";
|
||||
/** 系统通告消息状态:2=已撤销 */
|
||||
String ANNOUNCEMENT_SEND_STATUS_2 = "2";
|
||||
|
||||
/**ONLINE 报表权限用 从request中获取地址栏后的参数*/
|
||||
String ONL_REP_URL_PARAM_STR="onlRepUrlParamStr";
|
||||
|
||||
/**POST请求*/
|
||||
String HTTP_POST = "POST";
|
||||
|
||||
/**PUT请求*/
|
||||
String HTTP_PUT = "PUT";
|
||||
|
||||
/**PATCH请求*/
|
||||
String HTTP_PATCH = "PATCH";
|
||||
|
||||
/**未知的*/
|
||||
String UNKNOWN = "unknown";
|
||||
|
||||
/**字符串http*/
|
||||
String STR_HTTP = "http";
|
||||
|
||||
/**String 类型的空值*/
|
||||
String STRING_NULL = "null";
|
||||
|
||||
/**前端vue3版本Header参数名*/
|
||||
String VERSION="X-Version";
|
||||
|
||||
/**存储在线程变量里的动态表名*/
|
||||
String DYNAMIC_TABLE_NAME="DYNAMIC_TABLE_NAME";
|
||||
/**
|
||||
* http:// http协议
|
||||
*/
|
||||
String HTTP_PROTOCOL = "http://";
|
||||
|
||||
/**
|
||||
* https:// https协议
|
||||
*/
|
||||
String HTTPS_PROTOCOL = "https://";
|
||||
|
||||
/** 部门表唯一key,id */
|
||||
String DEPART_KEY_ID = "id";
|
||||
/** 部门表唯一key,orgCode */
|
||||
String DEPART_KEY_ORG_CODE = "orgCode";
|
||||
|
||||
/**
|
||||
* 发消息 会传递一些信息到map
|
||||
*/
|
||||
String NOTICE_MSG_SUMMARY = "NOTICE_MSG_SUMMARY";
|
||||
|
||||
/**
|
||||
* 发消息 会传递一个业务ID到map
|
||||
*/
|
||||
String NOTICE_MSG_BUS_ID = "NOTICE_MSG_BUS_ID";
|
||||
|
||||
/**
|
||||
* 邮箱消息中地址登录时地址后携带的token,需要替换成真实的token值
|
||||
*/
|
||||
String LOGIN_TOKEN = "{LOGIN_TOKEN}";
|
||||
|
||||
/**
|
||||
* 模板消息中 跳转地址的对应的key
|
||||
*/
|
||||
String MSG_HREF_URL = "url";
|
||||
|
||||
/**
|
||||
* sys_data_log表的类型 用于区别评论区域的日志数据
|
||||
*/
|
||||
String DATA_LOG_TYPE_COMMENT = "comment";
|
||||
|
||||
/**
|
||||
* sys_data_log表的类型 老的数据比较 类型都设置为json
|
||||
*/
|
||||
String DATA_LOG_TYPE_JSON = "json";
|
||||
|
||||
/** 消息模板:markdown */
|
||||
String MSG_TEMPLATE_TYPE_MD = "5";
|
||||
|
||||
/**
|
||||
* 短信验证码redis-key的前缀
|
||||
*/
|
||||
String PHONE_REDIS_KEY_PRE = "phone_msg";
|
||||
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
/**
|
||||
* 系统通告 - 发布状态
|
||||
* @Author LeeShaoQing
|
||||
*
|
||||
*/
|
||||
public interface CommonSendStatus {
|
||||
|
||||
/**
|
||||
* 未发布
|
||||
*/
|
||||
public static final String UNPUBLISHED_STATUS_0 = "0";
|
||||
|
||||
/**
|
||||
* 已发布
|
||||
*/
|
||||
public static final String PUBLISHED_STATUS_1 = "1";
|
||||
|
||||
/**
|
||||
* 撤销
|
||||
*/
|
||||
public static final String REVOKE_STATUS_2 = "2";
|
||||
|
||||
/**
|
||||
* app端推送会话标识后缀
|
||||
*/
|
||||
public static final String APP_SESSION_SUFFIX = "_app";
|
||||
|
||||
|
||||
/**流程催办——系统通知消息模板*/
|
||||
public static final String TZMB_BPM_CUIBAN = "bpm_cuiban";
|
||||
/**流程催办——邮件通知消息模板*/
|
||||
public static final String TZMB_BPM_CUIBAN_EMAIL = "bpm_cuiban_email";
|
||||
/**标准模板—系统消息通知*/
|
||||
public static final String TZMB_SYS_TS_NOTE = "sys_ts_note";
|
||||
/**流程超时提醒——系统通知消息模板*/
|
||||
public static final String TZMB_BPM_CHAOSHI_TIP = "bpm_chaoshi_tip";
|
||||
}
|
||||
@ -1,166 +0,0 @@
|
||||
package org.jeecg.common.constant;
|
||||
/**
|
||||
* 数据库上下文常量
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface DataBaseConstant {
|
||||
//*********数据库类型****************************************
|
||||
|
||||
/**MYSQL数据库*/
|
||||
public static final String DB_TYPE_MYSQL = "MYSQL";
|
||||
|
||||
/** ORACLE*/
|
||||
public static final String DB_TYPE_ORACLE = "ORACLE";
|
||||
|
||||
/**达梦数据库*/
|
||||
public static final String DB_TYPE_DM = "DM";
|
||||
|
||||
/**postgreSQL达梦数据库*/
|
||||
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
||||
|
||||
/**sqlserver数据库*/
|
||||
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
||||
|
||||
/**mariadb 数据库*/
|
||||
public static final String DB_TYPE_MARIADB = "MARIADB";
|
||||
|
||||
/**DB2 数据库*/
|
||||
public static final String DB_TYPE_DB2 = "DB2";
|
||||
|
||||
/**HSQL 数据库*/
|
||||
public static final String DB_TYPE_HSQL = "HSQL";
|
||||
|
||||
// // 数据库类型,对应 database_type 字典
|
||||
// public static final String DB_TYPE_MYSQL_NUM = "1";
|
||||
// public static final String DB_TYPE_MYSQL7_NUM = "6";
|
||||
// public static final String DB_TYPE_ORACLE_NUM = "2";
|
||||
// public static final String DB_TYPE_SQLSERVER_NUM = "3";
|
||||
// public static final String DB_TYPE_POSTGRESQL_NUM = "4";
|
||||
// public static final String DB_TYPE_MARIADB_NUM = "5";
|
||||
|
||||
//*********系统上下文变量****************************************
|
||||
/**
|
||||
* 数据-所属机构编码
|
||||
*/
|
||||
public static final String SYS_ORG_CODE = "sysOrgCode";
|
||||
/**
|
||||
* 数据-所属机构编码
|
||||
*/
|
||||
public static final String SYS_ORG_CODE_TABLE = "sys_org_code";
|
||||
/**
|
||||
* 数据-所属机构编码
|
||||
*/
|
||||
public static final String SYS_MULTI_ORG_CODE = "sysMultiOrgCode";
|
||||
/**
|
||||
* 数据-所属机构编码
|
||||
*/
|
||||
public static final String SYS_MULTI_ORG_CODE_TABLE = "sys_multi_org_code";
|
||||
/**
|
||||
* 数据-系统用户编码(对应登录用户账号)
|
||||
*/
|
||||
public static final String SYS_USER_CODE = "sysUserCode";
|
||||
/**
|
||||
* 数据-系统用户编码(对应登录用户账号)
|
||||
*/
|
||||
public static final String SYS_USER_CODE_TABLE = "sys_user_code";
|
||||
|
||||
/**
|
||||
* 登录用户真实姓名
|
||||
*/
|
||||
public static final String SYS_USER_NAME = "sysUserName";
|
||||
/**
|
||||
* 登录用户真实姓名
|
||||
*/
|
||||
public static final String SYS_USER_NAME_TABLE = "sys_user_name";
|
||||
/**
|
||||
* 系统日期"yyyy-MM-dd"
|
||||
*/
|
||||
public static final String SYS_DATE = "sysDate";
|
||||
/**
|
||||
* 系统日期"yyyy-MM-dd"
|
||||
*/
|
||||
public static final String SYS_DATE_TABLE = "sys_date";
|
||||
/**
|
||||
* 系统时间"yyyy-MM-dd HH:mm"
|
||||
*/
|
||||
public static final String SYS_TIME = "sysTime";
|
||||
/**
|
||||
* 系统时间"yyyy-MM-dd HH:mm"
|
||||
*/
|
||||
public static final String SYS_TIME_TABLE = "sys_time";
|
||||
/**
|
||||
* 数据-所属机构编码
|
||||
*/
|
||||
public static final String SYS_BASE_PATH = "sys_base_path";
|
||||
//*********系统上下文变量****************************************
|
||||
|
||||
|
||||
//*********系统建表标准字段****************************************
|
||||
/**
|
||||
* 创建者登录名称
|
||||
*/
|
||||
public static final String CREATE_BY_TABLE = "create_by";
|
||||
/**
|
||||
* 创建者登录名称
|
||||
*/
|
||||
public static final String CREATE_BY = "createBy";
|
||||
/**
|
||||
* 创建日期时间
|
||||
*/
|
||||
public static final String CREATE_TIME_TABLE = "create_time";
|
||||
/**
|
||||
* 创建日期时间
|
||||
*/
|
||||
public static final String CREATE_TIME = "createTime";
|
||||
/**
|
||||
* 更新用户登录名称
|
||||
*/
|
||||
public static final String UPDATE_BY_TABLE = "update_by";
|
||||
/**
|
||||
* 更新用户登录名称
|
||||
*/
|
||||
public static final String UPDATE_BY = "updateBy";
|
||||
/**
|
||||
* 更新日期时间
|
||||
*/
|
||||
public static final String UPDATE_TIME = "updateTime";
|
||||
/**
|
||||
* 更新日期时间
|
||||
*/
|
||||
public static final String UPDATE_TIME_TABLE = "update_time";
|
||||
|
||||
/**
|
||||
* 业务流程状态
|
||||
*/
|
||||
public static final String BPM_STATUS = "bpmStatus";
|
||||
/**
|
||||
* 业务流程状态
|
||||
*/
|
||||
public static final String BPM_STATUS_TABLE = "bpm_status";
|
||||
//*********系统建表标准字段****************************************
|
||||
|
||||
|
||||
/**
|
||||
* 租户ID 实体字段名
|
||||
*/
|
||||
String TENANT_ID = "tenantId";
|
||||
/**
|
||||
* 租户ID 数据库字段名
|
||||
*/
|
||||
String TENANT_ID_TABLE = "tenant_id";
|
||||
|
||||
/**
|
||||
* sql语句 where
|
||||
*/
|
||||
String SQL_WHERE = "where";
|
||||
|
||||
/**
|
||||
* sql语句 asc
|
||||
*/
|
||||
String SQL_ASC = "asc";
|
||||
|
||||
/**
|
||||
* sqlserver数据库,中间有空格
|
||||
*/
|
||||
String DB_TYPE_SQL_SERVER_BLANK = "sql server";
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
/**
|
||||
* @Description: TenantConstant
|
||||
* @author: scott
|
||||
* @date: 2022年08月29日 15:29
|
||||
*/
|
||||
public interface TenantConstant {
|
||||
|
||||
/**
|
||||
* 应用ID——表字段
|
||||
*/
|
||||
String DB_FIELD_LOW_APP_ID = "low_app_id";
|
||||
/**
|
||||
* 应用ID——实体字段
|
||||
*/
|
||||
String FIELD_LOW_APP_ID = "lowAppId";
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
String TENANT_ID = "tenantId";
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
package org.jeecg.common.constant.enums;
|
||||
|
||||
/**
|
||||
* LowApp 切面注解枚举
|
||||
* @date 2022-1-5
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public enum LowAppAopEnum {
|
||||
|
||||
/**
|
||||
* 新增方法
|
||||
*/
|
||||
ADD,
|
||||
/**
|
||||
* 删除方法(包含单个和批量删除)
|
||||
*/
|
||||
DELETE,
|
||||
/** 复制表单操作 */
|
||||
COPY,
|
||||
|
||||
/**
|
||||
* Online表单专用:数据库表转Online表单
|
||||
*/
|
||||
CGFORM_DB_IMPORT
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
/**
|
||||
* @Description: jeecg-boot自定义异常
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class JeecgBootException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JeecgBootException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JeecgBootException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public JeecgBootException(String message,Throwable cause)
|
||||
{
|
||||
super(message,cause);
|
||||
}
|
||||
}
|
||||
@ -1,136 +0,0 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.enums.SentinelErrorInfoEnum;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.data.redis.connection.PoolException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
*
|
||||
* @Author scott
|
||||
* @Date 2019
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class JeecgBootExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgBootException.class)
|
||||
public Result<?> handleJeecgBootException(JeecgBootException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义微服务异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgCloudException.class)
|
||||
public Result<?> handleJeecgCloudException(JeecgCloudException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgBoot401Exception.class)
|
||||
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||
public Result<?> handleJeecgBoot401Exception(JeecgBoot401Exception e){
|
||||
log.error(e.getMessage(), e);
|
||||
return new Result(401,e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoHandlerFoundException.class)
|
||||
public Result<?> handlerNoFoundException(Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(404, "路径不存在,请检查路径是否正确");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public Result<?> handleDuplicateKeyException(DuplicateKeyException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("数据库中已存在该记录");
|
||||
}
|
||||
|
||||
@ExceptionHandler({UnauthorizedException.class, AuthorizationException.class})
|
||||
public Result<?> handleAuthorizationException(AuthorizationException e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.noauth("没有权限,请联系管理员授权");
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result<?> handleException(Exception e){
|
||||
log.error(e.getMessage(), e);
|
||||
//update-begin---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常
|
||||
Throwable throwable = e.getCause();
|
||||
SentinelErrorInfoEnum errorInfoEnum = SentinelErrorInfoEnum.getErrorByException(throwable);
|
||||
if (ObjectUtil.isNotEmpty(errorInfoEnum)) {
|
||||
return Result.error(errorInfoEnum.getError());
|
||||
}
|
||||
//update-end---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常
|
||||
return Result.error("操作失败,"+e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author 政辉
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||
public Result<?> httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("不支持");
|
||||
sb.append(e.getMethod());
|
||||
sb.append("请求方法,");
|
||||
sb.append("支持以下");
|
||||
String [] methods = e.getSupportedMethods();
|
||||
if(methods!=null){
|
||||
for(String str:methods){
|
||||
sb.append(str);
|
||||
sb.append("、");
|
||||
}
|
||||
}
|
||||
log.error(sb.toString(), e);
|
||||
//return Result.error("没有权限,请联系管理员授权");
|
||||
return Result.error(405,sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException
|
||||
*/
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
public Result<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! ");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DataIntegrityViolationException.class)
|
||||
public Result<?> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
//【issues/3624】数据库执行异常handleDataIntegrityViolationException提示有误 #3624
|
||||
return Result.error("执行数据库异常,违反了完整性例如:违反惟一约束、违反非空限制、字段内容超出长度等");
|
||||
}
|
||||
|
||||
@ExceptionHandler(PoolException.class)
|
||||
public Result<?> handlePoolException(PoolException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("Redis 连接异常!");
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
package org.jeecg.common.system.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 将枚举类转化成字典数据
|
||||
* @Author taoYan
|
||||
* @Date 2022/7/8 10:34
|
||||
**/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EnumDict {
|
||||
|
||||
/**
|
||||
* 作为字典数据的唯一编码
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
@ -1,203 +0,0 @@
|
||||
package org.jeecg.common.system.base.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: Controller基类
|
||||
* @Author: dangzhenghui@163.com
|
||||
* @Date: 2019-4-21 8:13
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
public class JeecgController<T, S extends IService<T>> {
|
||||
/**issues/2933 JeecgController注入service时改用protected修饰,能避免重复引用service*/
|
||||
@Autowired
|
||||
protected S service;
|
||||
|
||||
@Value("${jeecg.path.upload}")
|
||||
private String upLoadPath;
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
protected ModelAndView exportXls(HttpServletRequest request, T object, Class<T> clazz, String title) {
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
|
||||
// 过滤选中数据
|
||||
String selections = request.getParameter("selections");
|
||||
if (oConvertUtils.isNotEmpty(selections)) {
|
||||
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||
queryWrapper.in("id",selectionList);
|
||||
}
|
||||
// Step.2 获取导出数据
|
||||
List<T> exportList = service.list(queryWrapper);
|
||||
|
||||
// Step.3 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
//此处设置的filename无效 ,前端会重更新设置一下
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, title);
|
||||
mv.addObject(NormalExcelConstants.CLASS, clazz);
|
||||
//update-begin--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置--------------------
|
||||
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title);
|
||||
exportParams.setImageBasePath(upLoadPath);
|
||||
//update-end--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置----------------------
|
||||
mv.addObject(NormalExcelConstants.PARAMS,exportParams);
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
|
||||
return mv;
|
||||
}
|
||||
/**
|
||||
* 根据每页sheet数量导出多sheet
|
||||
*
|
||||
* @param request
|
||||
* @param object 实体类
|
||||
* @param clazz 实体类class
|
||||
* @param title 标题
|
||||
* @param exportFields 导出字段自定义
|
||||
* @param pageNum 每个sheet的数据条数
|
||||
* @param request
|
||||
*/
|
||||
protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields,Integer pageNum) {
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// Step.2 计算分页sheet数据
|
||||
double total = service.count();
|
||||
int count = (int)Math.ceil(total/pageNum);
|
||||
//update-begin-author:liusq---date:20220629--for: 多sheet导出根据选择导出写法调整 ---
|
||||
// Step.3 过滤选中数据
|
||||
String selections = request.getParameter("selections");
|
||||
if (oConvertUtils.isNotEmpty(selections)) {
|
||||
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||
queryWrapper.in("id",selectionList);
|
||||
}
|
||||
//update-end-author:liusq---date:20220629--for: 多sheet导出根据选择导出写法调整 ---
|
||||
// Step.4 多sheet处理
|
||||
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
|
||||
for (int i = 1; i <=count ; i++) {
|
||||
Page<T> page = new Page<T>(i, pageNum);
|
||||
IPage<T> pageList = service.page(page, queryWrapper);
|
||||
List<T> exportList = pageList.getRecords();
|
||||
Map<String, Object> map = new HashMap<>(5);
|
||||
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title+i,upLoadPath);
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
//map.put("title",exportParams);
|
||||
//表格Title
|
||||
map.put(NormalExcelConstants.PARAMS,exportParams);
|
||||
//表格对应实体
|
||||
map.put(NormalExcelConstants.CLASS,clazz);
|
||||
//数据集合
|
||||
map.put(NormalExcelConstants.DATA_LIST, exportList);
|
||||
listMap.add(map);
|
||||
}
|
||||
// Step.4 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
//此处设置的filename无效 ,前端会重更新设置一下
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, title);
|
||||
mv.addObject(NormalExcelConstants.MAP_LIST, listMap);
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据权限导出excel,传入导出字段参数
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
protected ModelAndView exportXls(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields) {
|
||||
ModelAndView mv = this.exportXls(request,object,clazz,title);
|
||||
mv.addObject(NormalExcelConstants.EXPORT_FIELDS,exportFields);
|
||||
return mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象ID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String getId(T item) {
|
||||
try {
|
||||
return PropertyUtils.getProperty(item, "id").toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
protected Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = entity.getValue();
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
List<T> list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params);
|
||||
//update-begin-author:taoyan date:20190528 for:批量插入数据
|
||||
long start = System.currentTimeMillis();
|
||||
service.saveBatch(list);
|
||||
//400条 saveBatch消耗时间1592毫秒 循环插入消耗时间1947毫秒
|
||||
//1200条 saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
|
||||
log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
//update-end-author:taoyan date:20190528 for:批量插入数据
|
||||
return Result.ok("文件导入成功!数据行数:" + list.size());
|
||||
} catch (Exception e) {
|
||||
//update-begin-author:taoyan date:20211124 for: 导入数据重复增加提示
|
||||
String msg = e.getMessage();
|
||||
log.error(msg, e);
|
||||
if(msg!=null && msg.indexOf("Duplicate entry")>=0){
|
||||
return Result.error("文件导入失败:有重复数据!");
|
||||
}else{
|
||||
return Result.error("文件导入失败:" + e.getMessage());
|
||||
}
|
||||
//update-end-author:taoyan date:20211124 for: 导入数据重复增加提示
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.error("文件导入失败!");
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,86 +0,0 @@
|
||||
package org.jeecg.common.system.query;
|
||||
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
|
||||
/**
|
||||
* Query 规则 常量
|
||||
* @Author Scott
|
||||
* @Date 2019年02月14日
|
||||
*/
|
||||
public enum QueryRuleEnum {
|
||||
|
||||
/**查询规则 大于*/
|
||||
GT(">","gt","大于"),
|
||||
/**查询规则 大于等于*/
|
||||
GE(">=","ge","大于等于"),
|
||||
/**查询规则 小于*/
|
||||
LT("<","lt","小于"),
|
||||
/**查询规则 小于等于*/
|
||||
LE("<=","le","小于等于"),
|
||||
/**查询规则 等于*/
|
||||
EQ("=","eq","等于"),
|
||||
/**查询规则 不等于*/
|
||||
NE("!=","ne","不等于"),
|
||||
/**查询规则 包含*/
|
||||
IN("IN","in","包含"),
|
||||
/**查询规则 全模糊*/
|
||||
LIKE("LIKE","like","全模糊"),
|
||||
/**查询规则 左模糊*/
|
||||
LEFT_LIKE("LEFT_LIKE","left_like","左模糊"),
|
||||
/**查询规则 右模糊*/
|
||||
RIGHT_LIKE("RIGHT_LIKE","right_like","右模糊"),
|
||||
/**查询规则 带加号等于*/
|
||||
EQ_WITH_ADD("EQWITHADD","eq_with_add","带加号等于"),
|
||||
/**查询规则 多词模糊匹配*/
|
||||
LIKE_WITH_AND("LIKEWITHAND","like_with_and","多词模糊匹配————暂时未用上"),
|
||||
/**查询规则 自定义SQL片段*/
|
||||
SQL_RULES("USE_SQL_RULES","ext","自定义SQL片段");
|
||||
|
||||
private String value;
|
||||
|
||||
private String condition;
|
||||
|
||||
private String msg;
|
||||
|
||||
QueryRuleEnum(String value, String condition, String msg){
|
||||
this.value = value;
|
||||
this.condition = condition;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public void setCondition(String condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public static QueryRuleEnum getByValue(String value){
|
||||
if(oConvertUtils.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
for(QueryRuleEnum val :values()){
|
||||
if (val.getValue().equals(value) || val.getCondition().equals(value)){
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,252 +0,0 @@
|
||||
package org.jeecg.common.system.util;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.DataBaseConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
|
||||
/**
|
||||
* @Author Scott
|
||||
* @Date 2018-07-12 14:23
|
||||
* @Desc JWT工具类
|
||||
**/
|
||||
public class JwtUtil {
|
||||
|
||||
/**Token有效期为1小时(Token在reids中缓存时间为两倍)*/
|
||||
public static final long EXPIRE_TIME = 60 * 60 * 1000;
|
||||
static final String WELL_NUMBER = SymbolConstant.WELL_NUMBER + SymbolConstant.LEFT_CURLY_BRACKET;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param response
|
||||
* @param code
|
||||
* @param errorMsg
|
||||
*/
|
||||
public static void responseError(ServletResponse response, Integer code, String errorMsg) {
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
// issues/I4YH95浏览器显示乱码问题
|
||||
httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
|
||||
Result jsonResult = new Result(code, errorMsg);
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = httpServletResponse.getOutputStream();
|
||||
httpServletResponse.setCharacterEncoding("UTF-8");
|
||||
httpServletResponse.setStatus(code);
|
||||
os.write(new ObjectMapper().writeValueAsString(jsonResult).getBytes("UTF-8"));
|
||||
os.flush();
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验token是否正确
|
||||
*
|
||||
* @param token 密钥
|
||||
* @param secret 用户的密码
|
||||
* @return 是否正确
|
||||
*/
|
||||
public static boolean verify(String token, String username, String secret) {
|
||||
try {
|
||||
// 根据密码生成JWT效验器
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
|
||||
// 效验TOKEN
|
||||
DecodedJWT jwt = verifier.verify(token);
|
||||
return true;
|
||||
} catch (Exception exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得token中的信息无需secret解密也能获得
|
||||
*
|
||||
* @return token中包含的用户名
|
||||
*/
|
||||
public static String getUsername(String token) {
|
||||
try {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
return jwt.getClaim("username").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名,5min后过期
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param secret 用户的密码
|
||||
* @return 加密的token
|
||||
*/
|
||||
public static String sign(String username, String secret) {
|
||||
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
// 附带username信息
|
||||
return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据request中的token获取用户账号
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @throws JeecgBootException
|
||||
*/
|
||||
public static String getUserNameByToken(HttpServletRequest request) throws JeecgBootException {
|
||||
String accessToken = request.getHeader("X-Access-Token");
|
||||
String username = getUsername(accessToken);
|
||||
if (oConvertUtils.isEmpty(username)) {
|
||||
throw new JeecgBootException("未获取到用户");
|
||||
}
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从session中获取变量
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getSessionData(String key) {
|
||||
//${myVar}%
|
||||
//得到${} 后面的值
|
||||
String moshi = "";
|
||||
String wellNumber = WELL_NUMBER;
|
||||
|
||||
if(key.indexOf(SymbolConstant.RIGHT_CURLY_BRACKET)!=-1){
|
||||
moshi = key.substring(key.indexOf("}")+1);
|
||||
}
|
||||
String returnValue = null;
|
||||
if (key.contains(wellNumber)) {
|
||||
key = key.substring(2,key.indexOf("}"));
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(key)) {
|
||||
HttpSession session = SpringContextUtils.getHttpServletRequest().getSession();
|
||||
returnValue = (String) session.getAttribute(key);
|
||||
}
|
||||
//结果加上${} 后面的值
|
||||
if(returnValue!=null){returnValue = returnValue + moshi;}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从当前用户中获取变量
|
||||
* @param key
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public static String getUserSystemData(String key,SysUserCacheInfo user) {
|
||||
if(user==null) {
|
||||
user = JeecgDataAutorUtils.loadUserInfo();
|
||||
}
|
||||
//#{sys_user_code}%
|
||||
|
||||
// 获取登录用户信息
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
|
||||
String moshi = "";
|
||||
String wellNumber = WELL_NUMBER;
|
||||
if(key.indexOf(SymbolConstant.RIGHT_CURLY_BRACKET)!=-1){
|
||||
moshi = key.substring(key.indexOf("}")+1);
|
||||
}
|
||||
String returnValue = null;
|
||||
//针对特殊标示处理#{sysOrgCode},判断替换
|
||||
if (key.contains(wellNumber)) {
|
||||
key = key.substring(2,key.indexOf("}"));
|
||||
} else {
|
||||
key = key;
|
||||
}
|
||||
//替换为系统登录用户帐号
|
||||
if (key.equals(DataBaseConstant.SYS_USER_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_USER_CODE_TABLE)) {
|
||||
if(user==null) {
|
||||
returnValue = sysUser.getUsername();
|
||||
}else {
|
||||
returnValue = user.getSysUserCode();
|
||||
}
|
||||
}
|
||||
//替换为系统登录用户真实名字
|
||||
else if (key.equals(DataBaseConstant.SYS_USER_NAME)|| key.toLowerCase().equals(DataBaseConstant.SYS_USER_NAME_TABLE)) {
|
||||
if(user==null) {
|
||||
returnValue = sysUser.getRealname();
|
||||
}else {
|
||||
returnValue = user.getSysUserName();
|
||||
}
|
||||
}
|
||||
|
||||
//替换为系统用户登录所使用的机构编码
|
||||
else if (key.equals(DataBaseConstant.SYS_ORG_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_ORG_CODE_TABLE)) {
|
||||
if(user==null) {
|
||||
returnValue = sysUser.getOrgCode();
|
||||
}else {
|
||||
returnValue = user.getSysOrgCode();
|
||||
}
|
||||
}
|
||||
//替换为系统用户所拥有的所有机构编码
|
||||
else if (key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_MULTI_ORG_CODE_TABLE)) {
|
||||
if(user==null){
|
||||
//TODO 暂时使用用户登录部门,存在逻辑缺陷,不是用户所拥有的部门
|
||||
returnValue = sysUser.getOrgCode();
|
||||
}else{
|
||||
if(user.isOneDepart()) {
|
||||
returnValue = user.getSysMultiOrgCode().get(0);
|
||||
}else {
|
||||
returnValue = Joiner.on(",").join(user.getSysMultiOrgCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
//替换为当前系统时间(年月日)
|
||||
else if (key.equals(DataBaseConstant.SYS_DATE)|| key.toLowerCase().equals(DataBaseConstant.SYS_DATE_TABLE)) {
|
||||
returnValue = DateUtils.formatDate();
|
||||
}
|
||||
//替换为当前系统时间(年月日时分秒)
|
||||
else if (key.equals(DataBaseConstant.SYS_TIME)|| key.toLowerCase().equals(DataBaseConstant.SYS_TIME_TABLE)) {
|
||||
returnValue = DateUtils.now();
|
||||
}
|
||||
//流程状态默认值(默认未发起)
|
||||
else if (key.equals(DataBaseConstant.BPM_STATUS)|| key.toLowerCase().equals(DataBaseConstant.BPM_STATUS_TABLE)) {
|
||||
returnValue = "1";
|
||||
}
|
||||
//update-begin-author:taoyan date:20210330 for:多租户ID作为系统变量
|
||||
else if (key.equals(DataBaseConstant.TENANT_ID) || key.toLowerCase().equals(DataBaseConstant.TENANT_ID_TABLE)){
|
||||
returnValue = sysUser.getRelTenantIds();
|
||||
boolean flag = returnValue != null && returnValue.indexOf(SymbolConstant.COMMA) > 0;
|
||||
if(oConvertUtils.isEmpty(returnValue) || flag){
|
||||
returnValue = SpringContextUtils.getHttpServletRequest().getHeader(CommonConstant.TENANT_ID);
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:20210330 for:多租户ID作为系统变量
|
||||
if(returnValue!=null){returnValue = returnValue + moshi;}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjUzMzY1MTMsInVzZXJuYW1lIjoiYWRtaW4ifQ.xjhud_tWCNYBOg_aRlMgOdlZoWFFKB_givNElHNw3X0";
|
||||
// System.out.println(JwtUtil.getUsername(token));
|
||||
// }
|
||||
}
|
||||
@ -1,117 +0,0 @@
|
||||
package org.jeecg.common.system.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.system.annotation.EnumDict;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 资源加载工具类
|
||||
* @Author taoYan
|
||||
* @Date 2022/7/8 10:40
|
||||
**/
|
||||
@Slf4j
|
||||
public class ResourceUtil {
|
||||
|
||||
|
||||
/**
|
||||
* 枚举字典数据
|
||||
*/
|
||||
private final static Map<String, List<DictModel>> enumDictData = new HashMap<>(5);
|
||||
|
||||
/**
|
||||
* 所有java类
|
||||
*/
|
||||
private final static String CLASS_PATTERN="/**/*.class";
|
||||
|
||||
/**
|
||||
* 所有枚举java类
|
||||
*/
|
||||
|
||||
private final static String CLASS_ENMU_PATTERN="/**/*Enum.class";
|
||||
|
||||
/**
|
||||
* 包路径 org.jeecg
|
||||
*/
|
||||
private final static String BASE_PACKAGE = "org.jeecg";
|
||||
|
||||
/**
|
||||
* 枚举类中获取字典数据的方法名
|
||||
*/
|
||||
private final static String METHOD_NAME = "getDictList";
|
||||
|
||||
/**
|
||||
* 获取枚举类对应的字典数据 SysDictServiceImpl#queryAllDictItems()
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, List<DictModel>> getEnumDictData(){
|
||||
if(enumDictData.keySet().size()>0){
|
||||
return enumDictData;
|
||||
}
|
||||
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
|
||||
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(BASE_PACKAGE) + CLASS_ENMU_PATTERN;
|
||||
try {
|
||||
Resource[] resources = resourcePatternResolver.getResources(pattern);
|
||||
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
|
||||
for (Resource resource : resources) {
|
||||
MetadataReader reader = readerFactory.getMetadataReader(resource);
|
||||
String classname = reader.getClassMetadata().getClassName();
|
||||
Class<?> clazz = Class.forName(classname);
|
||||
EnumDict enumDict = clazz.getAnnotation(EnumDict.class);
|
||||
if (enumDict != null) {
|
||||
EnumDict annotation = clazz.getAnnotation(EnumDict.class);
|
||||
String key = annotation.value();
|
||||
if(oConvertUtils.isNotEmpty(key)){
|
||||
List<DictModel> list = (List<DictModel>) clazz.getDeclaredMethod(METHOD_NAME).invoke(null);
|
||||
enumDictData.put(key, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("获取枚举类字典数据异常", e.getMessage());
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return enumDictData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于后端字典翻译 SysDictServiceImpl#queryManyDictByKeys(java.util.List, java.util.List)
|
||||
* @param dictCodeList
|
||||
* @param keys
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, List<DictModel>> queryManyDictByKeys(List<String> dictCodeList, List<String> keys){
|
||||
if(enumDictData.keySet().size()==0){
|
||||
getEnumDictData();
|
||||
}
|
||||
Map<String, List<DictModel>> map = new HashMap<>();
|
||||
for (String code : enumDictData.keySet()) {
|
||||
if(dictCodeList.indexOf(code)>=0){
|
||||
List<DictModel> dictItemList = enumDictData.get(code);
|
||||
for(DictModel dm: dictItemList){
|
||||
String value = dm.getValue();
|
||||
if(keys.indexOf(value)>=0){
|
||||
List<DictModel> list = new ArrayList<>();
|
||||
list.add(new DictModel(value, dm.getText()));
|
||||
map.put(code,list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 字典类
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class DictModel implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DictModel() {
|
||||
}
|
||||
|
||||
public DictModel(String value, String text) {
|
||||
this.value = value;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典value
|
||||
*/
|
||||
private String value;
|
||||
/**
|
||||
* 字典文本
|
||||
*/
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* 特殊用途: JgEditableTable
|
||||
* @return
|
||||
*/
|
||||
public String getTitle() {
|
||||
return this.text;
|
||||
}
|
||||
/**
|
||||
* 特殊用途: vue3 Select组件
|
||||
*/
|
||||
public String getLabel() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,130 +0,0 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveField;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 在线用户信息
|
||||
* </p>
|
||||
*
|
||||
* @Author scott
|
||||
* @since 2018-12-20
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class LoginUser {
|
||||
|
||||
/**
|
||||
* 登录人id
|
||||
*/
|
||||
@SensitiveField
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 登录人账号
|
||||
*/
|
||||
@SensitiveField
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 登录人名字
|
||||
*/
|
||||
@SensitiveField
|
||||
private String realname;
|
||||
|
||||
/**
|
||||
* 登录人密码
|
||||
*/
|
||||
@SensitiveField
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 当前登录部门code
|
||||
*/
|
||||
private String orgCode;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
@SensitiveField
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
@SensitiveField
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date birthday;
|
||||
|
||||
/**
|
||||
* 性别(1:男 2:女)
|
||||
*/
|
||||
private Integer sex;
|
||||
|
||||
/**
|
||||
* 电子邮件
|
||||
*/
|
||||
@SensitiveField
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
@SensitiveField
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 状态(1:正常 2:冻结 )
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
private Integer delFlag;
|
||||
/**
|
||||
* 同步工作流引擎1同步0不同步
|
||||
*/
|
||||
private Integer activitiSync;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 身份(1 普通员工 2 上级)
|
||||
*/
|
||||
private Integer userIdentity;
|
||||
|
||||
/**
|
||||
* 管理部门ids
|
||||
*/
|
||||
private String departIds;
|
||||
|
||||
/**
|
||||
* 职务,关联职务表
|
||||
*/
|
||||
@SensitiveField
|
||||
private String post;
|
||||
|
||||
/**
|
||||
* 座机号
|
||||
*/
|
||||
@SensitiveField
|
||||
private String telephone;
|
||||
|
||||
/**多租户id配置,编辑用户的时候设置*/
|
||||
private String relTenantIds;
|
||||
|
||||
/**设备id uniapp推送用*/
|
||||
private String clientId;
|
||||
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
|
||||
/**
|
||||
* @Description: 用户缓存信息
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class SysUserCacheInfo {
|
||||
|
||||
private String sysUserCode;
|
||||
|
||||
private String sysUserName;
|
||||
|
||||
private String sysOrgCode;
|
||||
|
||||
private List<String> sysMultiOrgCode;
|
||||
|
||||
private boolean oneDepart;
|
||||
|
||||
public boolean isOneDepart() {
|
||||
return oneDepart;
|
||||
}
|
||||
|
||||
public void setOneDepart(boolean oneDepart) {
|
||||
this.oneDepart = oneDepart;
|
||||
}
|
||||
|
||||
public String getSysDate() {
|
||||
return DateUtils.formatDate();
|
||||
}
|
||||
|
||||
public String getSysTime() {
|
||||
return DateUtils.now();
|
||||
}
|
||||
|
||||
public String getSysUserCode() {
|
||||
return sysUserCode;
|
||||
}
|
||||
|
||||
public void setSysUserCode(String sysUserCode) {
|
||||
this.sysUserCode = sysUserCode;
|
||||
}
|
||||
|
||||
public String getSysUserName() {
|
||||
return sysUserName;
|
||||
}
|
||||
|
||||
public void setSysUserName(String sysUserName) {
|
||||
this.sysUserName = sysUserName;
|
||||
}
|
||||
|
||||
public String getSysOrgCode() {
|
||||
return sysOrgCode;
|
||||
}
|
||||
|
||||
public void setSysOrgCode(String sysOrgCode) {
|
||||
this.sysOrgCode = sysOrgCode;
|
||||
}
|
||||
|
||||
public List<String> getSysMultiOrgCode() {
|
||||
return sysMultiOrgCode;
|
||||
}
|
||||
|
||||
public void setSysMultiOrgCode(List<String> sysMultiOrgCode) {
|
||||
this.sysMultiOrgCode = sysMultiOrgCode;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,354 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.DataBaseConstant;
|
||||
import org.jeecg.common.constant.ServiceNameConstants;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.util.filter.FileTypeFilter;
|
||||
import org.jeecg.common.util.oss.OssBootUtil;
|
||||
import org.jeecgframework.poi.util.PoiPublicUtil;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Description: 通用工具
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
public class CommonUtils {
|
||||
|
||||
/**
|
||||
* 中文正则
|
||||
*/
|
||||
private static Pattern ZHONGWEN_PATTERN = Pattern.compile("[\u4e00-\u9fa5]");
|
||||
|
||||
/**
|
||||
* 文件名 正则字符串
|
||||
* 文件名支持的字符串:字母数字中文.-_()() 除此之外的字符将被删除
|
||||
*/
|
||||
private static String FILE_NAME_REGEX = "[^A-Za-z\\.\\(\\)\\-()\\_0-9\\u4e00-\\u9fa5]";
|
||||
|
||||
public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){
|
||||
String dbPath = null;
|
||||
String fileName = "image" + Math.round(Math.random() * 100000000000L);
|
||||
fileName += "." + PoiPublicUtil.getFileExtendName(data);
|
||||
try {
|
||||
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
||||
File file = new File(basePath + File.separator + bizPath + File.separator );
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();// 创建文件根目录
|
||||
}
|
||||
String savePath = file.getPath() + File.separator + fileName;
|
||||
File savefile = new File(savePath);
|
||||
FileCopyUtils.copy(data, savefile);
|
||||
dbPath = bizPath + File.separator + fileName;
|
||||
}else {
|
||||
InputStream in = new ByteArrayInputStream(data);
|
||||
String relativePath = bizPath+"/"+fileName;
|
||||
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
|
||||
dbPath = MinioUtil.upload(in,relativePath);
|
||||
}else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
|
||||
dbPath = OssBootUtil.upload(in,relativePath);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return dbPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件名是否带盘符,重新处理
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public static String getFileName(String fileName){
|
||||
//判断是否带有盘符信息
|
||||
// Check for Unix-style path
|
||||
int unixSep = fileName.lastIndexOf('/');
|
||||
// Check for Windows-style path
|
||||
int winSep = fileName.lastIndexOf('\\');
|
||||
// Cut off at latest possible point
|
||||
int pos = (winSep > unixSep ? winSep : unixSep);
|
||||
if (pos != -1) {
|
||||
// Any sort of path separator found...
|
||||
fileName = fileName.substring(pos + 1);
|
||||
}
|
||||
//替换上传文件名字的特殊字符
|
||||
fileName = fileName.replace("=","").replace(",","").replace("&","")
|
||||
.replace("#", "").replace("“", "").replace("”", "");
|
||||
//替换上传文件名字中的空格
|
||||
fileName=fileName.replaceAll("\\s","");
|
||||
//update-beign-author:taoyan date:20220302 for: /issues/3381 online 在线表单 使用文件组件时,上传文件名中含%,下载异常
|
||||
fileName = fileName.replaceAll(FILE_NAME_REGEX, "");
|
||||
//update-end-author:taoyan date:20220302 for: /issues/3381 online 在线表单 使用文件组件时,上传文件名中含%,下载异常
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* java 判断字符串里是否包含中文字符
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean ifContainChinese(String str) {
|
||||
if(str.getBytes().length == str.length()){
|
||||
return false;
|
||||
}else{
|
||||
Matcher m = ZHONGWEN_PATTERN.matcher(str);
|
||||
if (m.find()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一全局上传
|
||||
* @Return: java.lang.String
|
||||
*/
|
||||
public static String upload(MultipartFile file, String bizPath, String uploadType) {
|
||||
String url = "";
|
||||
try {
|
||||
if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
|
||||
url = MinioUtil.upload(file, bizPath);
|
||||
} else {
|
||||
url = OssBootUtil.upload(file, bizPath);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
/**
|
||||
* 本地文件上传
|
||||
* @param mf 文件
|
||||
* @param bizPath 自定义路径
|
||||
* @return
|
||||
*/
|
||||
public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){
|
||||
try {
|
||||
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
||||
FileTypeFilter.fileTypeFilter(mf);
|
||||
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
||||
String fileName = null;
|
||||
File file = new File(uploadpath + File.separator + bizPath + File.separator );
|
||||
if (!file.exists()) {
|
||||
// 创建文件根目录
|
||||
file.mkdirs();
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = mf.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
if(orgName.indexOf(SymbolConstant.SPOT)!=-1){
|
||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||
}else{
|
||||
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||
}
|
||||
String savePath = file.getPath() + File.separator + fileName;
|
||||
File savefile = new File(savePath);
|
||||
FileCopyUtils.copy(mf.getBytes(), savefile);
|
||||
String dbpath = null;
|
||||
if(oConvertUtils.isNotEmpty(bizPath)){
|
||||
dbpath = bizPath + File.separator + fileName;
|
||||
}else{
|
||||
dbpath = fileName;
|
||||
}
|
||||
if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) {
|
||||
dbpath = dbpath.replace("\\", "/");
|
||||
}
|
||||
return dbpath;
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一全局上传 带桶
|
||||
* @Return: java.lang.String
|
||||
*/
|
||||
public static String upload(MultipartFile file, String bizPath, String uploadType, String customBucket) {
|
||||
String url = "";
|
||||
try {
|
||||
if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
|
||||
url = MinioUtil.upload(file, bizPath, customBucket);
|
||||
} else {
|
||||
url = OssBootUtil.upload(file, bizPath, customBucket);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/** 当前系统数据库类型 */
|
||||
private static String DB_TYPE = "";
|
||||
private static DbType dbTypeEnum = null;
|
||||
|
||||
/**
|
||||
* 全局获取平台数据库类型(作废了)
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getDatabaseType() {
|
||||
if(oConvertUtils.isNotEmpty(DB_TYPE)){
|
||||
return DB_TYPE;
|
||||
}
|
||||
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
|
||||
try {
|
||||
return getDatabaseTypeByDataSource(dataSource);
|
||||
} catch (SQLException e) {
|
||||
//e.printStackTrace();
|
||||
log.warn(e.getMessage(),e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局获取平台数据库类型(对应mybaisPlus枚举)
|
||||
* @return
|
||||
*/
|
||||
public static DbType getDatabaseTypeEnum() {
|
||||
if (oConvertUtils.isNotEmpty(dbTypeEnum)) {
|
||||
return dbTypeEnum;
|
||||
}
|
||||
try {
|
||||
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
|
||||
dbTypeEnum = JdbcUtils.getDbType(dataSource.getConnection().getMetaData().getURL());
|
||||
return dbTypeEnum;
|
||||
} catch (SQLException e) {
|
||||
log.warn(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据数据源key获取DataSourceProperty
|
||||
* @param sourceKey
|
||||
* @return
|
||||
*/
|
||||
public static DataSourceProperty getDataSourceProperty(String sourceKey){
|
||||
DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class);
|
||||
Map<String, DataSourceProperty> map = prop.getDatasource();
|
||||
DataSourceProperty db = (DataSourceProperty)map.get(sourceKey);
|
||||
return db;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据sourceKey 获取数据源连接
|
||||
* @param sourceKey
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Connection getDataSourceConnect(String sourceKey) throws SQLException {
|
||||
if (oConvertUtils.isEmpty(sourceKey)) {
|
||||
sourceKey = "master";
|
||||
}
|
||||
DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class);
|
||||
Map<String, DataSourceProperty> map = prop.getDatasource();
|
||||
DataSourceProperty db = (DataSourceProperty)map.get(sourceKey);
|
||||
if(db==null){
|
||||
return null;
|
||||
}
|
||||
DriverManagerDataSource ds = new DriverManagerDataSource ();
|
||||
ds.setDriverClassName(db.getDriverClassName());
|
||||
ds.setUrl(db.getUrl());
|
||||
ds.setUsername(db.getUsername());
|
||||
ds.setPassword(db.getPassword());
|
||||
return ds.getConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库类型
|
||||
* @param dataSource
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
private static String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{
|
||||
if("".equals(DB_TYPE)) {
|
||||
Connection connection = dataSource.getConnection();
|
||||
try {
|
||||
DatabaseMetaData md = connection.getMetaData();
|
||||
String dbType = md.getDatabaseProductName().toUpperCase();
|
||||
String sqlserver= "SQL SERVER";
|
||||
if(dbType.indexOf(DataBaseConstant.DB_TYPE_MYSQL)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_ORACLE)>=0 ||dbType.indexOf(DataBaseConstant.DB_TYPE_DM)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_SQLSERVER)>=0||dbType.indexOf(sqlserver)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
|
||||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_MARIADB)>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
|
||||
}else {
|
||||
log.error("数据库类型:[" + dbType + "]不识别!");
|
||||
//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
return DB_TYPE;
|
||||
|
||||
}
|
||||
/**
|
||||
* 获取服务器地址
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static String getBaseUrl(HttpServletRequest request) {
|
||||
//1.【兼容】兼容微服务下的 base path-------
|
||||
String xGatewayBasePath = request.getHeader(ServiceNameConstants.X_GATEWAY_BASE_PATH);
|
||||
if(oConvertUtils.isNotEmpty(xGatewayBasePath)){
|
||||
log.info("x_gateway_base_path = "+ xGatewayBasePath);
|
||||
return xGatewayBasePath;
|
||||
}
|
||||
//2.【兼容】SSL认证之后,request.getScheme()获取不到https的问题
|
||||
// https://blog.csdn.net/weixin_34376986/article/details/89767950
|
||||
String scheme = request.getHeader(CommonConstant.X_FORWARDED_SCHEME);
|
||||
if(oConvertUtils.isEmpty(scheme)){
|
||||
scheme = request.getScheme();
|
||||
}
|
||||
|
||||
//3.常规操作
|
||||
String serverName = request.getServerName();
|
||||
int serverPort = request.getServerPort();
|
||||
String contextPath = request.getContextPath();
|
||||
|
||||
//返回 host domain
|
||||
String baseDomainPath = null;
|
||||
int length = 80;
|
||||
if(length == serverPort){
|
||||
baseDomainPath = scheme + "://" + serverName + contextPath ;
|
||||
}else{
|
||||
baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ;
|
||||
}
|
||||
log.debug("-----Common getBaseUrl----- : " + baseDomainPath);
|
||||
return baseDomainPath;
|
||||
}
|
||||
}
|
||||
@ -1,124 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import org.jeecg.config.StaticConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
|
||||
import com.aliyuncs.exceptions.ClientException;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import com.aliyuncs.profile.IClientProfile;
|
||||
|
||||
/**
|
||||
* Created on 17/6/7.
|
||||
* 短信API产品的DEMO程序,工程中包含了一个SmsDemo类,直接通过
|
||||
* 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可)
|
||||
* 工程依赖了2个jar包(存放在工程的libs目录下)
|
||||
* 1:aliyun-java-sdk-core.jar
|
||||
* 2:aliyun-java-sdk-dysmsapi.jar
|
||||
*
|
||||
* 备注:Demo工程编码采用UTF-8
|
||||
* 国际短信发送请勿参照此DEMO
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class DySmsHelper {
|
||||
|
||||
private final static Logger logger=LoggerFactory.getLogger(DySmsHelper.class);
|
||||
|
||||
/**产品名称:云通信短信API产品,开发者无需替换*/
|
||||
static final String PRODUCT = "Dysmsapi";
|
||||
/**产品域名,开发者无需替换*/
|
||||
static final String DOMAIN = "dysmsapi.aliyuncs.com";
|
||||
|
||||
/**TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)*/
|
||||
static String accessKeyId;
|
||||
static String accessKeySecret;
|
||||
|
||||
public static void setAccessKeyId(String accessKeyId) {
|
||||
DySmsHelper.accessKeyId = accessKeyId;
|
||||
}
|
||||
|
||||
public static void setAccessKeySecret(String accessKeySecret) {
|
||||
DySmsHelper.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
|
||||
public static String getAccessKeyId() {
|
||||
return accessKeyId;
|
||||
}
|
||||
|
||||
public static String getAccessKeySecret() {
|
||||
return accessKeySecret;
|
||||
}
|
||||
|
||||
|
||||
public static boolean sendSms(String phone,JSONObject templateParamJson,DySmsEnum dySmsEnum) throws ClientException {
|
||||
//可自助调整超时时间
|
||||
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
|
||||
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
|
||||
|
||||
//update-begin-author:taoyan date:20200811 for:配置类数据获取
|
||||
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
|
||||
setAccessKeyId(staticConfig.getAccessKeyId());
|
||||
setAccessKeySecret(staticConfig.getAccessKeySecret());
|
||||
//update-end-author:taoyan date:20200811 for:配置类数据获取
|
||||
|
||||
//初始化acsClient,暂不支持region化
|
||||
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
|
||||
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", PRODUCT, DOMAIN);
|
||||
IAcsClient acsClient = new DefaultAcsClient(profile);
|
||||
|
||||
//验证json参数
|
||||
validateParam(templateParamJson,dySmsEnum);
|
||||
|
||||
//组装请求对象-具体描述见控制台-文档部分内容
|
||||
SendSmsRequest request = new SendSmsRequest();
|
||||
//必填:待发送手机号
|
||||
request.setPhoneNumbers(phone);
|
||||
//必填:短信签名-可在短信控制台中找到
|
||||
request.setSignName(dySmsEnum.getSignName());
|
||||
//必填:短信模板-可在短信控制台中找到
|
||||
request.setTemplateCode(dySmsEnum.getTemplateCode());
|
||||
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
|
||||
request.setTemplateParam(templateParamJson.toJSONString());
|
||||
|
||||
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
|
||||
//request.setSmsUpExtendCode("90997");
|
||||
|
||||
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
|
||||
//request.setOutId("yourOutId");
|
||||
|
||||
boolean result = false;
|
||||
|
||||
//hint 此处可能会抛出异常,注意catch
|
||||
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
|
||||
logger.info("短信接口返回的数据----------------");
|
||||
logger.info("{Code:" + sendSmsResponse.getCode()+",Message:" + sendSmsResponse.getMessage()+",RequestId:"+ sendSmsResponse.getRequestId()+",BizId:"+sendSmsResponse.getBizId()+"}");
|
||||
String ok = "OK";
|
||||
if (ok.equals(sendSmsResponse.getCode())) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private static void validateParam(JSONObject templateParamJson,DySmsEnum dySmsEnum) {
|
||||
String keys = dySmsEnum.getKeys();
|
||||
String [] keyArr = keys.split(",");
|
||||
for(String item :keyArr) {
|
||||
if(!templateParamJson.containsKey(item)) {
|
||||
throw new RuntimeException("模板缺少参数:"+item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public static void main(String[] args) throws ClientException, InterruptedException {
|
||||
// JSONObject obj = new JSONObject();
|
||||
// obj.put("code", "1234");
|
||||
// sendSms("13800138000", obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
|
||||
// }
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.handler.IFillRuleHandler;
|
||||
|
||||
|
||||
/**
|
||||
* 规则值自动生成工具类
|
||||
*
|
||||
* @author qinfeng
|
||||
* @举例: 自动生成订单号;自动生成当前日期
|
||||
*/
|
||||
@Slf4j
|
||||
public class FillRuleUtil {
|
||||
|
||||
/**
|
||||
* @param ruleCode ruleCode
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Object executeRule(String ruleCode, JSONObject formData) {
|
||||
if (!StringUtils.isEmpty(ruleCode)) {
|
||||
try {
|
||||
// 获取 Service
|
||||
ServiceImpl impl = (ServiceImpl) SpringContextUtils.getBean("sysFillRuleServiceImpl");
|
||||
// 根据 ruleCode 查询出实体
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
queryWrapper.eq("rule_code", ruleCode);
|
||||
JSONObject entity = JSON.parseObject(JSON.toJSONString(impl.getOne(queryWrapper)));
|
||||
if (entity == null) {
|
||||
log.warn("填值规则:" + ruleCode + " 不存在");
|
||||
return null;
|
||||
}
|
||||
// 获取必要的参数
|
||||
String ruleClass = entity.getString("ruleClass");
|
||||
JSONObject params = entity.getJSONObject("ruleParams");
|
||||
if (params == null) {
|
||||
params = new JSONObject();
|
||||
}
|
||||
if (formData == null) {
|
||||
formData = new JSONObject();
|
||||
}
|
||||
// 通过反射执行配置的类里的方法
|
||||
IFillRuleHandler ruleHandler = (IFillRuleHandler) Class.forName(ruleClass).newInstance();
|
||||
return ruleHandler.execute(params, formData);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.pegdown.PegDownProcessor;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
|
||||
/**
|
||||
* HTML 工具类
|
||||
* @author: jeecg-boot
|
||||
* @date: 2022/3/30 14:43
|
||||
*/
|
||||
@SuppressWarnings("AlibabaClassNamingShouldBeCamel")
|
||||
public class HTMLUtils {
|
||||
|
||||
/**
|
||||
* 获取HTML内的文本,不包含标签
|
||||
*
|
||||
* @param html HTML 代码
|
||||
*/
|
||||
public static String getInnerText(String html) {
|
||||
if (StringUtils.isNotBlank(html)) {
|
||||
//去掉 html 的标签
|
||||
String content = html.replaceAll("</?[^>]+>", "");
|
||||
// 将多个空格合并成一个空格
|
||||
content = content.replaceAll("( )+", " ");
|
||||
// 反向转义字符
|
||||
content = HtmlUtils.htmlUnescape(content);
|
||||
return content.trim();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Markdown解析成Html
|
||||
* @param markdownContent
|
||||
* @return
|
||||
*/
|
||||
public static String parseMarkdown(String markdownContent) {
|
||||
PegDownProcessor pdp = new PegDownProcessor();
|
||||
return pdp.markdownToHtml(markdownContent);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
*
|
||||
* @Author scott
|
||||
* @email jeecgos@163.com
|
||||
* @Date 2019年01月14日
|
||||
*/
|
||||
public class IpUtils {
|
||||
private static Logger logger = LoggerFactory.getLogger(IpUtils.class);
|
||||
|
||||
/**
|
||||
* 获取IP地址
|
||||
*
|
||||
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
|
||||
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
String ip = null;
|
||||
try {
|
||||
ip = request.getHeader("x-forwarded-for");
|
||||
if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || ip.length() == 0 ||CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("IPUtils ERROR ", e);
|
||||
}
|
||||
|
||||
// //使用代理,则获取第一个IP地址
|
||||
// if(StringUtils.isEmpty(ip) && ip.length() > 15) {
|
||||
// if(ip.indexOf(",") > 0) {
|
||||
// ip = ip.substring(0, ip.indexOf(","));
|
||||
// }
|
||||
// }
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,255 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author 张代浩
|
||||
* @desc 通过反射来动态调用get 和 set 方法
|
||||
*/
|
||||
@Slf4j
|
||||
public class ReflectHelper {
|
||||
|
||||
private Class cls;
|
||||
|
||||
/**
|
||||
* 传过来的对象
|
||||
*/
|
||||
private Object obj;
|
||||
|
||||
/**
|
||||
* 存放get方法
|
||||
*/
|
||||
private Hashtable<String, Method> getMethods = null;
|
||||
/**
|
||||
* 存放set方法
|
||||
*/
|
||||
private Hashtable<String, Method> setMethods = null;
|
||||
|
||||
/**
|
||||
* 定义构造方法 -- 一般来说是个pojo
|
||||
*
|
||||
* @param o 目标对象
|
||||
*/
|
||||
public ReflectHelper(Object o) {
|
||||
obj = o;
|
||||
initMethods();
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 初始化
|
||||
*/
|
||||
public void initMethods() {
|
||||
getMethods = new Hashtable<String, Method>();
|
||||
setMethods = new Hashtable<String, Method>();
|
||||
cls = obj.getClass();
|
||||
Method[] methods = cls.getMethods();
|
||||
// 定义正则表达式,从方法中过滤出getter / setter 函数.
|
||||
String gs = "get(\\w+)";
|
||||
Pattern getM = Pattern.compile(gs);
|
||||
String ss = "set(\\w+)";
|
||||
Pattern setM = Pattern.compile(ss);
|
||||
// 把方法中的"set" 或者 "get" 去掉
|
||||
String rapl = "$1";
|
||||
String param;
|
||||
for (int i = 0; i < methods.length; ++i) {
|
||||
Method m = methods[i];
|
||||
String methodName = m.getName();
|
||||
if (Pattern.matches(gs, methodName)) {
|
||||
param = getM.matcher(methodName).replaceAll(rapl).toLowerCase();
|
||||
getMethods.put(param, m);
|
||||
} else if (Pattern.matches(ss, methodName)) {
|
||||
param = setM.matcher(methodName).replaceAll(rapl).toLowerCase();
|
||||
setMethods.put(param, m);
|
||||
} else {
|
||||
// logger.info(methodName + " 不是getter,setter方法!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 调用set方法
|
||||
*/
|
||||
public boolean setMethodValue(String property, Object object) {
|
||||
Method m = setMethods.get(property.toLowerCase());
|
||||
if (m != null) {
|
||||
try {
|
||||
// 调用目标类的setter函数
|
||||
m.invoke(obj, object);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
log.info("invoke getter on " + property + " error: " + ex.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 调用set方法
|
||||
*/
|
||||
public Object getMethodValue(String property) {
|
||||
Object value = null;
|
||||
Method m = getMethods.get(property.toLowerCase());
|
||||
if (m != null) {
|
||||
try {
|
||||
/*
|
||||
* 调用obj类的setter函数
|
||||
*/
|
||||
value = m.invoke(obj, new Object[]{});
|
||||
|
||||
} catch (Exception ex) {
|
||||
log.info("invoke getter on " + property + " error: " + ex.toString());
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把map中的内容全部注入到obj中
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public Object setAll(Map<String, Object> data) {
|
||||
if (data == null || data.keySet().size() <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (Entry<String, Object> entry : data.entrySet()) {
|
||||
this.setMethodValue(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把map中的内容全部注入到obj中
|
||||
*
|
||||
* @param o
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static Object setAll(Object o, Map<String, Object> data) {
|
||||
ReflectHelper reflectHelper = new ReflectHelper(o);
|
||||
reflectHelper.setAll(data);
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把map中的内容全部注入到新实例中
|
||||
*
|
||||
* @param clazz
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T setAll(Class<T> clazz, Map<String, Object> data) {
|
||||
T o = null;
|
||||
try {
|
||||
o = clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
o = null;
|
||||
return o;
|
||||
}
|
||||
return (T) setAll(o, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据传入的class将mapList转换为实体类list
|
||||
*
|
||||
* @param mapist
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> transList2Entrys(List<Map<String, Object>> mapist, Class<T> clazz) {
|
||||
List<T> list = new ArrayList<T>();
|
||||
if (mapist != null && mapist.size() > 0) {
|
||||
for (Map<String, Object> data : mapist) {
|
||||
list.add(ReflectHelper.setAll(clazz, data));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据属性名获取属性值
|
||||
*/
|
||||
public static Object getFieldValueByName(String fieldName, Object o) {
|
||||
try {
|
||||
String firstLetter = fieldName.substring(0, 1).toUpperCase();
|
||||
String getter = "get" + firstLetter + fieldName.substring(1);
|
||||
Method method = o.getClass().getMethod(getter, new Class[]{});
|
||||
Object value = method.invoke(o, new Object[]{});
|
||||
return value;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性值
|
||||
*/
|
||||
public static Object getFieldVal(String fieldName, Object o) {
|
||||
try {
|
||||
// 暴力反射获取属性
|
||||
Field filed = o.getClass().getDeclaredField(fieldName);
|
||||
// 设置反射时取消Java的访问检查,暴力访问
|
||||
filed.setAccessible(true);
|
||||
Object val = filed.get(o);
|
||||
return val;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性名数组
|
||||
*/
|
||||
public static String[] getFiledName(Object o) {
|
||||
Field[] fields = o.getClass().getDeclaredFields();
|
||||
String[] fieldNames = new String[fields.length];
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
//log.info(fields[i].getType());
|
||||
fieldNames[i] = fields[i].getName();
|
||||
}
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性类型(type),属性名(name),属性值(value)的map组成的list
|
||||
*/
|
||||
public static List<Map> getFiledsInfo(Object o) {
|
||||
Field[] fields = o.getClass().getDeclaredFields();
|
||||
String[] fieldNames = new String[fields.length];
|
||||
List<Map> list = new ArrayList<Map>();
|
||||
Map<String, Object> infoMap = null;
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
infoMap = new HashMap<>(5);
|
||||
infoMap.put("type", fields[i].getType().toString());
|
||||
infoMap.put("name", fields[i].getName());
|
||||
infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
|
||||
list.add(infoMap);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象的所有属性值,返回一个对象数组
|
||||
*/
|
||||
public static Object[] getFiledValues(Object o) {
|
||||
String[] fieldNames = getFiledName(o);
|
||||
Object[] value = new Object[fieldNames.length];
|
||||
for (int i = 0; i < fieldNames.length; i++) {
|
||||
value[i] = getFieldValueByName(fieldNames[i], o);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,276 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 调用 Restful 接口 Util
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
@Slf4j
|
||||
public class RestUtil {
|
||||
|
||||
private static String domain = null;
|
||||
|
||||
public static String getDomain() {
|
||||
if (domain == null) {
|
||||
domain = SpringContextUtils.getDomain();
|
||||
// issues/2959
|
||||
// 微服务版集成企业微信单点登录
|
||||
// 因为微服务版没有端口号,导致 SpringContextUtils.getDomain() 方法获取的域名的端口号变成了:-1所以出问题了,只需要把这个-1给去掉就可以了。
|
||||
String port=":-1";
|
||||
if (domain.endsWith(port)) {
|
||||
domain = domain.substring(0, domain.length() - 3);
|
||||
}
|
||||
}
|
||||
return domain;
|
||||
}
|
||||
|
||||
public static String path = null;
|
||||
|
||||
public static String getPath() {
|
||||
if (path == null) {
|
||||
path = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path");
|
||||
}
|
||||
return oConvertUtils.getString(path);
|
||||
}
|
||||
|
||||
public static String getBaseUrl() {
|
||||
String basepath = null;
|
||||
try {
|
||||
basepath = getDomain() + getPath();
|
||||
} catch (Exception e) {
|
||||
log.warn(e.getMessage(),e);
|
||||
}
|
||||
|
||||
//定时任务情况下,通过request是获取不到domain的,这种情况下通过配置获取pc后台域名
|
||||
if(oConvertUtils.isEmpty(basepath)){
|
||||
JeecgBaseConfig jeecgBaseConfig = SpringContextUtils.getBean(JeecgBaseConfig.class);
|
||||
basepath = jeecgBaseConfig.getDomainUrl().getPc();
|
||||
}
|
||||
log.info(" RestUtil.getBaseUrl: " + basepath);
|
||||
return basepath;
|
||||
}
|
||||
|
||||
/**
|
||||
* RestAPI 调用器
|
||||
*/
|
||||
private final static RestTemplate RT;
|
||||
|
||||
static {
|
||||
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||
requestFactory.setConnectTimeout(3000);
|
||||
requestFactory.setReadTimeout(3000);
|
||||
RT = new RestTemplate(requestFactory);
|
||||
// 解决乱码问题
|
||||
RT.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public static RestTemplate getRestTemplate() {
|
||||
return RT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url) {
|
||||
return getNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url, JSONObject variables) {
|
||||
return getNative(url, variables, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url, JSONObject variables, JSONObject params) {
|
||||
return getNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> getNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.GET, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url) {
|
||||
return postNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url, JSONObject params) {
|
||||
return postNative(url, null, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url, JSONObject variables, JSONObject params) {
|
||||
return postNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 POST 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> postNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.POST, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url) {
|
||||
return putNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url, JSONObject params) {
|
||||
return putNative(url, null, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url, JSONObject variables, JSONObject params) {
|
||||
return putNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> putNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.PUT, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求
|
||||
*/
|
||||
public static JSONObject delete(String url) {
|
||||
return deleteNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求
|
||||
*/
|
||||
public static JSONObject delete(String url, JSONObject variables, JSONObject params) {
|
||||
return deleteNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> deleteNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.DELETE, null, variables, params, JSONObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> request(String url, HttpMethod method, JSONObject variables, JSONObject params) {
|
||||
return request(url, method, getHeaderApplicationJson(), variables, params, JSONObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param method 请求方式
|
||||
* @param headers 请求头 可空
|
||||
* @param variables 请求url参数 可空
|
||||
* @param params 请求body参数 可空
|
||||
* @param responseType 返回类型
|
||||
* @return ResponseEntity<responseType>
|
||||
*/
|
||||
public static <T> ResponseEntity<T> request(String url, HttpMethod method, HttpHeaders headers, JSONObject variables, Object params, Class<T> responseType) {
|
||||
log.info(" RestUtil --- request --- url = "+ url);
|
||||
if (StringUtils.isEmpty(url)) {
|
||||
throw new RuntimeException("url 不能为空");
|
||||
}
|
||||
if (method == null) {
|
||||
throw new RuntimeException("method 不能为空");
|
||||
}
|
||||
if (headers == null) {
|
||||
headers = new HttpHeaders();
|
||||
}
|
||||
// 请求体
|
||||
String body = "";
|
||||
if (params != null) {
|
||||
if (params instanceof JSONObject) {
|
||||
body = ((JSONObject) params).toJSONString();
|
||||
|
||||
} else {
|
||||
body = params.toString();
|
||||
}
|
||||
}
|
||||
// 拼接 url 参数
|
||||
if (variables != null && !variables.isEmpty()) {
|
||||
url += ("?" + asUrlVariables(variables));
|
||||
}
|
||||
// 发送请求
|
||||
HttpEntity<String> request = new HttpEntity<>(body, headers);
|
||||
return RT.exchange(url, method, request, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取JSON请求头
|
||||
*/
|
||||
public static HttpHeaders getHeaderApplicationJson() {
|
||||
return getHeader(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求头
|
||||
*/
|
||||
public static HttpHeaders getHeader(String mediaType) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType(mediaType));
|
||||
headers.add("Accept", mediaType);
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 JSONObject 转为 a=1&b=2&c=3...&n=n 的形式
|
||||
*/
|
||||
public static String asUrlVariables(JSONObject variables) {
|
||||
Map<String, Object> source = variables.getInnerMap();
|
||||
Iterator<String> it = source.keySet().iterator();
|
||||
StringBuilder urlVariables = new StringBuilder();
|
||||
while (it.hasNext()) {
|
||||
String key = it.next();
|
||||
String value = "";
|
||||
Object object = source.get(key);
|
||||
if (object != null) {
|
||||
if (!StringUtils.isEmpty(object.toString())) {
|
||||
value = object.toString();
|
||||
}
|
||||
}
|
||||
urlVariables.append("&").append(key).append("=").append(value);
|
||||
}
|
||||
// 去掉第一个&
|
||||
return urlVariables.substring(1);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,259 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* sql注入处理工具类
|
||||
*
|
||||
* @author zhoujf
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlInjectionUtil {
|
||||
/**
|
||||
* sign 用于表字典加签的盐值【SQL漏洞】
|
||||
* (上线修改值 20200501,同步修改前端的盐值)
|
||||
*/
|
||||
private final static String TABLE_DICT_SIGN_SALT = "20200501";
|
||||
private final static String XSS_STR = "and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|user()";
|
||||
|
||||
/**
|
||||
* 正则 user() 匹配更严谨
|
||||
*/
|
||||
private final static String REGULAR_EXPRE_USER = "user[\\s]*\\([\\s]*\\)";
|
||||
/**正则 show tables*/
|
||||
private final static String SHOW_TABLES = "show\\s+tables";
|
||||
|
||||
/**
|
||||
* 针对表字典进行额外的sign签名校验(增加安全机制)
|
||||
* @param dictCode:
|
||||
* @param sign:
|
||||
* @param request:
|
||||
* @Return: void
|
||||
*/
|
||||
public static void checkDictTableSign(String dictCode, String sign, HttpServletRequest request) {
|
||||
//表字典SQL注入漏洞,签名校验
|
||||
String accessToken = request.getHeader("X-Access-Token");
|
||||
String signStr = dictCode + SqlInjectionUtil.TABLE_DICT_SIGN_SALT + accessToken;
|
||||
String javaSign = SecureUtil.md5(signStr);
|
||||
if (!javaSign.equals(sign)) {
|
||||
log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode);
|
||||
throw new JeecgBootException("无权限访问!");
|
||||
}
|
||||
log.info(" 表字典,SQL注入漏洞签名校验成功!sign=" + sign + ",dictCode=" + dictCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
* @param value
|
||||
*/
|
||||
public static void filterContent(String value) {
|
||||
filterContent(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static void filterContent(String value, String customXssString) {
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
// 统一转为小写
|
||||
value = value.toLowerCase();
|
||||
//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
|
||||
value = value.replaceAll("/\\*.*\\*/","");
|
||||
|
||||
String[] xssArr = XSS_STR.split("\\|");
|
||||
for (int i = 0; i < xssArr.length; i++) {
|
||||
if (value.indexOf(xssArr[i]) > -1) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
//update-begin-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
|
||||
if (customXssString != null) {
|
||||
String[] xssArr2 = customXssString.split("\\|");
|
||||
for (int i = 0; i < xssArr2.length; i++) {
|
||||
if (value.indexOf(xssArr2[i]) > -1) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr2[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
|
||||
if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
* @param values
|
||||
*/
|
||||
public static void filterContent(String[] values) {
|
||||
filterContent(values, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
*
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static void filterContent(String[] values, String customXssString) {
|
||||
String[] xssArr = XSS_STR.split("\\|");
|
||||
for (String value : values) {
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
// 统一转为小写
|
||||
value = value.toLowerCase();
|
||||
//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
|
||||
value = value.replaceAll("/\\*.*\\*/","");
|
||||
|
||||
for (int i = 0; i < xssArr.length; i++) {
|
||||
if (value.indexOf(xssArr[i]) > -1) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
//update-begin-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
|
||||
if (customXssString != null) {
|
||||
String[] xssArr2 = customXssString.split("\\|");
|
||||
for (int i = 0; i < xssArr2.length; i++) {
|
||||
if (value.indexOf(xssArr2[i]) > -1) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr2[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
|
||||
if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【提醒:不通用】
|
||||
* 仅用于字典条件SQL参数,注入过滤
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
//@Deprecated
|
||||
public static void specialFilterContentForDictSql(String value) {
|
||||
String specialXssStr = " exec | insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|user()";
|
||||
String[] xssArr = specialXssStr.split("\\|");
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
// 统一转为小写
|
||||
value = value.toLowerCase();
|
||||
//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
|
||||
value = value.replaceAll("/\\*.*\\*/","");
|
||||
|
||||
for (int i = 0; i < xssArr.length; i++) {
|
||||
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【提醒:不通用】
|
||||
* 仅用于Online报表SQL解析,注入过滤
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
//@Deprecated
|
||||
public static void specialFilterContentForOnlineReport(String value) {
|
||||
String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |user()";
|
||||
String[] xssArr = specialXssStr.split("\\|");
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
// 统一转为小写
|
||||
value = value.toLowerCase();
|
||||
//SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE
|
||||
value = value.replaceAll("/\\*.*\\*/","");
|
||||
|
||||
for (int i = 0; i < xssArr.length; i++) {
|
||||
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
|
||||
if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断给定的字段是不是类中的属性
|
||||
* @param field 字段名
|
||||
* @param clazz 类对象
|
||||
* @return
|
||||
*/
|
||||
public static boolean isClassField(String field, Class clazz){
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for(int i=0;i<fields.length;i++){
|
||||
String fieldName = fields[i].getName();
|
||||
String tableColumnName = oConvertUtils.camelToUnderline(fieldName);
|
||||
if(fieldName.equalsIgnoreCase(field) || tableColumnName.equalsIgnoreCase(field)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断给定的多个字段是不是类中的属性
|
||||
* @param fieldSet 字段名set
|
||||
* @param clazz 类对象
|
||||
* @return
|
||||
*/
|
||||
public static boolean isClassField(Set<String> fieldSet, Class clazz){
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for(String field: fieldSet){
|
||||
boolean exist = false;
|
||||
for(int i=0;i<fields.length;i++){
|
||||
String fieldName = fields[i].getName();
|
||||
String tableColumnName = oConvertUtils.camelToUnderline(fieldName);
|
||||
if(fieldName.equalsIgnoreCase(field) || tableColumnName.equalsIgnoreCase(field)){
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!exist){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
/**
|
||||
* 系统公告自定义跳转方式
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public enum SysAnnmentTypeEnum {
|
||||
/**
|
||||
* 邮件跳转组件
|
||||
*/
|
||||
EMAIL("email", "component", "modules/eoa/email/modals/EoaEmailInForm"),
|
||||
/**
|
||||
* 流程跳转到我的任务
|
||||
*/
|
||||
BPM("bpm", "url", "/bpm/task/MyTaskList");
|
||||
|
||||
/**
|
||||
* 业务类型(email:邮件 bpm:流程)
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 打开方式 组件:component 路由:url
|
||||
*/
|
||||
private String openType;
|
||||
/**
|
||||
* 组件/路由 地址
|
||||
*/
|
||||
private String openPage;
|
||||
|
||||
SysAnnmentTypeEnum(String type, String openType, String openPage) {
|
||||
this.type = type;
|
||||
this.openType = openType;
|
||||
this.openPage = openPage;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getOpenType() {
|
||||
return openType;
|
||||
}
|
||||
|
||||
public void setOpenType(String openType) {
|
||||
this.openType = openType;
|
||||
}
|
||||
|
||||
public String getOpenPage() {
|
||||
return openPage;
|
||||
}
|
||||
|
||||
public void setOpenPage(String openPage) {
|
||||
this.openPage = openPage;
|
||||
}
|
||||
|
||||
public static SysAnnmentTypeEnum getByType(String type) {
|
||||
if (oConvertUtils.isEmpty(type)) {
|
||||
return null;
|
||||
}
|
||||
for (SysAnnmentTypeEnum val : values()) {
|
||||
if (val.getType().equals(type)) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,125 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.api.CommonAPI;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
|
||||
import org.jeecg.common.exception.JeecgBoot401Exception;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @Author scott
|
||||
* @Date 2019/9/23 14:12
|
||||
* @Description: 编程校验token有效性
|
||||
*/
|
||||
@Slf4j
|
||||
public class TokenUtils {
|
||||
|
||||
/**
|
||||
* 获取 request 里传递的 token
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static String getTokenByRequest(HttpServletRequest request) {
|
||||
String token = request.getParameter("token");
|
||||
if (token == null) {
|
||||
token = request.getHeader("X-Access-Token");
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Token
|
||||
*/
|
||||
public static boolean verifyToken(HttpServletRequest request, CommonAPI commonApi, RedisUtil redisUtil) {
|
||||
log.debug(" -- url --" + request.getRequestURL());
|
||||
String token = getTokenByRequest(request);
|
||||
return TokenUtils.verifyToken(token, commonApi, redisUtil);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Token
|
||||
*/
|
||||
public static boolean verifyToken(String token, CommonAPI commonApi, RedisUtil redisUtil) {
|
||||
if (StringUtils.isBlank(token)) {
|
||||
throw new JeecgBoot401Exception("token不能为空!");
|
||||
}
|
||||
|
||||
// 解密获得username,用于和数据库进行对比
|
||||
String username = JwtUtil.getUsername(token);
|
||||
if (username == null) {
|
||||
throw new JeecgBoot401Exception("token非法无效!");
|
||||
}
|
||||
|
||||
// 查询用户信息
|
||||
LoginUser user = TokenUtils.getLoginUser(username, commonApi, redisUtil);
|
||||
//LoginUser user = commonApi.getUserByName(username);
|
||||
if (user == null) {
|
||||
throw new JeecgBoot401Exception("用户不存在!");
|
||||
}
|
||||
// 判断用户状态
|
||||
if (user.getStatus() != 1) {
|
||||
throw new JeecgBoot401Exception("账号已被锁定,请联系管理员!");
|
||||
}
|
||||
// 校验token是否超时失效 & 或者账号密码是否错误
|
||||
if (!jwtTokenRefresh(token, username, user.getPassword(), redisUtil)) {
|
||||
throw new JeecgBoot401Exception(CommonConstant.TOKEN_IS_INVALID_MSG);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token(保证用户在线操作不掉线)
|
||||
* @param token
|
||||
* @param userName
|
||||
* @param passWord
|
||||
* @param redisUtil
|
||||
* @return
|
||||
*/
|
||||
private static boolean jwtTokenRefresh(String token, String userName, String passWord, RedisUtil redisUtil) {
|
||||
String cacheToken = oConvertUtils.getString(redisUtil.get(CommonConstant.PREFIX_USER_TOKEN + token));
|
||||
if (oConvertUtils.isNotEmpty(cacheToken)) {
|
||||
// 校验token有效性
|
||||
if (!JwtUtil.verify(cacheToken, userName, passWord)) {
|
||||
String newAuthorization = JwtUtil.sign(userName, passWord);
|
||||
// 设置Toekn缓存有效时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, newAuthorization);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户
|
||||
*
|
||||
* @param commonApi
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public static LoginUser getLoginUser(String username, CommonAPI commonApi, RedisUtil redisUtil) {
|
||||
LoginUser loginUser = null;
|
||||
String loginUserKey = CacheConstant.SYS_USERS_CACHE + "::" + username;
|
||||
//【重要】此处通过redis原生获取缓存用户,是为了解决微服务下system服务挂了,其他服务互调不通问题---
|
||||
if (redisUtil.hasKey(loginUserKey)) {
|
||||
try {
|
||||
loginUser = (LoginUser) redisUtil.get(loginUserKey);
|
||||
//解密用户
|
||||
SensitiveInfoUtil.handlerObject(loginUser, false);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
// 查询用户信息
|
||||
loginUser = commonApi.getUserByName(username);
|
||||
}
|
||||
return loginUser;
|
||||
}
|
||||
}
|
||||
@ -1,124 +0,0 @@
|
||||
package org.jeecg.common.util.encryption;
|
||||
|
||||
import org.apache.shiro.codec.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* @Description: AES 加密
|
||||
* @author: jeecg-boot
|
||||
* @date: 2022/3/30 11:48
|
||||
*/
|
||||
public class AesEncryptUtil {
|
||||
|
||||
/**
|
||||
* 使用AES-128-CBC加密模式 key和iv可以相同
|
||||
*/
|
||||
private static String KEY = EncryptedString.key;
|
||||
private static String IV = EncryptedString.iv;
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
* @param data 要加密的数据
|
||||
* @param key 加密key
|
||||
* @param iv 加密iv
|
||||
* @return 加密的结果
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String data, String key, String iv) throws Exception {
|
||||
try {
|
||||
|
||||
//"算法/模式/补码方式"NoPadding PkcsPadding
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
int blockSize = cipher.getBlockSize();
|
||||
|
||||
byte[] dataBytes = data.getBytes();
|
||||
int plaintextLength = dataBytes.length;
|
||||
if (plaintextLength % blockSize != 0) {
|
||||
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
|
||||
}
|
||||
|
||||
byte[] plaintext = new byte[plaintextLength];
|
||||
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
|
||||
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
|
||||
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
|
||||
byte[] encrypted = cipher.doFinal(plaintext);
|
||||
|
||||
return Base64.encodeToString(encrypted);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
* @param data 要解密的数据
|
||||
* @param key 解密key
|
||||
* @param iv 解密iv
|
||||
* @return 解密的结果
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String desEncrypt(String data, String key, String iv) throws Exception {
|
||||
//update-begin-author:taoyan date:2022-5-23 for:VUEN-1084 【vue3】online表单测试发现的新问题 6、解密报错 ---解码失败应该把异常抛出去,在外面处理
|
||||
byte[] encrypted1 = Base64.decode(data);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
||||
|
||||
byte[] original = cipher.doFinal(encrypted1);
|
||||
String originalString = new String(original);
|
||||
//加密解码后的字符串会出现\u0000
|
||||
return originalString.replaceAll("\\u0000", "");
|
||||
//update-end-author:taoyan date:2022-5-23 for:VUEN-1084 【vue3】online表单测试发现的新问题 6、解密报错 ---解码失败应该把异常抛出去,在外面处理
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用默认的key和iv加密
|
||||
* @param data
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String data) throws Exception {
|
||||
return encrypt(data, KEY, IV);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用默认的key和iv解密
|
||||
* @param data
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String desEncrypt(String data) throws Exception {
|
||||
return desEncrypt(data, KEY, IV);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * 测试
|
||||
// */
|
||||
// public static void main(String args[]) throws Exception {
|
||||
// String test1 = "sa";
|
||||
// String test =new String(test1.getBytes(),"UTF-8");
|
||||
// String data = null;
|
||||
// String key = KEY;
|
||||
// String iv = IV;
|
||||
// // /g2wzfqvMOeazgtsUVbq1kmJawROa6mcRAzwG1/GeJ4=
|
||||
// data = encrypt(test, key, iv);
|
||||
// System.out.println("数据:"+test);
|
||||
// System.out.println("加密:"+data);
|
||||
// String jiemi =desEncrypt(data, key, iv).trim();
|
||||
// System.out.println("解密:"+jiemi);
|
||||
// }
|
||||
|
||||
}
|
||||
@ -1,166 +0,0 @@
|
||||
package org.jeecg.common.util.filter;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @author: lsq
|
||||
* @date: 2021年08月09日 15:29
|
||||
*/
|
||||
public class FileTypeFilter {
|
||||
|
||||
/**文件后缀*/
|
||||
private static String[] forbidType = {"jsp","php"};
|
||||
|
||||
/**初始化文件头类型,不够的自行补充*/
|
||||
final static HashMap<String, String> FILE_TYPE_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
FILE_TYPE_MAP.put("3c25402070616765206c", "jsp");
|
||||
FILE_TYPE_MAP.put("3c3f7068700a0a2f2a2a0a202a205048", "php");
|
||||
/* fileTypeMap.put("ffd8ffe000104a464946", "jpg");
|
||||
fileTypeMap.put("89504e470d0a1a0a0000", "png");
|
||||
fileTypeMap.put("47494638396126026f01", "gif");
|
||||
fileTypeMap.put("49492a00227105008037", "tif");
|
||||
fileTypeMap.put("424d228c010000000000", "bmp");
|
||||
fileTypeMap.put("424d8240090000000000", "bmp");
|
||||
fileTypeMap.put("424d8e1b030000000000", "bmp");
|
||||
fileTypeMap.put("41433130313500000000", "dwg");
|
||||
fileTypeMap.put("3c21444f435459504520", "html");
|
||||
fileTypeMap.put("3c21646f637479706520", "htm");
|
||||
fileTypeMap.put("48544d4c207b0d0a0942", "css");
|
||||
fileTypeMap.put("696b2e71623d696b2e71", "js");
|
||||
fileTypeMap.put("7b5c727466315c616e73", "rtf");
|
||||
fileTypeMap.put("38425053000100000000", "psd");
|
||||
fileTypeMap.put("46726f6d3a203d3f6762", "eml");
|
||||
fileTypeMap.put("d0cf11e0a1b11ae10000", "doc");
|
||||
fileTypeMap.put("5374616E64617264204A", "mdb");
|
||||
fileTypeMap.put("252150532D41646F6265", "ps");
|
||||
fileTypeMap.put("255044462d312e350d0a", "pdf");
|
||||
fileTypeMap.put("2e524d46000000120001", "rmvb");
|
||||
fileTypeMap.put("464c5601050000000900", "flv");
|
||||
fileTypeMap.put("00000020667479706d70", "mp4");
|
||||
fileTypeMap.put("49443303000000002176", "mp3");
|
||||
fileTypeMap.put("000001ba210001000180", "mpg");
|
||||
fileTypeMap.put("3026b2758e66cf11a6d9", "wmv");
|
||||
fileTypeMap.put("52494646e27807005741", "wav");
|
||||
fileTypeMap.put("52494646d07d60074156", "avi");
|
||||
fileTypeMap.put("4d546864000000060001", "mid");
|
||||
fileTypeMap.put("504b0304140000000800", "zip");
|
||||
fileTypeMap.put("526172211a0700cf9073", "rar");
|
||||
fileTypeMap.put("235468697320636f6e66", "ini");
|
||||
fileTypeMap.put("504b03040a0000000000", "jar");
|
||||
fileTypeMap.put("4d5a9000030000000400", "exe");
|
||||
fileTypeMap.put("3c25402070616765206c", "jsp");
|
||||
fileTypeMap.put("4d616e69666573742d56", "mf");
|
||||
fileTypeMap.put("3c3f786d6c2076657273", "xml");
|
||||
fileTypeMap.put("494e5345525420494e54", "sql");
|
||||
fileTypeMap.put("7061636b616765207765", "java");
|
||||
fileTypeMap.put("406563686f206f66660d", "bat");
|
||||
fileTypeMap.put("1f8b0800000000000000", "gz");
|
||||
fileTypeMap.put("6c6f67346a2e726f6f74", "properties");
|
||||
fileTypeMap.put("cafebabe0000002e0041", "class");
|
||||
fileTypeMap.put("49545346030000006000", "chm");
|
||||
fileTypeMap.put("04000000010000001300", "mxp");
|
||||
fileTypeMap.put("504b0304140006000800", "docx");
|
||||
fileTypeMap.put("6431303a637265617465", "torrent");
|
||||
fileTypeMap.put("6D6F6F76", "mov");
|
||||
fileTypeMap.put("FF575043", "wpd");
|
||||
fileTypeMap.put("CFAD12FEC5FD746F", "dbx");
|
||||
fileTypeMap.put("2142444E", "pst");
|
||||
fileTypeMap.put("AC9EBD8F", "qdf");
|
||||
fileTypeMap.put("E3828596", "pwl");
|
||||
fileTypeMap.put("2E7261FD", "ram");*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileName
|
||||
* @return String
|
||||
* @description 通过文件后缀名获取文件类型
|
||||
*/
|
||||
private static String getFileTypeBySuffix(String fileName) {
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件类型过滤
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
public static void fileTypeFilter(MultipartFile file) throws Exception {
|
||||
String suffix = getFileType(file);
|
||||
for (String type : forbidType) {
|
||||
if (type.contains(suffix)) {
|
||||
throw new Exception("上传失败,非法文件类型:" + suffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过读取文件头部获得文件类型
|
||||
*
|
||||
* @param file
|
||||
* @return 文件类型
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
private static String getFileType(MultipartFile file) throws Exception {
|
||||
String fileExtendName = null;
|
||||
InputStream is;
|
||||
try {
|
||||
//is = new FileInputStream(file);
|
||||
is = file.getInputStream();
|
||||
byte[] b = new byte[10];
|
||||
is.read(b, 0, b.length);
|
||||
String fileTypeHex = String.valueOf(bytesToHexString(b));
|
||||
Iterator<String> keyIter = FILE_TYPE_MAP.keySet().iterator();
|
||||
while (keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
// 验证前5个字符比较
|
||||
if (key.toLowerCase().startsWith(fileTypeHex.toLowerCase().substring(0, 5))
|
||||
|| fileTypeHex.toLowerCase().substring(0, 5).startsWith(key.toLowerCase())) {
|
||||
fileExtendName = FILE_TYPE_MAP.get(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 如果不是上述类型,则判断扩展名
|
||||
if (StringUtils.isBlank(fileExtendName)) {
|
||||
String fileName = file.getOriginalFilename();
|
||||
return getFileTypeBySuffix(fileName);
|
||||
}
|
||||
is.close();
|
||||
return fileExtendName;
|
||||
} catch (Exception exception) {
|
||||
throw new Exception(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得文件头部字符串
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
private static String bytesToHexString(byte[] src) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (src == null || src.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
int v = src[i] & 0xFF;
|
||||
String hv = Integer.toHexString(v);
|
||||
if (hv.length() < 2) {
|
||||
stringBuilder.append(0);
|
||||
}
|
||||
stringBuilder.append(hv);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
@ -1,680 +0,0 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.sql.Date;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @Author 张代浩
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
public class oConvertUtils {
|
||||
public static boolean isEmpty(Object object) {
|
||||
if (object == null) {
|
||||
return (true);
|
||||
}
|
||||
if ("".equals(object)) {
|
||||
return (true);
|
||||
}
|
||||
if (CommonConstant.STRING_NULL.equals(object)) {
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(Object object) {
|
||||
if (object != null && !"".equals(object) && !object.equals(CommonConstant.STRING_NULL)) {
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
public static String decode(String strIn, String sourceCode, String targetCode) {
|
||||
String temp = code2code(strIn, sourceCode, targetCode);
|
||||
return temp;
|
||||
}
|
||||
|
||||
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
|
||||
public static String StrToUTF(String strIn, String sourceCode, String targetCode) {
|
||||
strIn = "";
|
||||
try {
|
||||
strIn = new String(strIn.getBytes("ISO-8859-1"), "GBK");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return strIn;
|
||||
|
||||
}
|
||||
|
||||
private static String code2code(String strIn, String sourceCode, String targetCode) {
|
||||
String strOut = null;
|
||||
if (strIn == null || "".equals(strIn.trim())) {
|
||||
return strIn;
|
||||
}
|
||||
try {
|
||||
byte[] b = strIn.getBytes(sourceCode);
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
System.out.print(b[i] + " ");
|
||||
}
|
||||
strOut = new String(b, targetCode);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return strOut;
|
||||
}
|
||||
|
||||
public static int getInt(String s, int defval) {
|
||||
if (s == null || s == "") {
|
||||
return (defval);
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return (defval);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInt(String s) {
|
||||
if (s == null || s == "") {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInt(String s, Integer df) {
|
||||
if (s == null || s == "") {
|
||||
return df;
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Integer[] getInts(String[] s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
Integer[] integer = new Integer[s.length];
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
integer[i] = Integer.parseInt(s[i]);
|
||||
}
|
||||
return integer;
|
||||
|
||||
}
|
||||
|
||||
public static double getDouble(String s, double defval) {
|
||||
if (s == null || s == "") {
|
||||
return (defval);
|
||||
}
|
||||
try {
|
||||
return (Double.parseDouble(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return (defval);
|
||||
}
|
||||
}
|
||||
|
||||
public static double getDou(Double s, double defval) {
|
||||
if (s == null) {
|
||||
return (defval);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*public static Short getShort(String s) {
|
||||
if (StringUtil.isNotEmpty(s)) {
|
||||
return (Short.parseShort(s));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
|
||||
public static int getInt(Object object, int defval) {
|
||||
if (isEmpty(object)) {
|
||||
return (defval);
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(object.toString()));
|
||||
} catch (NumberFormatException e) {
|
||||
return (defval);
|
||||
}
|
||||
}
|
||||
|
||||
public static Integer getInt(Object object) {
|
||||
if (isEmpty(object)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (Integer.parseInt(object.toString()));
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInt(BigDecimal s, int defval) {
|
||||
if (s == null) {
|
||||
return (defval);
|
||||
}
|
||||
return s.intValue();
|
||||
}
|
||||
|
||||
public static Integer[] getIntegerArry(String[] object) {
|
||||
int len = object.length;
|
||||
Integer[] result = new Integer[len];
|
||||
try {
|
||||
for (int i = 0; i < len; i++) {
|
||||
result[i] = new Integer(object[i].trim());
|
||||
}
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getString(String s) {
|
||||
return (getString(s, ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转义成Unicode编码
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
/*public static String escapeJava(Object s) {
|
||||
return StringEscapeUtils.escapeJava(getString(s));
|
||||
}*/
|
||||
|
||||
public static String getString(Object object) {
|
||||
if (isEmpty(object)) {
|
||||
return "";
|
||||
}
|
||||
return (object.toString().trim());
|
||||
}
|
||||
|
||||
public static String getString(int i) {
|
||||
return (String.valueOf(i));
|
||||
}
|
||||
|
||||
public static String getString(float i) {
|
||||
return (String.valueOf(i));
|
||||
}
|
||||
|
||||
public static String getString(String s, String defval) {
|
||||
if (isEmpty(s)) {
|
||||
return (defval);
|
||||
}
|
||||
return (s.trim());
|
||||
}
|
||||
|
||||
public static String getString(Object s, String defval) {
|
||||
if (isEmpty(s)) {
|
||||
return (defval);
|
||||
}
|
||||
return (s.toString().trim());
|
||||
}
|
||||
|
||||
public static long stringToLong(String str) {
|
||||
Long test = new Long(0);
|
||||
try {
|
||||
test = Long.valueOf(str);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return test.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本机IP
|
||||
*/
|
||||
public static String getIp() {
|
||||
String ip = null;
|
||||
try {
|
||||
InetAddress address = InetAddress.getLocalHost();
|
||||
ip = address.getHostAddress();
|
||||
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断一个类是否为基本数据类型。
|
||||
*
|
||||
* @param clazz
|
||||
* 要判断的类。
|
||||
* @return true 表示为基本数据类型。
|
||||
*/
|
||||
private static boolean isBaseDataType(Class clazz) throws Exception {
|
||||
return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class) || clazz.isPrimitive());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param request
|
||||
* IP
|
||||
* @return IP Address
|
||||
*/
|
||||
public static String getIpAddrByRequest(HttpServletRequest request) {
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 本机IP
|
||||
* @throws SocketException
|
||||
*/
|
||||
public static String getRealIp() throws SocketException {
|
||||
// 本地IP,如果没有配置外网IP则返回它
|
||||
String localip = null;
|
||||
// 外网IP
|
||||
String netip = null;
|
||||
|
||||
Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||
InetAddress ip = null;
|
||||
// 是否找到外网IP
|
||||
boolean finded = false;
|
||||
while (netInterfaces.hasMoreElements() && !finded) {
|
||||
NetworkInterface ni = netInterfaces.nextElement();
|
||||
Enumeration<InetAddress> address = ni.getInetAddresses();
|
||||
while (address.hasMoreElements()) {
|
||||
ip = address.nextElement();
|
||||
// 外网IP
|
||||
if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {
|
||||
netip = ip.getHostAddress();
|
||||
finded = true;
|
||||
break;
|
||||
} else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {
|
||||
// 内网IP
|
||||
localip = ip.getHostAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (netip != null && !"".equals(netip)) {
|
||||
return netip;
|
||||
} else {
|
||||
return localip;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* java去除字符串中的空格、回车、换行符、制表符
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String replaceBlank(String str) {
|
||||
String dest = "";
|
||||
if (str != null) {
|
||||
String reg = "\\s*|\t|\r|\n";
|
||||
Pattern p = Pattern.compile(reg);
|
||||
Matcher m = p.matcher(str);
|
||||
dest = m.replaceAll("");
|
||||
}
|
||||
return dest;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断元素是否在数组内
|
||||
*
|
||||
* @param substring
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static boolean isIn(String substring, String[] source) {
|
||||
if (source == null || source.length == 0) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < source.length; i++) {
|
||||
String aSource = source[i];
|
||||
if (aSource.equals(substring)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map对象
|
||||
*/
|
||||
public static Map<Object, Object> getHashMap() {
|
||||
return new HashMap<>(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* SET转换MAP
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static Map<Object, Object> setToMap(Set<Object> setobj) {
|
||||
Map<Object, Object> map = getHashMap();
|
||||
for (Iterator iterator = setobj.iterator(); iterator.hasNext();) {
|
||||
Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) iterator.next();
|
||||
map.put(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString().trim());
|
||||
}
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
public static boolean isInnerIp(String ipAddress) {
|
||||
boolean isInnerIp = false;
|
||||
long ipNum = getIpNum(ipAddress);
|
||||
/**
|
||||
* 私有IP:A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类 192.168.0.0-192.168.255.255 当然,还有127这个网段是环回地址
|
||||
**/
|
||||
long aBegin = getIpNum("10.0.0.0");
|
||||
long aEnd = getIpNum("10.255.255.255");
|
||||
long bBegin = getIpNum("172.16.0.0");
|
||||
long bEnd = getIpNum("172.31.255.255");
|
||||
long cBegin = getIpNum("192.168.0.0");
|
||||
long cEnd = getIpNum("192.168.255.255");
|
||||
String localIp = "127.0.0.1";
|
||||
isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || localIp.equals(ipAddress);
|
||||
return isInnerIp;
|
||||
}
|
||||
|
||||
private static long getIpNum(String ipAddress) {
|
||||
String[] ip = ipAddress.split("\\.");
|
||||
long a = Integer.parseInt(ip[0]);
|
||||
long b = Integer.parseInt(ip[1]);
|
||||
long c = Integer.parseInt(ip[2]);
|
||||
long d = Integer.parseInt(ip[3]);
|
||||
|
||||
long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
|
||||
return ipNum;
|
||||
}
|
||||
|
||||
private static boolean isInner(long userIp, long begin, long end) {
|
||||
return (userIp >= begin) && (userIp <= end);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将下划线大写方式命名的字符串转换为驼峰式。
|
||||
* 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
|
||||
* 例如:hello_world->helloWorld
|
||||
*
|
||||
* @param name
|
||||
* 转换前的下划线大写方式命名的字符串
|
||||
* @return 转换后的驼峰式命名的字符串
|
||||
*/
|
||||
public static String camelName(String name) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
// 快速检查
|
||||
if (name == null || name.isEmpty()) {
|
||||
// 没必要转换
|
||||
return "";
|
||||
} else if (!name.contains(SymbolConstant.UNDERLINE)) {
|
||||
// 不含下划线,仅将首字母小写
|
||||
//update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
//update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase();
|
||||
//update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
}
|
||||
// 用下划线将原始字符串分割
|
||||
String[] camels = name.split("_");
|
||||
for (String camel : camels) {
|
||||
// 跳过原始字符串中开头、结尾的下换线或双重下划线
|
||||
if (camel.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
// 处理真正的驼峰片段
|
||||
if (result.length() == 0) {
|
||||
// 第一个驼峰片段,全部字母都小写
|
||||
result.append(camel.toLowerCase());
|
||||
} else {
|
||||
// 其他的驼峰片段,首字母大写
|
||||
result.append(camel.substring(0, 1).toUpperCase());
|
||||
result.append(camel.substring(1).toLowerCase());
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将下划线大写方式命名的字符串转换为驼峰式。
|
||||
* 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
|
||||
* 例如:hello_world,test_id->helloWorld,testId
|
||||
*
|
||||
* @param name
|
||||
* 转换前的下划线大写方式命名的字符串
|
||||
* @return 转换后的驼峰式命名的字符串
|
||||
*/
|
||||
public static String camelNames(String names) {
|
||||
if(names==null||"".equals(names)){
|
||||
return null;
|
||||
}
|
||||
StringBuffer sf = new StringBuffer();
|
||||
String[] fs = names.split(",");
|
||||
for (String field : fs) {
|
||||
field = camelName(field);
|
||||
sf.append(field + ",");
|
||||
}
|
||||
String result = sf.toString();
|
||||
return result.substring(0, result.length() - 1);
|
||||
}
|
||||
|
||||
//update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
/**
|
||||
* 将下划线大写方式命名的字符串转换为驼峰式。(首字母写)
|
||||
* 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
|
||||
* 例如:hello_world->HelloWorld
|
||||
*
|
||||
* @param name
|
||||
* 转换前的下划线大写方式命名的字符串
|
||||
* @return 转换后的驼峰式命名的字符串
|
||||
*/
|
||||
public static String camelNameCapFirst(String name) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
// 快速检查
|
||||
if (name == null || name.isEmpty()) {
|
||||
// 没必要转换
|
||||
return "";
|
||||
} else if (!name.contains(SymbolConstant.UNDERLINE)) {
|
||||
// 不含下划线,仅将首字母小写
|
||||
return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase();
|
||||
}
|
||||
// 用下划线将原始字符串分割
|
||||
String[] camels = name.split("_");
|
||||
for (String camel : camels) {
|
||||
// 跳过原始字符串中开头、结尾的下换线或双重下划线
|
||||
if (camel.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
// 其他的驼峰片段,首字母大写
|
||||
result.append(camel.substring(0, 1).toUpperCase());
|
||||
result.append(camel.substring(1).toLowerCase());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
//update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
|
||||
|
||||
/**
|
||||
* 将驼峰命名转化成下划线
|
||||
* @param para
|
||||
* @return
|
||||
*/
|
||||
public static String camelToUnderline(String para){
|
||||
int length = 3;
|
||||
if(para.length()<length){
|
||||
return para.toLowerCase();
|
||||
}
|
||||
StringBuilder sb=new StringBuilder(para);
|
||||
//定位
|
||||
int temp=0;
|
||||
//从第三个字符开始 避免命名不规范
|
||||
for(int i=2;i<para.length();i++){
|
||||
if(Character.isUpperCase(para.charAt(i))){
|
||||
sb.insert(i+temp, "_");
|
||||
temp+=1;
|
||||
}
|
||||
}
|
||||
return sb.toString().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机数
|
||||
* @param place 定义随机数的位数
|
||||
*/
|
||||
public static String randomGen(int place) {
|
||||
String base = "qwertyuioplkjhgfdsazxcvbnmQAZWSXEDCRFVTGBYHNUJMIKLOP0123456789";
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Random rd = new Random();
|
||||
for(int i=0;i<place;i++) {
|
||||
sb.append(base.charAt(rd.nextInt(base.length())));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类的所有属性,包括父类
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static Field[] getAllFields(Object object) {
|
||||
Class<?> clazz = object.getClass();
|
||||
List<Field> fieldList = new ArrayList<>();
|
||||
while (clazz != null) {
|
||||
fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
Field[] fields = new Field[fieldList.size()];
|
||||
fieldList.toArray(fields);
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将map的key全部转成小写
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static List<Map<String, Object>> toLowerCasePageList(List<Map<String, Object>> list){
|
||||
List<Map<String, Object>> select = new ArrayList<>();
|
||||
for (Map<String, Object> row : list) {
|
||||
Map<String, Object> resultMap = new HashMap<>(5);
|
||||
Set<String> keySet = row.keySet();
|
||||
for (String key : keySet) {
|
||||
String newKey = key.toLowerCase();
|
||||
resultMap.put(newKey, row.get(key));
|
||||
}
|
||||
select.add(resultMap);
|
||||
}
|
||||
return select;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将entityList转换成modelList
|
||||
* @param fromList
|
||||
* @param tClass
|
||||
* @param <F>
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static<F,T> List<T> entityListToModelList(List<F> fromList, Class<T> tClass){
|
||||
if(fromList == null || fromList.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
List<T> tList = new ArrayList<>();
|
||||
for(F f : fromList){
|
||||
T t = entityToModel(f, tClass);
|
||||
tList.add(t);
|
||||
}
|
||||
return tList;
|
||||
}
|
||||
|
||||
public static<F,T> T entityToModel(F entity, Class<T> modelClass) {
|
||||
log.debug("entityToModel : Entity属性的值赋值到Model");
|
||||
Object model = null;
|
||||
if (entity == null || modelClass ==null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
model = modelClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
log.error("entityToModel : 实例化异常", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error("entityToModel : 安全权限异常", e);
|
||||
}
|
||||
BeanUtils.copyProperties(entity, model);
|
||||
return (T)model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 list 是否为空
|
||||
*
|
||||
* @param list
|
||||
* @return true or false
|
||||
* list == null : true
|
||||
* list.size() == 0 : true
|
||||
*/
|
||||
public static boolean listIsEmpty(Collection list) {
|
||||
return (list == null || list.size() == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 list 是否不为空
|
||||
*
|
||||
* @param list
|
||||
* @return true or false
|
||||
* list == null : false
|
||||
* list.size() == 0 : false
|
||||
*/
|
||||
public static boolean listIsNotEmpty(Collection list) {
|
||||
return !listIsEmpty(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取静态文本内容
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
public static String readStatic(String url) {
|
||||
String json = "";
|
||||
try {
|
||||
//换个写法,解决springboot读取jar包中文件的问题
|
||||
InputStream stream = oConvertUtils.class.getClassLoader().getResourceAsStream(url.replace("classpath:", ""));
|
||||
json = IOUtils.toString(stream,"UTF-8");
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
@ -1,181 +0,0 @@
|
||||
package org.jeecg.common.util.security;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 查询表/字段 黑名单处理
|
||||
* @Author taoYan
|
||||
* @Date 2022/3/17 11:21
|
||||
**/
|
||||
@Slf4j
|
||||
public abstract class AbstractQueryBlackListHandler {
|
||||
|
||||
/**
|
||||
* key-表名
|
||||
* value-字段名,多个逗号隔开
|
||||
* 两种配置方式-- 全部配置成小写
|
||||
* ruleMap.put("sys_user", "*")sys_user所有的字段不支持查询
|
||||
* ruleMap.put("sys_user", "username,password")sys_user中的username和password不支持查询
|
||||
*/
|
||||
public static Map<String, String> ruleMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
ruleMap.put("sys_user", "password,salt");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 sql语句 获取表和字段信息,需要到具体的实现类重写此方法-
|
||||
* 不同的场景 处理可能不太一样 需要自定义,但是返回值确定
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
protected abstract List<QueryTable> getQueryTableInfo(String sql);
|
||||
|
||||
|
||||
/**
|
||||
* 校验sql语句 成功返回true
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
public boolean isPass(String sql) {
|
||||
List<QueryTable> list = null;
|
||||
//【jeecg-boot/issues/4040】在线报表不支持子查询,解析报错 #4040
|
||||
try {
|
||||
list = this.getQueryTableInfo(sql.toLowerCase());
|
||||
} catch (Exception e) {
|
||||
log.warn("校验sql语句,解析报错:{}",e.getMessage());
|
||||
}
|
||||
|
||||
if(list==null){
|
||||
return true;
|
||||
}
|
||||
log.info("--获取sql信息--", list.toString());
|
||||
boolean flag = true;
|
||||
for (QueryTable table : list) {
|
||||
String name = table.getName();
|
||||
String fieldString = ruleMap.get(name);
|
||||
// 有没有配置这张表
|
||||
if (fieldString != null) {
|
||||
if ("*".equals(fieldString) || table.isAll()) {
|
||||
flag = false;
|
||||
log.warn("sql黑名单校验,表【"+name+"】禁止查询");
|
||||
break;
|
||||
} else if (table.existSameField(fieldString)) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询的表的信息
|
||||
*/
|
||||
protected class QueryTable {
|
||||
//表名
|
||||
private String name;
|
||||
//表的别名
|
||||
private String alias;
|
||||
// 字段名集合
|
||||
private Set<String> fields;
|
||||
// 是否查询所有字段
|
||||
private boolean all;
|
||||
|
||||
public QueryTable() {
|
||||
}
|
||||
|
||||
public QueryTable(String name, String alias) {
|
||||
this.name = name;
|
||||
this.alias = alias;
|
||||
this.all = false;
|
||||
this.fields = new HashSet<>();
|
||||
}
|
||||
|
||||
public void addField(String field) {
|
||||
this.fields.add(field);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Set<String> getFields() {
|
||||
return new HashSet<>(fields);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setFields(Set<String> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
public boolean isAll() {
|
||||
return all;
|
||||
}
|
||||
|
||||
public void setAll(boolean all) {
|
||||
this.all = all;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有相同字段
|
||||
*
|
||||
* @param fieldString
|
||||
* @return
|
||||
*/
|
||||
public boolean existSameField(String fieldString) {
|
||||
String[] arr = fieldString.split(",");
|
||||
for (String exp : fields) {
|
||||
for (String config : arr) {
|
||||
if (exp.equals(config)) {
|
||||
// 非常明确的列直接比较
|
||||
log.warn("sql黑名单校验,表【"+name+"】中字段【"+config+"】禁止查询");
|
||||
return true;
|
||||
} else {
|
||||
// 使用表达式的列 只能判读字符串包含了
|
||||
String aliasColumn = config;
|
||||
if (alias != null && alias.length() > 0) {
|
||||
aliasColumn = alias + "." + config;
|
||||
}
|
||||
if (exp.indexOf(aliasColumn) > 0) {
|
||||
log.warn("sql黑名单校验,表【"+name+"】中字段【"+config+"】禁止查询");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QueryTable{" +
|
||||
"name='" + name + '\'' +
|
||||
", alias='" + alias + '\'' +
|
||||
", fields=" + fields +
|
||||
", all=" + all +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public String getError(){
|
||||
// TODO
|
||||
return "系统设置了安全规则,敏感表和敏感字段禁止查询,联系管理员授权!";
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
package org.jeecg.config;
|
||||
|
||||
import org.jeecg.config.vo.DomainUrl;
|
||||
import org.jeecg.config.vo.Path;
|
||||
import org.jeecg.config.vo.Shiro;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
/**
|
||||
* 加载项目配置
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Component("jeecgBaseConfig")
|
||||
@ConfigurationProperties(prefix = "jeecg")
|
||||
public class JeecgBaseConfig {
|
||||
/**
|
||||
* 签名密钥串(字典等敏感接口)
|
||||
* @TODO 降低使用成本加的默认值,实际以 yml配置 为准
|
||||
*/
|
||||
private String signatureSecret = "dd05f1c54d63749eda95f9fa6d49v442a";
|
||||
/**
|
||||
* 需要加强校验的接口清单
|
||||
*/
|
||||
private String signUrls;
|
||||
/**
|
||||
* 上传模式
|
||||
* 本地:local\Minio:minio\阿里云:alioss
|
||||
*/
|
||||
private String uploadType;
|
||||
/**
|
||||
* 是否启用安全模式
|
||||
*/
|
||||
private Boolean safeMode = false;
|
||||
/**
|
||||
* shiro拦截排除
|
||||
*/
|
||||
private Shiro shiro;
|
||||
/**
|
||||
* 上传文件配置
|
||||
*/
|
||||
private Path path;
|
||||
|
||||
/**
|
||||
* 前端页面访问地址
|
||||
* pc: http://localhost:3100
|
||||
* app: http://localhost:8051
|
||||
*/
|
||||
private DomainUrl domainUrl;
|
||||
|
||||
/**
|
||||
* 文件预览
|
||||
*/
|
||||
private String fileViewDomain;
|
||||
|
||||
public Boolean getSafeMode() {
|
||||
return safeMode;
|
||||
}
|
||||
|
||||
public void setSafeMode(Boolean safeMode) {
|
||||
this.safeMode = safeMode;
|
||||
}
|
||||
|
||||
public String getSignatureSecret() {
|
||||
return signatureSecret;
|
||||
}
|
||||
|
||||
public void setSignatureSecret(String signatureSecret) {
|
||||
this.signatureSecret = signatureSecret;
|
||||
}
|
||||
|
||||
public Shiro getShiro() {
|
||||
return shiro;
|
||||
}
|
||||
|
||||
public void setShiro(Shiro shiro) {
|
||||
this.shiro = shiro;
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public DomainUrl getDomainUrl() {
|
||||
return domainUrl;
|
||||
}
|
||||
|
||||
public void setDomainUrl(DomainUrl domainUrl) {
|
||||
this.domainUrl = domainUrl;
|
||||
}
|
||||
public String getSignUrls() {
|
||||
return signUrls;
|
||||
}
|
||||
|
||||
public void setSignUrls(String signUrls) {
|
||||
this.signUrls = signUrls;
|
||||
}
|
||||
|
||||
|
||||
public String getFileViewDomain() {
|
||||
return fileViewDomain;
|
||||
}
|
||||
|
||||
public void setFileViewDomain(String fileViewDomain) {
|
||||
this.fileViewDomain = fileViewDomain;
|
||||
}
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
package org.jeecg.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 设置静态参数初始化
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Component
|
||||
@Data
|
||||
public class StaticConfig {
|
||||
|
||||
@Value("${jeecg.oss.accessKey}")
|
||||
private String accessKeyId;
|
||||
|
||||
@Value("${jeecg.oss.secretKey}")
|
||||
private String accessKeySecret;
|
||||
|
||||
@Value(value = "${spring.mail.username}")
|
||||
private String emailFrom;
|
||||
|
||||
// /**
|
||||
// * 签名密钥串
|
||||
// */
|
||||
// @Value(value = "${jeecg.signatureSecret}")
|
||||
// private String signatureSecret;
|
||||
|
||||
|
||||
/*@Bean
|
||||
public void initStatic() {
|
||||
DySmsHelper.setAccessKeyId(accessKeyId);
|
||||
DySmsHelper.setAccessKeySecret(accessKeySecret);
|
||||
EmailSendMsgHandle.setEmailFrom(emailFrom);
|
||||
}*/
|
||||
|
||||
}
|
||||
@ -1,183 +0,0 @@
|
||||
package org.jeecg.config;
|
||||
|
||||
|
||||
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
|
||||
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.ParameterBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.oas.annotations.EnableOpenApi;
|
||||
import springfox.documentation.schema.ModelRef;
|
||||
import springfox.documentation.service.*;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
|
||||
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author scott
|
||||
*/
|
||||
@Configuration
|
||||
@EnableSwagger2 //开启 Swagger2
|
||||
@EnableKnife4j //开启 knife4j,可以不写
|
||||
@Import(BeanValidatorPluginsConfiguration.class)
|
||||
public class Swagger2Config implements WebMvcConfigurer {
|
||||
|
||||
/**
|
||||
*
|
||||
* 显示swagger-ui.html文档展示页,还必须注入swagger资源:
|
||||
*
|
||||
* @param registry
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
|
||||
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
|
||||
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
|
||||
}
|
||||
|
||||
/**
|
||||
* swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等
|
||||
*
|
||||
* @return Docket
|
||||
*/
|
||||
@Bean(value = "defaultApi2")
|
||||
public Docket defaultApi2() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(apiInfo())
|
||||
.select()
|
||||
//此包路径下的类,才生成接口文档
|
||||
.apis(RequestHandlerSelectors.basePackage("org.jeecg"))
|
||||
//加了ApiOperation注解的类,才生成接口文档
|
||||
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.securitySchemes(Collections.singletonList(securityScheme()))
|
||||
.securityContexts(securityContexts())
|
||||
.globalOperationParameters(setHeaderToken());
|
||||
}
|
||||
|
||||
/***
|
||||
* oauth2配置
|
||||
* 需要增加swagger授权回调地址
|
||||
* http://localhost:8888/webjars/springfox-swagger-ui/o2c.html
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
SecurityScheme securityScheme() {
|
||||
return new ApiKey(CommonConstant.X_ACCESS_TOKEN, CommonConstant.X_ACCESS_TOKEN, "header");
|
||||
}
|
||||
/**
|
||||
* JWT token
|
||||
* @return
|
||||
*/
|
||||
private List<Parameter> setHeaderToken() {
|
||||
ParameterBuilder tokenPar = new ParameterBuilder();
|
||||
List<Parameter> pars = new ArrayList<>();
|
||||
tokenPar.name(CommonConstant.X_ACCESS_TOKEN).description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
|
||||
pars.add(tokenPar.build());
|
||||
return pars;
|
||||
}
|
||||
|
||||
/**
|
||||
* api文档的详细信息函数,注意这里的注解引用的是哪个
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
// //大标题
|
||||
.title("JeecgBoot 后台服务API接口文档")
|
||||
// 版本号
|
||||
.version("1.0")
|
||||
// .termsOfServiceUrl("NO terms of service")
|
||||
// 描述
|
||||
.description("后台API接口")
|
||||
// 作者
|
||||
.contact(new Contact("北京国炬信息技术有限公司","www.jeccg.com","jeecgos@163.com"))
|
||||
.license("The Apache License, Version 2.0")
|
||||
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增 securityContexts 保持登录状态
|
||||
*/
|
||||
private List<SecurityContext> securityContexts() {
|
||||
return new ArrayList(
|
||||
Collections.singleton(SecurityContext.builder()
|
||||
.securityReferences(defaultAuth())
|
||||
.forPaths(PathSelectors.regex("^(?!auth).*$"))
|
||||
.build())
|
||||
);
|
||||
}
|
||||
|
||||
private List<SecurityReference> defaultAuth() {
|
||||
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
|
||||
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
||||
authorizationScopes[0] = authorizationScope;
|
||||
return new ArrayList(
|
||||
Collections.singleton(new SecurityReference(CommonConstant.X_ACCESS_TOKEN, authorizationScopes)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解决springboot2.6 和springfox不兼容问题
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
|
||||
return new BeanPostProcessor() {
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
|
||||
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
|
||||
List<T> copy = mappings.stream()
|
||||
.filter(mapping -> mapping.getPatternParser() == null)
|
||||
.collect(Collectors.toList());
|
||||
mappings.clear();
|
||||
mappings.addAll(copy);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
|
||||
try {
|
||||
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
|
||||
field.setAccessible(true);
|
||||
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,156 +0,0 @@
|
||||
package org.jeecg.config;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||
import io.micrometer.prometheus.PrometheusMeterRegistry;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
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.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Spring Boot 2.0 解决跨域问题
|
||||
*
|
||||
* @Author qinfeng
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||
|
||||
@Resource
|
||||
JeecgBaseConfig jeecgBaseConfig;
|
||||
@Value("${spring.resource.static-locations:}")
|
||||
private String staticLocations;
|
||||
|
||||
@Autowired(required = false)
|
||||
private PrometheusMeterRegistry prometheusMeterRegistry;
|
||||
|
||||
/**
|
||||
* 静态资源的配置 - 使得可以从磁盘中读取 Html、图片、视频、音频等
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/**")
|
||||
//update-begin-author:taoyan date:20211116 for: jeecg.path.webapp配置无效 #3126
|
||||
.addResourceLocations("file:" + jeecgBaseConfig.getPath().getUpload() + "//")
|
||||
.addResourceLocations("file:" + jeecgBaseConfig.getPath().getWebapp() + "//")
|
||||
//update-end-author:taoyan date:20211116 for: jeecg.path.webapp配置无效 #3126
|
||||
.addResourceLocations(staticLocations.split(","));
|
||||
}
|
||||
|
||||
/**
|
||||
* 方案一: 默认访问根路径跳转 doc.html页面 (swagger文档页面)
|
||||
* 方案二: 访问根路径改成跳转 index.html页面 (简化部署方案: 可以把前端打包直接放到项目的 webapp,上面的配置)
|
||||
*/
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/").setViewName("doc.html");
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Conditional(CorsFilterCondition.class)
|
||||
public CorsFilter corsFilter() {
|
||||
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
|
||||
final CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
//是否允许请求带有验证信息
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
// 允许访问的客户端域名
|
||||
corsConfiguration.addAllowedOriginPattern("*");
|
||||
// 允许服务端访问的客户端请求头
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
// 允许访问的方法名,GET POST等
|
||||
corsConfiguration.addAllowedMethod("*");
|
||||
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
|
||||
return new CorsFilter(urlBasedCorsConfigurationSource);
|
||||
}
|
||||
@Override
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(objectMapper());
|
||||
converters.add(jackson2HttpMessageConverter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义ObjectMapper
|
||||
*/
|
||||
@Bean
|
||||
@Primary
|
||||
public ObjectMapper objectMapper() {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
//处理bigDecimal
|
||||
objectMapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
|
||||
objectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
|
||||
//处理失败
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES, false);
|
||||
//默认的处理日期时间格式
|
||||
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||
objectMapper.registerModule(javaTimeModule);
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* SpringBootAdmin的Httptrace不见了
|
||||
* https://blog.csdn.net/u013810234/article/details/110097201
|
||||
*/
|
||||
@Bean
|
||||
public InMemoryHttpTraceRepository getInMemoryHttpTrace(){
|
||||
return new InMemoryHttpTraceRepository();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解决metrics端点不显示jvm信息的问题(zyf)
|
||||
*/
|
||||
@Bean
|
||||
InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor) {
|
||||
return () -> meterRegistryPostProcessor.postProcessAfterInitialization(prometheusMeterRegistry, "");
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 注册拦截器【拦截器拦截参数,自动切换数据源——后期实现多租户切换数据源功能】
|
||||
// * @param registry
|
||||
// */
|
||||
// @Override
|
||||
// public void addInterceptors(InterceptorRegistry registry) {
|
||||
// registry.addInterceptor(new DynamicDatasourceInterceptor()).addPathPatterns("/test/dynamic/**");
|
||||
// }
|
||||
|
||||
}
|
||||
@ -1,166 +0,0 @@
|
||||
package org.jeecg.config.mybatis;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.binding.MapperMethod.ParamMap;
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlCommandType;
|
||||
import org.apache.ibatis.plugin.*;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* mybatis拦截器,自动注入创建人、创建时间、修改人、修改时间
|
||||
* @Author scott
|
||||
* @Date 2019-01-19
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
|
||||
public class MybatisInterceptor implements Interceptor {
|
||||
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
|
||||
String sqlId = mappedStatement.getId();
|
||||
log.debug("------sqlId------" + sqlId);
|
||||
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
|
||||
Object parameter = invocation.getArgs()[1];
|
||||
log.debug("------sqlCommandType------" + sqlCommandType);
|
||||
|
||||
if (parameter == null) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
if (SqlCommandType.INSERT == sqlCommandType) {
|
||||
LoginUser sysUser = this.getLoginUser();
|
||||
Field[] fields = oConvertUtils.getAllFields(parameter);
|
||||
for (Field field : fields) {
|
||||
log.debug("------field.name------" + field.getName());
|
||||
try {
|
||||
if ("createBy".equals(field.getName())) {
|
||||
field.setAccessible(true);
|
||||
Object localCreateBy = field.get(parameter);
|
||||
field.setAccessible(false);
|
||||
if (localCreateBy == null || "".equals(localCreateBy)) {
|
||||
if (sysUser != null) {
|
||||
// 登录人账号
|
||||
field.setAccessible(true);
|
||||
field.set(parameter, sysUser.getUsername());
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 注入创建时间
|
||||
if ("createTime".equals(field.getName())) {
|
||||
field.setAccessible(true);
|
||||
Object localCreateDate = field.get(parameter);
|
||||
field.setAccessible(false);
|
||||
if (localCreateDate == null || "".equals(localCreateDate)) {
|
||||
field.setAccessible(true);
|
||||
field.set(parameter, new Date());
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
//注入部门编码
|
||||
if ("sysOrgCode".equals(field.getName())) {
|
||||
field.setAccessible(true);
|
||||
Object localSysOrgCode = field.get(parameter);
|
||||
field.setAccessible(false);
|
||||
if (localSysOrgCode == null || "".equals(localSysOrgCode)) {
|
||||
// 获取登录用户信息
|
||||
if (sysUser != null) {
|
||||
field.setAccessible(true);
|
||||
field.set(parameter, sysUser.getOrgCode());
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SqlCommandType.UPDATE == sqlCommandType) {
|
||||
LoginUser sysUser = this.getLoginUser();
|
||||
Field[] fields = null;
|
||||
if (parameter instanceof ParamMap) {
|
||||
ParamMap<?> p = (ParamMap<?>) parameter;
|
||||
//update-begin-author:scott date:20190729 for:批量更新报错issues/IZA3Q--
|
||||
String et = "et";
|
||||
if (p.containsKey(et)) {
|
||||
parameter = p.get(et);
|
||||
} else {
|
||||
parameter = p.get("param1");
|
||||
}
|
||||
//update-end-author:scott date:20190729 for:批量更新报错issues/IZA3Q-
|
||||
|
||||
//update-begin-author:scott date:20190729 for:更新指定字段时报错 issues/#516-
|
||||
if (parameter == null) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
//update-end-author:scott date:20190729 for:更新指定字段时报错 issues/#516-
|
||||
|
||||
fields = oConvertUtils.getAllFields(parameter);
|
||||
} else {
|
||||
fields = oConvertUtils.getAllFields(parameter);
|
||||
}
|
||||
|
||||
for (Field field : fields) {
|
||||
log.debug("------field.name------" + field.getName());
|
||||
try {
|
||||
if ("updateBy".equals(field.getName())) {
|
||||
//获取登录用户信息
|
||||
if (sysUser != null) {
|
||||
// 登录账号
|
||||
field.setAccessible(true);
|
||||
field.set(parameter, sysUser.getUsername());
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
if ("updateTime".equals(field.getName())) {
|
||||
field.setAccessible(true);
|
||||
field.set(parameter, new Date());
|
||||
field.setAccessible(false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
return Plugin.wrap(target, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
//update-begin--Author:scott Date:20191213 for:关于使用Quzrtz 开启线程任务, #465
|
||||
/**
|
||||
* 获取登录用户
|
||||
* @return
|
||||
*/
|
||||
private LoginUser getLoginUser() {
|
||||
LoginUser sysUser = null;
|
||||
try {
|
||||
sysUser = SecurityUtils.getSubject().getPrincipal() != null ? (LoginUser) SecurityUtils.getSubject().getPrincipal() : null;
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
sysUser = null;
|
||||
}
|
||||
return sysUser;
|
||||
}
|
||||
//update-end--Author:scott Date:20191213 for:关于使用Quzrtz 开启线程任务, #465
|
||||
|
||||
}
|
||||
@ -1,123 +0,0 @@
|
||||
package org.jeecg.config.mybatis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
|
||||
/**
|
||||
* 单数据源配置(jeecg.datasource.open = false时生效)
|
||||
* @Author zhoujf
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@MapperScan(value={"org.jeecg.modules.**.mapper*"})
|
||||
public class MybatisPlusSaasConfig {
|
||||
/**
|
||||
* tenant_id 字段名
|
||||
*/
|
||||
private static final String TENANT_FIELD_NAME = "tenant_id";
|
||||
/**
|
||||
* 哪些表需要做多租户 表需要添加一个字段 tenant_id
|
||||
*/
|
||||
private static final List<String> TENANT_TABLE = new ArrayList<String>();
|
||||
|
||||
static {
|
||||
TENANT_TABLE.add("demo");
|
||||
|
||||
// //角色、菜单、部门
|
||||
// tenantTable.add("sys_role");
|
||||
// tenantTable.add("sys_permission");
|
||||
// tenantTable.add("sys_depart");
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
// 先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
|
||||
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
|
||||
@Override
|
||||
public Expression getTenantId() {
|
||||
String tenantId = oConvertUtils.getString(TenantContext.getTenant(),"0");
|
||||
return new LongValue(tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTenantIdColumn(){
|
||||
return TENANT_FIELD_NAME;
|
||||
}
|
||||
|
||||
// 返回 true 表示不走租户逻辑
|
||||
@Override
|
||||
public boolean ignoreTable(String tableName) {
|
||||
for(String temp: TENANT_TABLE){
|
||||
if(temp.equalsIgnoreCase(tableName)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
|
||||
//update-begin-author:zyf date:20220425 for:【VUEN-606】注入动态表名适配拦截器解决多表名问题
|
||||
interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor());
|
||||
//update-end-author:zyf date:20220425 for:【VUEN-606】注入动态表名适配拦截器解决多表名问题
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态表名切换拦截器,用于适配vue2和vue3同一个表有多个的情况,如sys_role_index在vue3情况下表名为sys_role_index_v3
|
||||
* @return
|
||||
*/
|
||||
private DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor() {
|
||||
DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
|
||||
dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
|
||||
//获取需要动态解析的表名
|
||||
String dynamicTableName = ThreadLocalDataHelper.get(CommonConstant.DYNAMIC_TABLE_NAME);
|
||||
//当dynamicTableName不为空时才走动态表名处理逻辑,否则返回原始表名
|
||||
if (ObjectUtil.isNotEmpty(dynamicTableName) && dynamicTableName.equals(tableName)) {
|
||||
// 获取前端传递的版本号标识
|
||||
Object version = ThreadLocalDataHelper.get(CommonConstant.VERSION);
|
||||
if (ObjectUtil.isNotEmpty(version)) {
|
||||
//拼接表名规则(原始表名+下划线+前端传递的版本号)
|
||||
return tableName + "_" + version;
|
||||
}
|
||||
}
|
||||
return tableName;
|
||||
});
|
||||
return dynamicTableNameInnerInterceptor;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 下个版本会删除,现在为了避免缓存出现问题不得不配置
|
||||
// * @return
|
||||
// */
|
||||
// @Bean
|
||||
// public ConfigurationCustomizer configurationCustomizer() {
|
||||
// return configuration -> configuration.setUseDeprecatedExecutor(false);
|
||||
// }
|
||||
// /**
|
||||
// * mybatis-plus SQL执行效率插件【生产环境可以关闭】
|
||||
// */
|
||||
// @Bean
|
||||
// public PerformanceInterceptor performanceInterceptor() {
|
||||
// return new PerformanceInterceptor();
|
||||
// }
|
||||
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
package org.jeecg.config.shiro;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
|
||||
/**
|
||||
* @Author Scott
|
||||
* @create 2018-07-12 15:19
|
||||
* @desc
|
||||
**/
|
||||
public class JwtToken implements AuthenticationToken {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String token;
|
||||
|
||||
public JwtToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@ -1,279 +0,0 @@
|
||||
package org.jeecg.config.shiro;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
||||
import org.apache.shiro.mgt.DefaultSubjectDAO;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.crazycake.shiro.IRedisManager;
|
||||
import org.crazycake.shiro.RedisCacheManager;
|
||||
import org.crazycake.shiro.RedisClusterManager;
|
||||
import org.crazycake.shiro.RedisManager;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.config.shiro.filters.CustomShiroFilterFactoryBean;
|
||||
import org.jeecg.config.shiro.filters.JwtFilter;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.Filter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author: Scott
|
||||
* @date: 2018/2/7
|
||||
* @description: shiro 配置类
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class ShiroConfig {
|
||||
|
||||
@Resource
|
||||
private LettuceConnectionFactory lettuceConnectionFactory;
|
||||
@Autowired
|
||||
private Environment env;
|
||||
@Resource
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
/**
|
||||
* Filter Chain定义说明
|
||||
*
|
||||
* 1、一个URL可以配置多个Filter,使用逗号分隔
|
||||
* 2、当设置多个过滤器时,全部验证通过,才视为通过
|
||||
* 3、部分过滤器可指定参数,如perms,roles
|
||||
*/
|
||||
@Bean("shiroFilterFactoryBean")
|
||||
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
|
||||
CustomShiroFilterFactoryBean shiroFilterFactoryBean = new CustomShiroFilterFactoryBean();
|
||||
shiroFilterFactoryBean.setSecurityManager(securityManager);
|
||||
// 拦截器
|
||||
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
|
||||
|
||||
//支持yml方式,配置拦截排除
|
||||
if(jeecgBaseConfig!=null && jeecgBaseConfig.getShiro()!=null){
|
||||
String shiroExcludeUrls = jeecgBaseConfig.getShiro().getExcludeUrls();
|
||||
if(oConvertUtils.isNotEmpty(shiroExcludeUrls)){
|
||||
String[] permissionUrl = shiroExcludeUrls.split(",");
|
||||
for(String url : permissionUrl){
|
||||
filterChainDefinitionMap.put(url,"anon");
|
||||
}
|
||||
}
|
||||
}
|
||||
// 配置不会被拦截的链接 顺序判断
|
||||
filterChainDefinitionMap.put("/sys/cas/client/validateLogin", "anon"); //cas验证登录
|
||||
filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除
|
||||
filterChainDefinitionMap.put("/sys/checkCaptcha", "anon"); //登录验证码接口排除
|
||||
filterChainDefinitionMap.put("/sys/login", "anon"); //登录接口排除
|
||||
filterChainDefinitionMap.put("/sys/mLogin", "anon"); //登录接口排除
|
||||
filterChainDefinitionMap.put("/sys/logout", "anon"); //登出接口排除
|
||||
filterChainDefinitionMap.put("/sys/thirdLogin/**", "anon"); //第三方登录
|
||||
filterChainDefinitionMap.put("/sys/getEncryptedString", "anon"); //获取加密串
|
||||
filterChainDefinitionMap.put("/sys/sms", "anon");//短信验证码
|
||||
filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//手机登录
|
||||
filterChainDefinitionMap.put("/sys/user/checkOnlyUser", "anon");//校验用户是否存在
|
||||
filterChainDefinitionMap.put("/sys/user/register", "anon");//用户注册
|
||||
filterChainDefinitionMap.put("/sys/user/phoneVerification", "anon");//用户忘记密码验证手机号
|
||||
filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//用户更改密码
|
||||
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
|
||||
filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token
|
||||
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
|
||||
filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要文件
|
||||
|
||||
filterChainDefinitionMap.put("/sys/getLoginQrcode/**", "anon"); //登录二维码
|
||||
filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码
|
||||
filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除
|
||||
|
||||
|
||||
filterChainDefinitionMap.put("/", "anon");
|
||||
filterChainDefinitionMap.put("/doc.html", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.js", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.css", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.html", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.svg", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.pdf", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.jpg", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.png", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.gif", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.ico", "anon");
|
||||
|
||||
// update-begin--Author:sunjianlei Date:20190813 for:排除字体格式的后缀
|
||||
filterChainDefinitionMap.put("/**/*.ttf", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.woff", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.woff2", "anon");
|
||||
// update-begin--Author:sunjianlei Date:20190813 for:排除字体格式的后缀
|
||||
|
||||
filterChainDefinitionMap.put("/druid/**", "anon");
|
||||
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
|
||||
filterChainDefinitionMap.put("/swagger**/**", "anon");
|
||||
filterChainDefinitionMap.put("/webjars/**", "anon");
|
||||
filterChainDefinitionMap.put("/v2/**", "anon");
|
||||
|
||||
filterChainDefinitionMap.put("/sys/annountCement/show/**", "anon");
|
||||
|
||||
//积木报表排除
|
||||
filterChainDefinitionMap.put("/jmreport/**", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.js.map", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.css.map", "anon");
|
||||
|
||||
//大屏模板例子
|
||||
filterChainDefinitionMap.put("/test/bigScreen/**", "anon");
|
||||
filterChainDefinitionMap.put("/bigscreen/template1/**", "anon");
|
||||
filterChainDefinitionMap.put("/bigscreen/template1/**", "anon");
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/rabbitMqClientTest/**", "anon"); //MQ测试
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/html", "anon"); //模板页面
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/redis/**", "anon"); //redis测试
|
||||
|
||||
//websocket排除
|
||||
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
|
||||
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
|
||||
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
|
||||
|
||||
|
||||
//性能监控,放开排除会存在安全漏洞泄露TOEKN(durid连接池也有)
|
||||
//filterChainDefinitionMap.put("/actuator/**", "anon");
|
||||
|
||||
//测试模块排除
|
||||
filterChainDefinitionMap.put("/test/seata/**", "anon");
|
||||
|
||||
// 添加自己的过滤器并且取名为jwt
|
||||
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
|
||||
//如果cloudServer为空 则说明是单体 需要加载跨域配置【微服务跨域切换】
|
||||
Object cloudServer = env.getProperty(CommonConstant.CLOUD_SERVER_KEY);
|
||||
filterMap.put("jwt", new JwtFilter(cloudServer==null));
|
||||
shiroFilterFactoryBean.setFilters(filterMap);
|
||||
// <!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边
|
||||
filterChainDefinitionMap.put("/**", "jwt");
|
||||
|
||||
// 未授权界面返回JSON
|
||||
shiroFilterFactoryBean.setUnauthorizedUrl("/sys/common/403");
|
||||
shiroFilterFactoryBean.setLoginUrl("/sys/common/403");
|
||||
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
|
||||
return shiroFilterFactoryBean;
|
||||
}
|
||||
|
||||
@Bean("securityManager")
|
||||
public DefaultWebSecurityManager securityManager(ShiroRealm myRealm) {
|
||||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||
securityManager.setRealm(myRealm);
|
||||
|
||||
/*
|
||||
* 关闭shiro自带的session,详情见文档
|
||||
* http://shiro.apache.org/session-management.html#SessionManagement-
|
||||
* StatelessApplications%28Sessionless%29
|
||||
*/
|
||||
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
|
||||
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
|
||||
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
|
||||
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
|
||||
securityManager.setSubjectDAO(subjectDAO);
|
||||
//自定义缓存实现,使用redis
|
||||
securityManager.setCacheManager(redisCacheManager());
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下面的代码是添加注解支持
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@DependsOn("lifecycleBeanPostProcessor")
|
||||
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
|
||||
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
|
||||
/**
|
||||
* 解决重复代理问题 github#994
|
||||
* 添加前缀判断 不匹配 任何Advisor
|
||||
*/
|
||||
defaultAdvisorAutoProxyCreator.setUsePrefix(true);
|
||||
defaultAdvisorAutoProxyCreator.setAdvisorBeanNamePrefix("_no_advisor");
|
||||
return defaultAdvisorAutoProxyCreator;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
||||
return new LifecycleBeanPostProcessor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
|
||||
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
||||
advisor.setSecurityManager(securityManager);
|
||||
return advisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* cacheManager 缓存 redis实现
|
||||
* 使用的是shiro-redis开源插件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public RedisCacheManager redisCacheManager() {
|
||||
log.info("===============(1)创建缓存管理器RedisCacheManager");
|
||||
RedisCacheManager redisCacheManager = new RedisCacheManager();
|
||||
redisCacheManager.setRedisManager(redisManager());
|
||||
//redis中针对不同用户缓存(此处的id需要对应user实体中的id字段,用于唯一标识)
|
||||
redisCacheManager.setPrincipalIdFieldName("id");
|
||||
//用户权限信息缓存时间
|
||||
redisCacheManager.setExpire(200000);
|
||||
return redisCacheManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置shiro redisManager
|
||||
* 使用的是shiro-redis开源插件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public IRedisManager redisManager() {
|
||||
log.info("===============(2)创建RedisManager,连接Redis..");
|
||||
IRedisManager manager;
|
||||
// redis 单机支持,在集群为空,或者集群无机器时候使用 add by jzyadmin@163.com
|
||||
if (lettuceConnectionFactory.getClusterConfiguration() == null || lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().isEmpty()) {
|
||||
RedisManager redisManager = new RedisManager();
|
||||
redisManager.setHost(lettuceConnectionFactory.getHostName());
|
||||
redisManager.setPort(lettuceConnectionFactory.getPort());
|
||||
redisManager.setDatabase(lettuceConnectionFactory.getDatabase());
|
||||
redisManager.setTimeout(0);
|
||||
if (!StringUtils.isEmpty(lettuceConnectionFactory.getPassword())) {
|
||||
redisManager.setPassword(lettuceConnectionFactory.getPassword());
|
||||
}
|
||||
manager = redisManager;
|
||||
}else{
|
||||
// redis集群支持,优先使用集群配置
|
||||
RedisClusterManager redisManager = new RedisClusterManager();
|
||||
Set<HostAndPort> portSet = new HashSet<>();
|
||||
lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
|
||||
//update-begin--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
|
||||
if (oConvertUtils.isNotEmpty(lettuceConnectionFactory.getPassword())) {
|
||||
JedisCluster jedisCluster = new JedisCluster(portSet, 2000, 2000, 5,
|
||||
lettuceConnectionFactory.getPassword(), new GenericObjectPoolConfig());
|
||||
redisManager.setPassword(lettuceConnectionFactory.getPassword());
|
||||
redisManager.setJedisCluster(jedisCluster);
|
||||
} else {
|
||||
JedisCluster jedisCluster = new JedisCluster(portSet);
|
||||
redisManager.setJedisCluster(jedisCluster);
|
||||
}
|
||||
//update-end--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
|
||||
manager = redisManager;
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,205 +0,0 @@
|
||||
package org.jeecg.config.shiro;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||
import org.apache.shiro.realm.AuthorizingRealm;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.jeecg.common.api.CommonAPI;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Description: 用户登录鉴权和获取用户授权
|
||||
* @Author: Scott
|
||||
* @Date: 2019-4-23 8:13
|
||||
* @Version: 1.1
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ShiroRealm extends AuthorizingRealm {
|
||||
@Lazy
|
||||
@Resource
|
||||
private CommonAPI commonApi;
|
||||
|
||||
@Lazy
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
/**
|
||||
* 必须重写此方法,不然Shiro会报错
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(AuthenticationToken token) {
|
||||
return token instanceof JwtToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限信息认证(包括角色以及权限)是用户访问controller的时候才进行验证(redis存储的此处权限信息)
|
||||
* 触发检测用户权限时才会调用此方法,例如checkRole,checkPermission
|
||||
*
|
||||
* @param principals 身份信息
|
||||
* @return AuthorizationInfo 权限信息
|
||||
*/
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||
log.debug("===============Shiro权限认证开始============ [ roles、permissions]==========");
|
||||
String username = null;
|
||||
if (principals != null) {
|
||||
LoginUser sysUser = (LoginUser) principals.getPrimaryPrincipal();
|
||||
username = sysUser.getUsername();
|
||||
}
|
||||
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
||||
|
||||
// 设置用户拥有的角色集合,比如“admin,test”
|
||||
Set<String> roleSet = commonApi.queryUserRoles(username);
|
||||
//System.out.println(roleSet.toString());
|
||||
info.setRoles(roleSet);
|
||||
|
||||
// 设置用户拥有的权限集合,比如“sys:role:add,sys:user:add”
|
||||
Set<String> permissionSet = commonApi.queryUserAuths(username);
|
||||
info.addStringPermissions(permissionSet);
|
||||
//System.out.println(permissionSet);
|
||||
log.info("===============Shiro权限认证成功==============");
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户信息认证是在用户进行登录的时候进行验证(不存redis)
|
||||
* 也就是说验证用户输入的账号和密码是否正确,错误抛出异常
|
||||
*
|
||||
* @param auth 用户登录的账号密码信息
|
||||
* @return 返回封装了用户信息的 AuthenticationInfo 实例
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
@Override
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
|
||||
log.debug("===============Shiro身份认证开始============doGetAuthenticationInfo==========");
|
||||
String token = (String) auth.getCredentials();
|
||||
if (token == null) {
|
||||
HttpServletRequest req = SpringContextUtils.getHttpServletRequest();
|
||||
log.info("————————身份认证失败——————————IP地址: "+ oConvertUtils.getIpAddrByRequest(req) +",URL:"+req.getRequestURI());
|
||||
throw new AuthenticationException("token为空!");
|
||||
}
|
||||
// 校验token有效性
|
||||
LoginUser loginUser = null;
|
||||
try {
|
||||
loginUser = this.checkUserTokenIsEffect(token);
|
||||
} catch (AuthenticationException e) {
|
||||
JwtUtil.responseError(SpringContextUtils.getHttpServletResponse(),401,e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return new SimpleAuthenticationInfo(loginUser, token, getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验token的有效性
|
||||
*
|
||||
* @param token
|
||||
*/
|
||||
public LoginUser checkUserTokenIsEffect(String token) throws AuthenticationException {
|
||||
// 解密获得username,用于和数据库进行对比
|
||||
String username = JwtUtil.getUsername(token);
|
||||
if (username == null) {
|
||||
throw new AuthenticationException("token非法无效!");
|
||||
}
|
||||
|
||||
// 查询用户信息
|
||||
log.debug("———校验token是否有效————checkUserTokenIsEffect——————— "+ token);
|
||||
LoginUser loginUser = TokenUtils.getLoginUser(username, commonApi, redisUtil);
|
||||
//LoginUser loginUser = commonApi.getUserByName(username);
|
||||
if (loginUser == null) {
|
||||
throw new AuthenticationException("用户不存在!");
|
||||
}
|
||||
// 判断用户状态
|
||||
if (loginUser.getStatus() != 1) {
|
||||
throw new AuthenticationException("账号已被锁定,请联系管理员!");
|
||||
}
|
||||
// 校验token是否超时失效 & 或者账号密码是否错误
|
||||
if (!jwtTokenRefresh(token, username, loginUser.getPassword())) {
|
||||
throw new AuthenticationException(CommonConstant.TOKEN_IS_INVALID_MSG);
|
||||
}
|
||||
//update-begin-author:taoyan date:20210609 for:校验用户的tenant_id和前端传过来的是否一致
|
||||
String userTenantIds = loginUser.getRelTenantIds();
|
||||
if(oConvertUtils.isNotEmpty(userTenantIds)){
|
||||
String contextTenantId = TenantContext.getTenant();
|
||||
String str ="0";
|
||||
if(oConvertUtils.isNotEmpty(contextTenantId) && !str.equals(contextTenantId)){
|
||||
//update-begin-author:taoyan date:20211227 for: /issues/I4O14W 用户租户信息变更判断漏洞
|
||||
String[] arr = userTenantIds.split(",");
|
||||
if(!oConvertUtils.isIn(contextTenantId, arr)){
|
||||
throw new AuthenticationException("用户租户信息变更,请重新登陆!");
|
||||
}
|
||||
//update-end-author:taoyan date:20211227 for: /issues/I4O14W 用户租户信息变更判断漏洞
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:20210609 for:校验用户的tenant_id和前端传过来的是否一致
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* JWTToken刷新生命周期 (实现: 用户在线操作不掉线功能)
|
||||
* 1、登录成功后将用户的JWT生成的Token作为k、v存储到cache缓存里面(这时候k、v值一样),缓存有效期设置为Jwt有效时间的2倍
|
||||
* 2、当该用户再次请求时,通过JWTFilter层层校验之后会进入到doGetAuthenticationInfo进行身份验证
|
||||
* 3、当该用户这次请求jwt生成的token值已经超时,但该token对应cache中的k还是存在,则表示该用户一直在操作只是JWT的token失效了,程序会给token对应的k映射的v值重新生成JWTToken并覆盖v值,该缓存生命周期重新计算
|
||||
* 4、当该用户这次请求jwt在生成的token值已经超时,并在cache中不存在对应的k,则表示该用户账户空闲超时,返回用户信息已失效,请重新登录。
|
||||
* 注意: 前端请求Header中设置Authorization保持不变,校验有效性以缓存中的token为准。
|
||||
* 用户过期时间 = Jwt有效时间 * 2。
|
||||
*
|
||||
* @param userName
|
||||
* @param passWord
|
||||
* @return
|
||||
*/
|
||||
public boolean jwtTokenRefresh(String token, String userName, String passWord) {
|
||||
String cacheToken = String.valueOf(redisUtil.get(CommonConstant.PREFIX_USER_TOKEN + token));
|
||||
if (oConvertUtils.isNotEmpty(cacheToken)) {
|
||||
// 校验token有效性
|
||||
if (!JwtUtil.verify(cacheToken, userName, passWord)) {
|
||||
String newAuthorization = JwtUtil.sign(userName, passWord);
|
||||
// 设置超时时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, newAuthorization);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME *2 / 1000);
|
||||
log.debug("——————————用户在线操作,更新token保证不掉线—————————jwtTokenRefresh——————— "+ token);
|
||||
}
|
||||
//update-begin--Author:scott Date:20191005 for:解决每次请求,都重写redis中 token缓存问题
|
||||
// else {
|
||||
// // 设置超时时间
|
||||
// redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, cacheToken);
|
||||
// redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);
|
||||
// }
|
||||
//update-end--Author:scott Date:20191005 for:解决每次请求,都重写redis中 token缓存问题
|
||||
return true;
|
||||
}
|
||||
|
||||
//redis中不存在此TOEKN,说明token非法返回false
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除当前用户的权限认证缓存
|
||||
*
|
||||
* @param principals 权限信息
|
||||
*/
|
||||
@Override
|
||||
public void clearCache(PrincipalCollection principals) {
|
||||
super.clearCache(principals);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,77 +0,0 @@
|
||||
package org.jeecg.config.shiro.filters;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.web.filter.InvalidRequestFilter;
|
||||
import org.apache.shiro.web.filter.mgt.DefaultFilter;
|
||||
import org.apache.shiro.web.filter.mgt.FilterChainManager;
|
||||
import org.apache.shiro.web.filter.mgt.FilterChainResolver;
|
||||
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
|
||||
import org.apache.shiro.web.mgt.WebSecurityManager;
|
||||
import org.apache.shiro.web.servlet.AbstractShiroFilter;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 自定义ShiroFilterFactoryBean解决资源中文路径问题
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
public class CustomShiroFilterFactoryBean extends ShiroFilterFactoryBean {
|
||||
@Override
|
||||
public Class getObjectType() {
|
||||
return MySpringShiroFilter.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractShiroFilter createInstance() throws Exception {
|
||||
|
||||
SecurityManager securityManager = getSecurityManager();
|
||||
if (securityManager == null) {
|
||||
String msg = "SecurityManager property must be set.";
|
||||
throw new BeanInitializationException(msg);
|
||||
}
|
||||
|
||||
if (!(securityManager instanceof WebSecurityManager)) {
|
||||
String msg = "The security manager does not implement the WebSecurityManager interface.";
|
||||
throw new BeanInitializationException(msg);
|
||||
}
|
||||
|
||||
FilterChainManager manager = createFilterChainManager();
|
||||
//Expose the constructed FilterChainManager by first wrapping it in a
|
||||
// FilterChainResolver implementation. The AbstractShiroFilter implementations
|
||||
// do not know about FilterChainManagers - only resolvers:
|
||||
PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
|
||||
chainResolver.setFilterChainManager(manager);
|
||||
|
||||
Map<String, Filter> filterMap = manager.getFilters();
|
||||
Filter invalidRequestFilter = filterMap.get(DefaultFilter.invalidRequest.name());
|
||||
if (invalidRequestFilter instanceof InvalidRequestFilter) {
|
||||
//此处是关键,设置false跳过URL携带中文400,servletPath中文校验bug
|
||||
((InvalidRequestFilter) invalidRequestFilter).setBlockNonAscii(false);
|
||||
}
|
||||
//Now create a concrete ShiroFilter instance and apply the acquired SecurityManager and built
|
||||
//FilterChainResolver. It doesn't matter that the instance is an anonymous inner class
|
||||
//here - we're just using it because it is a concrete AbstractShiroFilter instance that accepts
|
||||
//injection of the SecurityManager and FilterChainResolver:
|
||||
return new MySpringShiroFilter((WebSecurityManager) securityManager, chainResolver);
|
||||
}
|
||||
|
||||
private static final class MySpringShiroFilter extends AbstractShiroFilter {
|
||||
protected MySpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
|
||||
if (webSecurityManager == null) {
|
||||
throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
|
||||
} else {
|
||||
this.setSecurityManager(webSecurityManager);
|
||||
if (resolver != null) {
|
||||
this.setFilterChainResolver(resolver);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,124 +0,0 @@
|
||||
package org.jeecg.config.shiro.filters;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.shiro.JwtToken;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @Description: 鉴权登录拦截器
|
||||
* @Author: Scott
|
||||
* @Date: 2018/10/7
|
||||
**/
|
||||
@Slf4j
|
||||
public class JwtFilter extends BasicHttpAuthenticationFilter {
|
||||
|
||||
/**
|
||||
* 默认开启跨域设置(使用单体)
|
||||
* 微服务情况下,此属性设置为false
|
||||
*/
|
||||
private boolean allowOrigin = true;
|
||||
|
||||
public JwtFilter(){}
|
||||
public JwtFilter(boolean allowOrigin){
|
||||
this.allowOrigin = allowOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行登录认证
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param mappedValue
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
|
||||
try {
|
||||
executeLogin(request, response);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
JwtUtil.responseError(response,401,CommonConstant.TOKEN_IS_INVALID_MSG);
|
||||
return false;
|
||||
//throw new AuthenticationException("Token失效,请重新登录", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
String token = httpServletRequest.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
// update-begin--Author:lvdandan Date:20210105 for:JT-355 OA聊天添加token验证,获取token参数
|
||||
if (oConvertUtils.isEmpty(token)) {
|
||||
token = httpServletRequest.getParameter("token");
|
||||
}
|
||||
// update-end--Author:lvdandan Date:20210105 for:JT-355 OA聊天添加token验证,获取token参数
|
||||
|
||||
JwtToken jwtToken = new JwtToken(token);
|
||||
// 提交给realm进行登入,如果错误他会抛出异常并被捕获
|
||||
getSubject(request, response).login(jwtToken);
|
||||
// 如果没有抛出异常则代表登入成功,返回true
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对跨域提供支持
|
||||
*/
|
||||
@Override
|
||||
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
if(allowOrigin){
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, httpServletRequest.getHeader(HttpHeaders.ORIGIN));
|
||||
// 允许客户端请求方法
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,OPTIONS,PUT,DELETE");
|
||||
// 允许客户端提交的Header
|
||||
String requestHeaders = httpServletRequest.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
|
||||
if (StringUtils.isNotEmpty(requestHeaders)) {
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders);
|
||||
}
|
||||
// 允许客户端携带凭证信息(是否允许发送Cookie)
|
||||
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
|
||||
}
|
||||
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
|
||||
if (RequestMethod.OPTIONS.name().equalsIgnoreCase(httpServletRequest.getMethod())) {
|
||||
httpServletResponse.setStatus(HttpStatus.OK.value());
|
||||
return false;
|
||||
}
|
||||
//update-begin-author:taoyan date:20200708 for:多租户用到
|
||||
String tenantId = httpServletRequest.getHeader(CommonConstant.TENANT_ID);
|
||||
TenantContext.setTenant(tenantId);
|
||||
//update-end-author:taoyan date:20200708 for:多租户用到
|
||||
|
||||
return super.preHandle(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* JwtFilter中ThreadLocal需要及时清除 #3634
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param exception
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(ServletRequest request, ServletResponse response, Exception exception) throws Exception {
|
||||
//log.info("------清空线程中多租户的ID={}------",TenantContext.getTenant());
|
||||
TenantContext.clear();
|
||||
}
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
package org.jeecg.config.shiro.filters;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.web.filter.AccessControlFilter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @Author Scott
|
||||
* @create 2019-02-01 15:56
|
||||
* @desc 鉴权请求URL访问权限拦截器
|
||||
*/
|
||||
@Slf4j
|
||||
public class ResourceCheckFilter extends AccessControlFilter {
|
||||
|
||||
private String errorUrl;
|
||||
|
||||
public String getErrorUrl() {
|
||||
return errorUrl;
|
||||
}
|
||||
|
||||
public void setErrorUrl(String errorUrl) {
|
||||
this.errorUrl = errorUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表示是否允许访问 ,如果允许访问返回true,否则false;
|
||||
*
|
||||
* @param servletRequest
|
||||
* @param servletResponse
|
||||
* @param o 表示写在拦截器中括号里面的字符串 mappedValue 就是 [urls] 配置中拦截器参数部分
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
|
||||
Subject subject = getSubject(servletRequest, servletResponse);
|
||||
String url = getPathWithinApplication(servletRequest);
|
||||
log.info("当前用户正在访问的 url => " + url);
|
||||
return subject.isPermitted(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* onAccessDenied:表示当访问拒绝时是否已经处理了; 如果返回 true 表示需要继续处理; 如果返回 false
|
||||
* 表示该拦截器实例已经处理了,将直接返回即可。
|
||||
*
|
||||
* @param servletRequest
|
||||
* @param servletResponse
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
|
||||
log.info("当 isAccessAllowed 返回 false 的时候,才会执行 method onAccessDenied ");
|
||||
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
response.sendRedirect(request.getContextPath() + this.errorUrl);
|
||||
|
||||
// 返回 false 表示已经处理,例如页面跳转啥的,表示不在走以下的拦截器了(如果还有配置的话)
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,80 +0,0 @@
|
||||
package org.jeecg.config.thirdapp;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 第三方App对接配置
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Configuration
|
||||
public class ThirdAppConfig {
|
||||
|
||||
/**
|
||||
* 钉钉
|
||||
*/
|
||||
public final static String DINGTALK = "DINGTALK";
|
||||
/**
|
||||
* 企业微信
|
||||
*/
|
||||
public final static String WECHAT_ENTERPRISE = "WECHAT_ENTERPRISE";
|
||||
|
||||
/**
|
||||
* 是否启用 第三方App对接
|
||||
*/
|
||||
@Value("${third-app.enabled:false}")
|
||||
private boolean enabled;
|
||||
|
||||
/**
|
||||
* 系统类型,目前支持:WECHAT_ENTERPRISE(企业微信);DINGTALK (钉钉)
|
||||
*/
|
||||
@Autowired
|
||||
private ThirdAppTypeConfig type;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public ThirdAppConfig setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业微信配置
|
||||
*/
|
||||
public ThirdAppTypeItemVo getWechatEnterprise() {
|
||||
return this.type.getWECHAT_ENTERPRISE();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取钉钉配置
|
||||
*/
|
||||
public ThirdAppTypeItemVo getDingtalk() {
|
||||
return this.type.getDINGTALK();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业微信是否启用
|
||||
*/
|
||||
public boolean isWechatEnterpriseEnabled() {
|
||||
try {
|
||||
return this.enabled && this.getWechatEnterprise().isEnabled();
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取钉钉是否启用
|
||||
*/
|
||||
public boolean isDingtalkEnabled() {
|
||||
try {
|
||||
return this.enabled && this.getDingtalk().isEnabled();
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
package org.jeecg.config.thirdapp;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 第三方APP配置
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "third-app.type")
|
||||
public class ThirdAppTypeConfig {
|
||||
|
||||
/**
|
||||
* 对应企业微信配置
|
||||
*/
|
||||
private ThirdAppTypeItemVo WECHAT_ENTERPRISE;
|
||||
/**
|
||||
* 对应钉钉配置
|
||||
*/
|
||||
private ThirdAppTypeItemVo DINGTALK;
|
||||
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package org.jeecg.config.thirdapp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 第三方App对接
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Data
|
||||
public class ThirdAppTypeItemVo {
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private boolean enabled;
|
||||
/**
|
||||
* 应用Key
|
||||
*/
|
||||
private String clientId;
|
||||
/**
|
||||
* 应用Secret
|
||||
*/
|
||||
private String clientSecret;
|
||||
/**
|
||||
* 应用ID
|
||||
*/
|
||||
private String agentId;
|
||||
/**
|
||||
* 目前仅企业微信用到:自建应用Secret
|
||||
*/
|
||||
private String agentAppSecret;
|
||||
|
||||
public int getAgentIdInt() {
|
||||
return Integer.parseInt(agentId);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
package org.jeecg.config.vo;
|
||||
|
||||
/**
|
||||
* @Description: TODO
|
||||
* @author: scott
|
||||
* @date: 2022年01月21日 14:23
|
||||
*/
|
||||
public class Shiro {
|
||||
private String excludeUrls = "";
|
||||
|
||||
public String getExcludeUrls() {
|
||||
return excludeUrls;
|
||||
}
|
||||
|
||||
public void setExcludeUrls(String excludeUrls) {
|
||||
this.excludeUrls = excludeUrls;
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
16
jeecg-boot/.gitignore
vendored
Normal file
16
jeecg-boot/.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
## ide
|
||||
**/.idea
|
||||
*.iml
|
||||
rebel.xml
|
||||
|
||||
## backend
|
||||
**/target
|
||||
**/logs
|
||||
|
||||
## front
|
||||
**/*.lock
|
||||
os_del.cmd
|
||||
os_del_doc.cmd
|
||||
.svn
|
||||
derby.log
|
||||
*.log
|
||||
213
jeecg-boot/LICENSE
Normal file
213
jeecg-boot/LICENSE
Normal file
@ -0,0 +1,213 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (c) 2019 <a href="http://www.jeecg.com">Jeecg Boot</a> All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software.
|
||||
|
||||
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com
|
||||
本软件受适用的国家软件著作权法(包括国际条约)和开源协议 双重保护许可。
|
||||
|
||||
开源协议中文释意如下:
|
||||
1.JeecgBoot开源版本无任何限制,在遵循本开源协议条款下,允许商用使用,不会造成侵权行为。
|
||||
2.允许基于本平台软件开展业务系统开发。
|
||||
3.在任何情况下,您不得使用本软件开发可能被认为与本软件竞争的软件。
|
||||
|
||||
最终解释权归:http://www.jeecg.com
|
||||
254
jeecg-boot/README.md
Normal file
254
jeecg-boot/README.md
Normal file
@ -0,0 +1,254 @@
|
||||
|
||||
JeecgBoot 低代码开发平台
|
||||
===============
|
||||
|
||||
当前最新版本: 3.9.0(发布日期:2025-12-01)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://jeecg.com/aboutusIndex)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
|
||||
|
||||
项目介绍
|
||||
-----------------------------------
|
||||
|
||||
<h3 align="center">企业级AI低代码平台</h3>
|
||||
|
||||
JeecgBoot 是一款基于BPM流程和代码生成的AI低代码平台,助力企业快速实现低代码开发和构建AI应用。
|
||||
采用前后端分离架构(Ant Design&Vue3,SpringBoot3,SpringCloud Alibaba,Mybatis-plus),强大代码生成器实现前后端一键生成,无需手写代码。
|
||||
平台引领AI低代码开发模式:AI生成→在线编码→代码生成→手工合并,解决Java项目80%重复工作,提升效率,节省成本,兼顾灵活性。
|
||||
具备强大且颗粒化的权限控制,支持按钮权限和数据权限设置,满足大型业务系统需求。功能涵盖在线表单、表单设计、流程设计、门户设计、报表与大屏设计、OA办公、AI应用、AI知识库、大模型管理、AI流程编排、AI聊天,支持ChatGPT、DeepSeek、Ollama等多种AI大模型。
|
||||
|
||||
`AI赋能报表:` 积木报表是一款自主研发的强大开源企业级Web报表与大屏工具。它通过零编码的拖拽式操作,赋能用户如同搭积木般轻松构建各类复杂报表和数据大屏,全面满足企业数据可视化与分析需求,助力企业级数据产品的高效打造与应用。
|
||||
|
||||
`AI赋能低代码:` 提供完善成熟的AI应用平台,涵盖AI应用管理、AI模型管理、智能对话助手、知识库问答、流程编排与设计器、AI建表等多项功能。平台兼容多种主流大模型,包括ChatGPT、DeepSeek、Ollama、智普、千问等,助力企业高效构建智能化应用,推动低代码开发与AI深度融合。
|
||||
|
||||
`JEECG宗旨是:` JEECG旨在通过OnlineCoding平台实现简单功能的零代码快速搭建,同时针对复杂功能采用代码生成器生成代码并手工合并,打造智能且灵活的低代码开发模式,有效解决了当前低代码产品普遍缺乏灵活性的问题,提升开发效率的同时兼顾系统的扩展性和定制化能力。
|
||||
|
||||
`JEECG业务流程:` JEECG业务流程采用BPM工作流引擎实现业务审批,扩展任务接口供开发人员编写业务逻辑,表单提供表单设计器、在线配置表单和编码表单等多种解决方案。通过流程与表单的分离设计(松耦合)及任务节点的灵活配置,既保障了企业流程的安全性与保密性,又大幅降低了开发人员的工作量。
|
||||
|
||||
|
||||
适用项目
|
||||
-----------------------------------
|
||||
JeecgBoot低代码平台兼容所有J2EE项目开发,支持信创国产化,特别适用于SAAS、企业信息管理系统(MIS)、内部办公系统(OA)、企业资源计划系统(ERP)、客户关系管理系统(CRM)及AI知识库等场景。其半智能手工Merge开发模式,可显著提升70%以上的开发效率,极大降低开发成本。同时,JeecgBoot还是一款全栈式AI开发平台,助力企业快速构建和部署个性化AI应用。。
|
||||
|
||||
|
||||
**信创兼容说明**
|
||||
- 操作系统:国产麒麟、银河麒麟等国产系统几乎都是基于 Linux 内核,因此它们具有良好的兼容性。
|
||||
- 数据库:达梦、人大金仓、TiDB
|
||||
- 中间件:东方通 TongWeb、TongRDS,宝兰德 AppServer、CacheDB, [信创配置文档](https://help.jeecg.com/java/tongweb-deploy/)
|
||||
|
||||
|
||||
|
||||
|
||||
#### 项目说明
|
||||
|
||||
| 项目名 | 说明 |
|
||||
|--------------------|------------------------------------|
|
||||
| `jeecg-boot` | 后端源码JAVA(SpringBoot3微服务架构) |
|
||||
| `jeecgboot-vue3` | 前端源码VUE3(vue3+vite6+antd4+ts最新技术栈) |
|
||||
|
||||
|
||||
|
||||
启动项目
|
||||
-----------------------------------
|
||||
|
||||
> 默认账号密码: admin/123456
|
||||
|
||||
- [开发环境搭建](https://help.jeecg.com/java/setup/tools)
|
||||
- [IDEA启动前后端(单体模式)](https://help.jeecg.com/java/setup/idea/startup)
|
||||
- [Docker一键启动(单体模式)](https://help.jeecg.com/java/docker/quick)
|
||||
- [IDEA启动前后端(微服务方式)](https://help.jeecg.com/java/springcloud/switchcloud/monomer)
|
||||
- [Docker一键启动(微服务方式)](https://help.jeecg.com/java/docker/quickcloud)
|
||||
|
||||
|
||||
技术文档
|
||||
-----------------------------------
|
||||
|
||||
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
- 在线演示: [平台演示](https://boot3.jeecg.com) | [APP演示](https://jeecg.com/appIndex)
|
||||
- 入门指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [代码生成使用](https://help.jeecg.com/java/codegen/online) | [开发文档](https://help.jeecg.com) | [AI应用手册](https://help.jeecg.com/aigc) | [视频教程](http://jeecg.com/doc/video)
|
||||
- 技术支持: [反馈问题](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md) | [低代码体验一分钟](https://jeecg.blog.csdn.net/article/details/106079007)
|
||||
- QQ交流群 : 964611995、⑩716488839(满)、⑨808791225(满)、其他(满)
|
||||
|
||||
|
||||
AI 应用平台介绍
|
||||
-----------------------------------
|
||||
|
||||
一个全栈式 AI 开发平台,旨在帮助开发者快速构建和部署个性化的 AI 应用。
|
||||
|
||||
JeecgBoot平台提供了一套完善的AI应用管理系统模块,是一套类似`Dify`的`AIGC应用开发平台`+`知识库问答`,是一款基于LLM大语言模型AI应用平台和 RAG 的知识库问答系统。
|
||||
其直观的界面结合了 AI 流程编排、RAG 管道、知识库管理、模型管理、对接向量库、实时运行可观察等,让您可以快速从原型到生产,拥有AI服务能力。
|
||||
|
||||
- [详细专题介绍,请点击查看](README-AI.md)
|
||||
|
||||
- AI视频介绍
|
||||
|
||||
[](https://www.bilibili.com/video/BV1zmd7YFE4w)
|
||||
|
||||
|
||||
为什么选择JeecgBoot?
|
||||
-----------------------------------
|
||||
- 1.采用最新主流前后分离框架(Spring Boot3 + MyBatis + Shiro/SpringAuthorizationServer + Ant Design4 + Vue3),容易上手;代码生成器依赖性低,灵活的扩展能力,可快速实现二次开发。
|
||||
- 2.前端大版本换代,最新版采用 Vue3.0 + TypeScript + Vite6 + Ant Design Vue4 等新技术方案。
|
||||
- 3.支持微服务Spring Cloud Alibaba(Nacos、Gateway、Sentinel、Skywalking),提供简易机制,支持单体和微服务自由切换(这样可以满足各类项目需求)。
|
||||
- 4.开发效率高,支持在线建表和AI建表,提供强大代码生成器,单表、树列表、一对多、一对一等数据模型,增删改查功能一键生成,菜单配置直接使用。
|
||||
- 5.代码生成器提供强大模板机制,支持自定义模板,目前提供四套风格模板(单表两套、树模型一套、一对多三套)。
|
||||
- 6.提供强大的报表和大屏可视化工具,支持丰富的数据源连接,能够通过拖拉拽方式快速制作报表、大屏和门户设计;支持多种图表类型:柱形图、折线图、散点图、饼图、环形图、面积图、漏斗图、进度图、仪表盘、雷达图、地图等。
|
||||
- 7.低代码能力:在线表单(无需编码,通过在线配置表单,实现表单的增删改查,支持单表、树、一对多、一对一等模型,实现人人皆可编码),在线配置零代码开发、所见即所得支持23种类控件。
|
||||
- 8.低代码能力:在线报表、在线图表(无需编码,通过在线配置方式,实现数据报表和图形报表,可以快速抽取数据,减轻开发压力,实现人人皆可编码)。
|
||||
- 9.Online支持在线增强开发,提供在线代码编辑器,支持代码高亮、代码提示等功能,支持多种语言(Java、SQL、JavaScript等)。
|
||||
- 10.封装完善的用户、角色、菜单、组织机构、数据字典、在线定时任务等基础功能,支持访问授权、按钮权限、数据权限等功能。
|
||||
- 11.前端UI提供丰富的组件库,支持各种常用组件,如表格、树形控件、下拉框、日期选择器等,满足各种复杂的业务需求 [UI组件库文档](https://help.jeecg.com/category/ui%E7%BB%84%E4%BB%B6%E5%BA%93)。
|
||||
- 12.提供APP配套框架,一份多代码多终端适配,一份代码多终端适配,小程序、H5、安卓、iOS、鸿蒙Next。
|
||||
- 13.新版APP框架采用Uniapp、Vue3.0、Vite、Wot-design-uni、TypeScript等最新技术栈,包括二次封装组件、路由拦截、请求拦截等功能。实现了与JeecgBoot完美对接:目前已经实现登录、用户信息、通讯录、公告、移动首页、九宫格、聊天、Online表单、仪表盘等功能,提供了丰富的组件。
|
||||
- 14.提供了一套成熟的AI应用平台功能,从AI模型、知识库到AI应用搭建,助力企业快速落地AI服务,加速智能化升级。
|
||||
- 15.AI能力:目前JeecgBoot支持AI大模型chatgpt和deepseek,现在最新版默认使用deepseek,速度更快质量更高。目前提供了AI对话助手、AI知识库、AI应用、AI建表、AI报表等功能。
|
||||
- 16.提供新行编辑表格JVXETable,轻松满足各种复杂ERP布局,拥有更高的性能、更灵活的扩展、更强大的功能。
|
||||
- 17.平台首页风格,提供多种组合模式,支持自定义风格;支持门户设计,支持自定义首页。
|
||||
- 18.常用共通封装,各种工具类(定时任务、短信接口、邮件发送、Excel导入导出等),基本满足80%项目需求。
|
||||
- 19.简易Excel导入导出,支持单表导出和一对多表模式导出,生成的代码自带导入导出功能。
|
||||
- 20.集成智能报表工具,报表打印、图像报表和数据导出非常方便,可极其方便地生成PDF、Excel、Word等报表。
|
||||
- 21.采用前后分离技术,页面UI风格精美,针对常用组件做了封装:时间、行表格控件、截取显示控件、报表组件、编辑器等。
|
||||
- 22.查询过滤器:查询功能自动生成,后台动态拼SQL追加查询条件;支持多种匹配方式(全匹配/模糊查询/包含查询/不匹配查询)。
|
||||
- 23.数据权限(精细化数据权限控制,控制到行级、列表级、表单字段级,实现不同人看不同数据,不同人对同一个页面操作不同字段)。
|
||||
- 24.接口安全机制,可细化控制接口授权,非常简便实现不同客户端只看自己数据等控制;也提供了基于AK和SK认证鉴权的OpenAPI功能。
|
||||
- 25.活跃的社区支持;近年来,随着网络威胁的日益增加,团队在安全和漏洞管理方面积累了丰富的经验,能够为企业提供全面的安全解决方案。
|
||||
- 26.权限控制采用RBAC(Role-Based Access Control,基于角色的访问控制)。
|
||||
- 27.页面校验自动生成(必须输入、数字校验、金额校验、时间空间等)。
|
||||
- 28.支持SaaS服务模式,提供SaaS多租户架构方案。
|
||||
- 29.分布式文件服务,集成MinIO、阿里OSS等优秀的第三方,提供便捷的文件上传与管理,同时也支持本地存储。
|
||||
- 30.主流数据库兼容,一套代码完全兼容MySQL、PostgreSQL、Oracle、SQL Server、MariaDB、达梦、人大金仓等主流数据库。
|
||||
- 31.集成工作流Flowable,并实现了只需在页面配置流程转向,可极大简化BPM工作流的开发;用BPM的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的Java代码。
|
||||
- 32.低代码能力:在线流程设计,采用开源Flowable流程引擎,实现在线画流程、自定义表单、表单挂靠、业务流转。
|
||||
- 33.多数据源:极其简易的使用方式,在线配置数据源配置,便捷地从其他数据抓取数据。
|
||||
- 34.提供单点登录CAS集成方案,项目中已经提供完善的对接代码。
|
||||
- 35.低代码能力:表单设计器,支持用户自定义表单布局,支持单表、一对多表单,支持select、radio、checkbox、textarea、date、popup、列表、宏等控件。
|
||||
- 36.专业接口对接机制,统一采用RESTful接口方式,集成Swagger-UI在线接口文档,JWT token安全验证,方便客户端对接。
|
||||
- 37.高级组合查询功能,在线配置支持主子表关联查询,可保存查询历史。
|
||||
- 38.提供各种系统监控,实时跟踪系统运行情况(监控Redis、Tomcat、JVM、服务器信息、请求追踪、SQL监控)。
|
||||
- 39.消息中心(支持短信、邮件、微信推送等);集成WebSocket消息通知机制。
|
||||
- 40.支持多语言,提供国际化方案。
|
||||
- 41.数据变更记录日志,可记录数据每次变更内容,通过版本对比功能查看历史变化。
|
||||
- 42.提供简单易用的打印插件,支持谷歌、火狐、IE11+等各种浏览器。
|
||||
- 43.后端采用Maven分模块开发方式;前端支持菜单动态路由。
|
||||
- 44.提供丰富的示例代码,涵盖了常用的业务场景,便于学习和参考。
|
||||
|
||||
|
||||
技术架构:
|
||||
-----------------------------------
|
||||
|
||||
#### 后端
|
||||
|
||||
- IDE建议: IDEA (必须安装lombok插件 )
|
||||
- 语言:Java 默认jdk17(jdk21、jdk24)
|
||||
- 依赖管理:Maven
|
||||
- 基础框架:Spring Boot 3.5.5
|
||||
- 微服务框架: Spring Cloud Alibaba 2023.0.3.3
|
||||
- 持久层框架:MybatisPlus 3.5.12
|
||||
- 报表工具: JimuReport 2.1.3
|
||||
- 安全框架:Apache Shiro 2.0.4,Jwt 4.5.0
|
||||
- 微服务技术栈:Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywalking
|
||||
- 数据库连接池:阿里巴巴Druid 1.2.24
|
||||
- AI大模型:支持 `ChatGPT` `DeepSeek` `千问`等各种常规模式
|
||||
- 日志打印:logback
|
||||
- 缓存:Redis
|
||||
- 其他:autopoi, fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。
|
||||
- 默认提供MySQL5.7+数据库脚本
|
||||
- [其他数据库,需要自己转](https://my.oschina.net/jeecg/blog/4905722)
|
||||
|
||||
|
||||
#### 前端
|
||||
|
||||
- 前端环境要求:Node.js要求`Node 20+` 版本以上、pnpm 要求`9+` 版本以上
|
||||
` ( Vite 不再支持已结束生命周期(EOL)的 Node.js 18。现在需要使用 Node.js 20.19+ 或 22.12+)`
|
||||
|
||||
- 依赖管理:node、npm、pnpm
|
||||
- 前端IDE建议:IDEA、WebStorm、Vscode
|
||||
- 采用 Vue3.0+TypeScript+Vite6+Ant-Design-Vue4等新技术方案,包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能
|
||||
- 最新技术栈:Vue3.0 + TypeScript + Vite6 + ant-design-vue4 + pinia + echarts + unocss + vxe-table + qiankun + es6
|
||||
|
||||
|
||||
|
||||
|
||||
#### 支持库
|
||||
|
||||
| 数据库 | 支持 |
|
||||
| --- | --- |
|
||||
| MySQL | √ |
|
||||
| Oracle11g | √ |
|
||||
| Sqlserver2017 | √ |
|
||||
| PostgreSQL | √ |
|
||||
| MariaDB | √ |
|
||||
| 达梦 | √ |
|
||||
| 人大金仓 | √ |
|
||||
| TiDB | √ |
|
||||
|
||||
|
||||
|
||||
|
||||
## 微服务解决方案
|
||||
|
||||
|
||||
- 1、服务注册和发现 Nacos √
|
||||
- 2、统一配置中心 Nacos √
|
||||
- 3、路由网关 gateway(三种加载方式) √
|
||||
- 4、分布式 http feign √
|
||||
- 5、熔断降级限流 Sentinel √
|
||||
- 6、分布式文件 Minio、阿里OSS √
|
||||
- 7、统一权限控制 JWT + Shiro √
|
||||
- 8、服务监控 SpringBootAdmin√
|
||||
- 9、链路跟踪 Skywalking [参考文档](https://help.jeecg.com/java/springcloud/super/skywarking)
|
||||
- 10、消息中间件 RabbitMQ √
|
||||
- 11、分布式任务 xxl-job √
|
||||
- 12、分布式事务 Seata
|
||||
- 13、轻量分布式日志 Loki+grafana套件
|
||||
- 14、支持 docker-compose、k8s、jenkins
|
||||
- 15、CAS 单点登录 √
|
||||
- 16、路由限流 √
|
||||
|
||||
|
||||
|
||||
后台目录结构
|
||||
-----------------------------------
|
||||
```
|
||||
项目结构
|
||||
├─jeecg-boot-parent(父POM: 项目依赖、modules组织)
|
||||
│ ├─jeecg-boot-base-core(共通模块: 工具类、config、权限、查询过滤器、注解等)
|
||||
│ ├─jeecg-module-demo 示例代码
|
||||
│ ├─jeecg-module-system System系统管理目录
|
||||
│ │ ├─jeecg-system-biz System系统管理权限等功能
|
||||
│ │ ├─jeecg-system-start System单体启动项目(8080)
|
||||
│ │ ├─jeecg-system-api System系统管理模块对外api
|
||||
│ │ │ ├─jeecg-system-cloud-api System模块对外提供的微服务接口
|
||||
│ │ │ ├─jeecg-system-local-api System模块对外提供的单体接口
|
||||
│ ├─jeecg-server-cloud --微服务模块
|
||||
├─jeecg-cloud-gateway --微服务网关模块(9999)
|
||||
├─jeecg-cloud-nacos --Nacos服务模块(8848)
|
||||
├─jeecg-system-cloud-start --System微服务启动项目(7001)
|
||||
├─jeecg-demo-cloud-start --Demo微服务启动项目(7002)
|
||||
├─jeecg-visual
|
||||
├─jeecg-cloud-monitor --微服务监控模块 (9111)
|
||||
├─jeecg-cloud-xxljob --微服务xxljob定时任务服务端 (9080)
|
||||
├─jeecg-cloud-sentinel --sentinel服务端 (9000)
|
||||
├─jeecg-cloud-test -- 微服务测试示例(各种例子)
|
||||
├─jeecg-cloud-test-more -- 微服务测试示例(feign、熔断降级、xxljob、分布式锁)
|
||||
├─jeecg-cloud-test-rabbitmq -- 微服务测试示例(rabbitmq)
|
||||
├─jeecg-cloud-test-seata -- 微服务测试示例(seata分布式事务)
|
||||
├─jeecg-cloud-test-shardingsphere -- 微服务测试示例(分库分表)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### 微服务架构图
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
13
jeecg-boot/db/Dockerfile
Normal file
13
jeecg-boot/db/Dockerfile
Normal file
@ -0,0 +1,13 @@
|
||||
FROM registry.cn-hangzhou.aliyuncs.com/jeecgdocker/mysql:8.0.19
|
||||
|
||||
MAINTAINER jeecgos@163.com
|
||||
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
COPY ./tables_nacos.sql /docker-entrypoint-initdb.d
|
||||
|
||||
COPY ./jeecgboot-mysql-5.7.sql /docker-entrypoint-initdb.d
|
||||
|
||||
COPY ./tables_xxl_job.sql /docker-entrypoint-initdb.d
|
||||
9737
jeecg-boot/db/jeecgboot-mysql-5.7.sql
Normal file
9737
jeecg-boot/db/jeecgboot-mysql-5.7.sql
Normal file
File diff suppressed because one or more lines are too long
357
jeecg-boot/db/tables_nacos.sql
Normal file
357
jeecg-boot/db/tables_nacos.sql
Normal file
File diff suppressed because one or more lines are too long
360
jeecg-boot/db/tables_xxl_job.sql
Normal file
360
jeecg-boot/db/tables_xxl_job.sql
Normal file
@ -0,0 +1,360 @@
|
||||
#
|
||||
# XXL-JOB v2.4.0
|
||||
# Copyright (c) 2015-present, xuxueli.
|
||||
|
||||
CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_general_ci;
|
||||
use `xxl_job`;
|
||||
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : mysql5.7
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 50738 (5.7.38)
|
||||
Source Host : 127.0.0.1:3306
|
||||
Source Schema : xxl_job
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 50738 (5.7.38)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 10/02/2025 13:49:31
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_group
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_group`;
|
||||
CREATE TABLE `xxl_job_group` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`app_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '执行器AppName',
|
||||
`title` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '执行器名称',
|
||||
`address_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '执行器地址类型:0=自动注册、1=手动录入',
|
||||
`address_list` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '执行器地址列表,多地址逗号分隔',
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_group
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_group` VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2025-02-10 13:49:04');
|
||||
INSERT INTO `xxl_job_group` VALUES (2, 'jeecg-demo', '测试Demo模块', 0, NULL, '2025-02-10 13:49:04');
|
||||
INSERT INTO `xxl_job_group` VALUES (3, 'jeecg-system', '系统System模块', 0, NULL, '2025-02-10 13:49:04');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_info`;
|
||||
CREATE TABLE `xxl_job_info` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
|
||||
`job_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`add_time` datetime NULL DEFAULT NULL,
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
`author` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '作者',
|
||||
`alarm_email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '报警邮件',
|
||||
`schedule_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
|
||||
`schedule_conf` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
|
||||
`misfire_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
|
||||
`executor_route_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器路由策略',
|
||||
`executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务handler',
|
||||
`executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务参数',
|
||||
`executor_block_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '阻塞处理策略',
|
||||
`executor_timeout` int(11) NOT NULL DEFAULT 0 COMMENT '任务执行超时时间,单位秒',
|
||||
`executor_fail_retry_count` int(11) NOT NULL DEFAULT 0 COMMENT '失败重试次数',
|
||||
`glue_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE类型',
|
||||
`glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE源代码',
|
||||
`glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE备注',
|
||||
`glue_updatetime` datetime NULL DEFAULT NULL COMMENT 'GLUE更新时间',
|
||||
`child_jobid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
|
||||
`trigger_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '调度状态:0-停止,1-运行',
|
||||
`trigger_last_time` bigint(13) NOT NULL DEFAULT 0 COMMENT '上次调度时间',
|
||||
`trigger_next_time` bigint(13) NOT NULL DEFAULT 0 COMMENT '下次调度时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_info
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_info` VALUES (1, 1, '测试任务1', '2018-11-03 22:21:31', '2024-08-21 22:30:30', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJob', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '', 1, 1729353600000, 1739203200000);
|
||||
INSERT INTO `xxl_job_info` VALUES (2, 3, '测试jeecg xxljob', '2024-08-21 22:41:10', '2024-08-21 22:41:30', 'JEECG', '', 'CRON', '* * * * * ?', 'DO_NOTHING', 'FIRST', 'demoJob', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2024-08-21 22:41:10', '', 1, 1739166572000, 1739166573000);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_lock
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_lock`;
|
||||
CREATE TABLE `xxl_job_lock` (
|
||||
`lock_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '锁名称',
|
||||
PRIMARY KEY (`lock_name`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_lock
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_lock` VALUES ('schedule_lock');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_log
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_log`;
|
||||
CREATE TABLE `xxl_job_log` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
|
||||
`job_id` int(11) NOT NULL COMMENT '任务,主键ID',
|
||||
`executor_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
|
||||
`executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务handler',
|
||||
`executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务参数',
|
||||
`executor_sharding_param` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
|
||||
`executor_fail_retry_count` int(11) NOT NULL DEFAULT 0 COMMENT '失败重试次数',
|
||||
`trigger_time` datetime NULL DEFAULT NULL COMMENT '调度-时间',
|
||||
`trigger_code` int(11) NOT NULL COMMENT '调度-结果',
|
||||
`trigger_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '调度-日志',
|
||||
`handle_time` datetime NULL DEFAULT NULL COMMENT '执行-时间',
|
||||
`handle_code` int(11) NOT NULL COMMENT '执行-状态',
|
||||
`handle_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '执行-日志',
|
||||
`alarm_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `I_trigger_time`(`trigger_time`) USING BTREE,
|
||||
INDEX `I_handle_code`(`handle_code`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 6761 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_log
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_log` VALUES (6618, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:09', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6619, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:10', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6620, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:11', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6621, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:12', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6622, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:13', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6623, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:14', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6624, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:15', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6625, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:16', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6626, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:17', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6627, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:18', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6628, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:19', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6629, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:20', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6630, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:21', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6631, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:22', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6632, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:23', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6633, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:24', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6634, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:25', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6635, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:26', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6636, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:27', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6637, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:28', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6638, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:29', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6639, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:30', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6640, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:31', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6641, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:32', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6642, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:33', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6643, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:34', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6644, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:35', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6645, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:36', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6646, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:37', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6647, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:38', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6648, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:39', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6649, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:40', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6650, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:41', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6651, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:42', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6652, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:43', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6653, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:44', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6654, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:45', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6655, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:46', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6656, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:47', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6657, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:48', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6658, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:49', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6659, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:50', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6660, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:51', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6661, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:52', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6662, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:53', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6663, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:54', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6664, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:55', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6665, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:56', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6666, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:57', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6667, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:58', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6668, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:59', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6669, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:00', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6670, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:01', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6671, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:02', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6672, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:03', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6673, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:04', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6674, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:05', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6675, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:06', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6676, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:07', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6677, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:08', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6678, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:09', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6679, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:10', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6680, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:11', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6681, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:12', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6682, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:13', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6683, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:14', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6684, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:15', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6685, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:16', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6686, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:17', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6687, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:18', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6688, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:19', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6689, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:20', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6690, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:21', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6691, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:22', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6692, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:23', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6693, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:24', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6694, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:25', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6695, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:26', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6696, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:27', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6697, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:28', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6698, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:29', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6699, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:30', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6700, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:31', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6701, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:32', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6702, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:33', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6703, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:34', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6704, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:35', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6705, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:36', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6706, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:37', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6707, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:38', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6708, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:39', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6709, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:40', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6710, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:41', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6711, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:42', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6712, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:43', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6713, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:44', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6714, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:45', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6715, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:46', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6716, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:47', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6717, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:48', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6718, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:49', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6719, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:50', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6720, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:51', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6721, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:52', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6722, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:53', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6723, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:54', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6724, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:55', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6725, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:56', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6726, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:57', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6727, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:58', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6728, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:59', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6729, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:00', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6730, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:01', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6731, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:02', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6732, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:03', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6733, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:04', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6734, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:05', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6735, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:06', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6736, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:07', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6737, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:08', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6738, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:09', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6739, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:10', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6740, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:11', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6741, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:12', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6742, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:13', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6743, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:14', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6744, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:15', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6745, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:16', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6746, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:17', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6747, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:18', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6748, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:19', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6749, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:20', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6750, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:21', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6751, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:22', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6752, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:23', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6753, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:24', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6754, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:25', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6755, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:26', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6756, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:27', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6757, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:28', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6758, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:29', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6759, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:30', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6760, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:31', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_log_report
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_log_report`;
|
||||
CREATE TABLE `xxl_job_log_report` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`trigger_day` datetime NULL DEFAULT NULL COMMENT '调度-时间',
|
||||
`running_count` int(11) NOT NULL DEFAULT 0 COMMENT '运行中-日志数量',
|
||||
`suc_count` int(11) NOT NULL DEFAULT 0 COMMENT '执行成功-日志数量',
|
||||
`fail_count` int(11) NOT NULL DEFAULT 0 COMMENT '执行失败-日志数量',
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `i_trigger_day`(`trigger_day`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_log_report
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_log_report` VALUES (1, '2024-08-21 00:00:00', 70, 0, 5, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (2, '2024-08-20 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (3, '2024-08-19 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (4, '2024-09-10 00:00:00', 0, 0, 56, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (5, '2024-09-09 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (6, '2024-09-08 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (7, '2024-10-19 00:00:00', 0, 0, 6391, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (8, '2024-10-18 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (9, '2024-10-17 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (10, '2025-02-10 00:00:00', 0, 0, 116, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (11, '2025-02-09 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (12, '2025-02-08 00:00:00', 0, 0, 0, NULL);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_logglue
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_logglue`;
|
||||
CREATE TABLE `xxl_job_logglue` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`job_id` int(11) NOT NULL COMMENT '任务,主键ID',
|
||||
`glue_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE类型',
|
||||
`glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE源代码',
|
||||
`glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE备注',
|
||||
`add_time` datetime NULL DEFAULT NULL,
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_logglue
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_registry
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_registry`;
|
||||
CREATE TABLE `xxl_job_registry` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`registry_group` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`registry_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`registry_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `i_g_k_v`(`registry_group`, `registry_key`, `registry_value`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_registry
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_user
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_user`;
|
||||
CREATE TABLE `xxl_job_user` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号',
|
||||
`password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
|
||||
`role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',
|
||||
`permission` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `i_username`(`username`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_user` VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
BIN
jeecg-boot/db/其他数据库脚本/jeecgboot-oracle11g.dmp
Normal file
BIN
jeecg-boot/db/其他数据库脚本/jeecgboot-oracle11g.dmp
Normal file
Binary file not shown.
31499
jeecg-boot/db/其他数据库脚本/jeecgboot-oracle11g.sql
Normal file
31499
jeecg-boot/db/其他数据库脚本/jeecgboot-oracle11g.sql
Normal file
File diff suppressed because one or more lines are too long
27491
jeecg-boot/db/其他数据库脚本/jeecgboot-postgresql17.sql
Normal file
27491
jeecg-boot/db/其他数据库脚本/jeecgboot-postgresql17.sql
Normal file
File diff suppressed because one or more lines are too long
50451
jeecg-boot/db/其他数据库脚本/jeecgboot-sqlserver2017.sql
Normal file
50451
jeecg-boot/db/其他数据库脚本/jeecgboot-sqlserver2017.sql
Normal file
File diff suppressed because one or more lines are too long
5
jeecg-boot/db/其他数据库脚本/oracle11g dmp说明.txt
Normal file
5
jeecg-boot/db/其他数据库脚本/oracle11g dmp说明.txt
Normal file
@ -0,0 +1,5 @@
|
||||
oracle导出编码: export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
|
||||
|
||||
导出用户: jeecgbootos
|
||||
|
||||
导入命令: imp scott/tiger@orcl file=jeecgboot-oracle11g.dmp
|
||||
45
jeecg-boot/db/增量SQL/sas升级脚本.sql
Normal file
45
jeecg-boot/db/增量SQL/sas升级脚本.sql
Normal file
@ -0,0 +1,45 @@
|
||||
CREATE TABLE `oauth2_registered_client` (
|
||||
`id` varchar(100) NOT NULL,
|
||||
`client_id` varchar(100) NOT NULL,
|
||||
`client_id_issued_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`client_secret` varchar(200) DEFAULT NULL,
|
||||
`client_secret_expires_at` timestamp NULL DEFAULT NULL,
|
||||
`client_name` varchar(200) NOT NULL,
|
||||
`client_authentication_methods` varchar(1000) NOT NULL,
|
||||
`authorization_grant_types` varchar(1000) NOT NULL,
|
||||
`redirect_uris` varchar(1000) DEFAULT NULL,
|
||||
`post_logout_redirect_uris` varchar(1000) DEFAULT NULL,
|
||||
`scopes` varchar(1000) NOT NULL,
|
||||
`client_settings` varchar(2000) NOT NULL,
|
||||
`token_settings` varchar(2000) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `oauth2_registered_client`
|
||||
(`id`,
|
||||
`client_id`,
|
||||
`client_id_issued_at`,
|
||||
`client_secret`,
|
||||
`client_secret_expires_at`,
|
||||
`client_name`,
|
||||
`client_authentication_methods`,
|
||||
`authorization_grant_types`,
|
||||
`redirect_uris`,
|
||||
`post_logout_redirect_uris`,
|
||||
`scopes`,
|
||||
`client_settings`,
|
||||
`token_settings`)
|
||||
VALUES
|
||||
('3eacac0e-0de9-4727-9a64-6bdd4be2ee1f',
|
||||
'jeecg-client',
|
||||
now(),
|
||||
'secret',
|
||||
null,
|
||||
'3eacac0e-0de9-4727-9a64-6bdd4be2ee1f',
|
||||
'client_secret_basic',
|
||||
'refresh_token,authorization_code,password,app,phone,social',
|
||||
'http://127.0.0.1:8080/jeecg-',
|
||||
'http://127.0.0.1:8080/',
|
||||
'*',
|
||||
'{"@class":"java.util.Collections$UnmodifiableMap","settings.client.require-proof-key":false,"settings.client.require-authorization-consent":true}',
|
||||
'{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",300000.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300000.000000000],"settings.token.device-code-time-to-live":["java.time.Duration",300000.000000000]}');
|
||||
23
jeecg-boot/db/版本升级说明.md
Normal file
23
jeecg-boot/db/版本升级说明.md
Normal file
@ -0,0 +1,23 @@
|
||||
# 版本升级方法
|
||||
|
||||
> JeecgBoot属于平台级产品,每次升级改动较大,目前做不到平滑升级。
|
||||
|
||||
### 增量升级方案
|
||||
|
||||
#### 1.代码合并
|
||||
本地通过svn或git做好主干,在分支上做业务开发,jeecg每次版本发布,可以手工覆盖主干的代码,对比合并代码;
|
||||
|
||||
#### 2.数据库升级
|
||||
- 从3.6.2+版本增加flyway自动升级数据库机制,支持 mysql5.7、mysql8;
|
||||
- 其他库请手工执行SQL, 目录: `jeecg-module-system\jeecg-system-start\src\main\resources\flyway\sql\mysql`
|
||||
> 注意: 升级sql只提供mysql版本;如果有权限升级, 还需要手工角色授权,退出重新登录才好使。
|
||||
|
||||
#### 3.其他数据库脚本说明
|
||||
原先官方默认提供oracle和SqlServer的脚本,但是维护成本太高,未提供脚本的数据库,可以参考下面的文档自己转
|
||||
https://my.oschina.net/jeecg/blog/4905722
|
||||
(注意:定时任务的表qrtz_*,需要删掉用原始的脚本重新执行一下)
|
||||
quartz-2.2.3-distribution.tar.gz放到百度网盘中,大家自己下载,执行所需数据库脚本
|
||||
https://pan.baidu.com/s/1WrmZdUuAPg3iBwJ-LoHWyg?pwd=8mdz
|
||||
|
||||
#### 4.兼容问题
|
||||
每次发版,会针对不兼容地方重点说明。
|
||||
82
jeecg-boot/docker-compose.yml
Normal file
82
jeecg-boot/docker-compose.yml
Normal file
@ -0,0 +1,82 @@
|
||||
version: '2'
|
||||
services:
|
||||
jeecg-boot-mysql:
|
||||
build:
|
||||
context: ./db
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_ROOT_HOST: '%'
|
||||
TZ: Asia/Shanghai
|
||||
restart: always
|
||||
container_name: jeecg-boot-mysql
|
||||
image: jeecg-boot-mysql
|
||||
command:
|
||||
--character-set-server=utf8mb4
|
||||
--collation-server=utf8mb4_general_ci
|
||||
--explicit_defaults_for_timestamp=true
|
||||
--lower_case_table_names=1
|
||||
--max_allowed_packet=128M
|
||||
--default-authentication-plugin=caching_sha2_password
|
||||
ports:
|
||||
- 13306:3306
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-redis:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/redis:5.0
|
||||
# ports:
|
||||
# - 6379:6379
|
||||
restart: always
|
||||
hostname: jeecg-boot-redis
|
||||
container_name: jeecg-boot-redis
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-pgvector:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/pgvector
|
||||
container_name: jeecg-boot-pgvector
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: vector_db
|
||||
# ports:
|
||||
# - 5432:5432
|
||||
restart: always
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
# jeecg-boot-rabbitmq:
|
||||
# image: rabbitmq:3.7.7-management
|
||||
## ports:
|
||||
## - 5672:5672
|
||||
## - 15672:15672
|
||||
# restart: always
|
||||
# container_name: jeecg-boot-rabbitmq
|
||||
# hostname: jeecg-boot-rabbitmq
|
||||
# environment:
|
||||
# RABBITMQ_DEFAULT_USER: guest
|
||||
# RABBITMQ_DEFAULT_PASS: guest
|
||||
# networks:
|
||||
# - jeecg-boot
|
||||
|
||||
jeecg-boot-system:
|
||||
build:
|
||||
context: ./jeecg-module-system/jeecg-system-start
|
||||
restart: on-failure
|
||||
mac_address: 02:42:ac:11:00:02
|
||||
depends_on:
|
||||
- jeecg-boot-mysql
|
||||
- jeecg-boot-redis
|
||||
container_name: jeecg-boot-system
|
||||
image: jeecg-boot-system
|
||||
hostname: jeecg-boot-system
|
||||
ports:
|
||||
- 8080:8080
|
||||
networks:
|
||||
- jeecg-boot
|
||||
volumes:
|
||||
- ./config:/jeecg-boot/config
|
||||
|
||||
networks:
|
||||
jeecg-boot:
|
||||
name: jeecg_boot
|
||||
342
jeecg-boot/jeecg-boot-base-core/pom.xml
Normal file
342
jeecg-boot/jeecg-boot-base-core/pom.xml
Normal file
@ -0,0 +1,342 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.jeecgframework.boot3</groupId>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<version>3.9.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>aliyun</id>
|
||||
<name>aliyun Repository</name>
|
||||
<url>https://maven.aliyun.com/repository/public</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jeecg</id>
|
||||
<name>jeecg Repository</name>
|
||||
<url>https://maven.jeecg.org/nexus/content/repositories/jeecg</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jeecg-snapshots</id>
|
||||
<name>jeecg-snapshots Repository</name>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!--jeecg-tools-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot3</groupId>
|
||||
<artifactId>jeecg-boot-common</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!--集成springmvc框架并实现自动配置 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- websocket -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<!--springboot2.3+ 需引入validation对应的包-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<!--springboot2.6+解决metrics端点不显示jvm信息的问题-->
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- commons -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>${commons.version}</version>
|
||||
</dependency>
|
||||
<!-- freemarker -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis-plus -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-jsqlparser-4.9</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
<!-- minidao -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot3</groupId>
|
||||
<artifactId>minidao-spring-boot-starter-jsqlparser-4.9</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- druid -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-3-starter</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 动态数据源 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
||||
<version>${dynamic-datasource-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据库驱动 -->
|
||||
<!--mysql-->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql-connector-java.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- sqlserver-->
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>${sqljdbc4.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- oracle驱动 -->
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
<version>${ojdbc6.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- postgresql驱动 -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgresql.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!--人大金仓驱动 版本号V008R006C005B0013 -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>kingbase8</artifactId>
|
||||
<version>${kingbase8.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!--达梦数据库驱动 版本号1-3-26-2023.07.26-197096-20046-ENT -->
|
||||
<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>DmJdbcDriver18</artifactId>
|
||||
<version>${dm8.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>DmDialect-for-hibernate5.0</artifactId>
|
||||
<version>${dm8.version}</version>
|
||||
</dependency>
|
||||
<!-- Quartz定时任务 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--JWT-->
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>${java-jwt.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||
</dependency>
|
||||
<!-- 添加spring security cas支持 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-cas</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-ui</artifactId>
|
||||
<version>${knife4j-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成器 -->
|
||||
<!-- 如下载失败,请参考此文档 https://help.jeecg.com/java/setup/maven.html -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>codegenerate</artifactId>
|
||||
<version>${codegenerate.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<groupId>commons-io</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<groupId>mysql</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- AutoPoi Excel工具类-->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>autopoi-spring-boot-3-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<version>2.12.2</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- mini文件存储服务 -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里云短信 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
|
||||
<version>${aliyun-java-sdk-dysmsapi.version}</version>
|
||||
</dependency>
|
||||
<!-- aliyun oss -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>${aliyun.oss.version}</version>
|
||||
</dependency>
|
||||
<!-- 第三方登录 -->
|
||||
<dependency>
|
||||
<groupId>com.xkcoding.justauth</groupId>
|
||||
<artifactId>justauth-spring-boot-starter</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
<!-- 解决okhttp引用了kotlin,应用启动有警告日志问题 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</dependency>
|
||||
<!--加载hutool-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-crypto</artifactId>
|
||||
</dependency>
|
||||
<!-- chatgpt -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot3</groupId>
|
||||
<artifactId>jeecg-boot-starter-chatgpt</artifactId>
|
||||
</dependency>
|
||||
<!-- 腾讯云 -->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-sms</artifactId>
|
||||
<version>${tencentcloud-sdk-java-sms.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.squareup.okio</groupId>
|
||||
<artifactId>okio</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,21 @@
|
||||
package org.apache.shiro;
|
||||
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
/**
|
||||
* 兼容处理Online功能使用处理,请勿修改
|
||||
* @author eightmonth@qq.com
|
||||
* @date 2024/4/29 14:05
|
||||
*/
|
||||
public class SecurityUtils {
|
||||
|
||||
|
||||
public static Subject getSubject() {
|
||||
return new Subject() {
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
return Subject.super.getPrincipal();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package org.apache.shiro.subject;
|
||||
|
||||
import org.jeecg.config.security.utils.SecureUtil;
|
||||
|
||||
/**
|
||||
* 兼容处理Online功能使用处理,请勿修改
|
||||
* @author eightmonth@qq.com
|
||||
* @date 2024/4/29 14:18
|
||||
*/
|
||||
public interface Subject {
|
||||
default Object getPrincipal() {
|
||||
return SecureUtil.currentUser();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,192 @@
|
||||
package org.jeecg.common.api;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.api.dto.AiragFlowDTO;
|
||||
import org.jeecg.common.system.vo.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 通用api
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public interface CommonAPI {
|
||||
|
||||
/**
|
||||
* 1查询用户角色信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryUserRoles(String username);
|
||||
|
||||
/**
|
||||
* 1查询用户角色信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryUserRolesById(String userId);
|
||||
|
||||
|
||||
/**
|
||||
* 2查询用户权限信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryUserAuths(String userId);
|
||||
|
||||
/**
|
||||
* 3根据 id 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceId
|
||||
* @return
|
||||
*/
|
||||
DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId);
|
||||
|
||||
/**
|
||||
* 4根据 code 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceCode
|
||||
* @return
|
||||
*/
|
||||
DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode);
|
||||
|
||||
/**
|
||||
* 5根据用户账号查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public LoginUser getUserByName(String username);
|
||||
|
||||
/**
|
||||
* 5根据用户账号查询用户Id
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public String getUserIdByName(String username);
|
||||
|
||||
/**
|
||||
* 5根据用户手机号查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public LoginUser getUserByPhone(String phone);
|
||||
|
||||
|
||||
/**
|
||||
* 6字典表的 翻译
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
String translateDictFromTable(String table, String text, String code, String key);
|
||||
|
||||
/**
|
||||
* 7普通字典的翻译
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
String translateDict(String code, String key);
|
||||
|
||||
/**
|
||||
* 8查询数据权限
|
||||
* @param component 组件
|
||||
* @param username 用户名
|
||||
* @param requestPath 前段请求地址
|
||||
* @return
|
||||
*/
|
||||
List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username);
|
||||
|
||||
|
||||
/**
|
||||
* 9查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
SysUserCacheInfo getCacheUser(String username);
|
||||
|
||||
/**
|
||||
* 10获取数据字典
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryDictItemsByCode(String code);
|
||||
|
||||
/**
|
||||
* 获取有效的数据字典项
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryEnableDictItemsByCode(String code);
|
||||
|
||||
/**
|
||||
* 13获取表数据字典
|
||||
* @param tableFilterSql
|
||||
* @param text
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> queryTableDictItemsByCode(String tableFilterSql, String text, String code);
|
||||
|
||||
/**
|
||||
* 14 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
|
||||
* @param dictCodes 例如:user_status,sex
|
||||
* @param keys 例如:1,2,0
|
||||
* @return
|
||||
*/
|
||||
Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys);
|
||||
|
||||
/**
|
||||
* 15 字典表的 翻译,可批量
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys 多个用逗号分割
|
||||
* @param dataSource 数据源
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys, String dataSource);
|
||||
|
||||
/**
|
||||
* 16 运行AIRag流程
|
||||
* for [QQYUN-13634]在baseapi里面封装方法,方便其他模块调用
|
||||
*
|
||||
* @param airagFlowDTO
|
||||
* @return 流程执行结果,可能是String或者Map
|
||||
* @author chenrui
|
||||
* @date 2025/9/2 11:43
|
||||
*/
|
||||
Object runAiragFlow(AiragFlowDTO airagFlowDTO);
|
||||
|
||||
/**
|
||||
* 登录加载系统字典
|
||||
* @return
|
||||
*/
|
||||
Map<String,List<DictModel>> queryAllDictItems();
|
||||
|
||||
/**
|
||||
* 查询SysDepart集合
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
List<SysDepartModel> queryUserDeparts(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户名设置部门ID
|
||||
* @param username
|
||||
* @param orgCode
|
||||
*/
|
||||
void updateUserDepart(String username,String orgCode,Integer loginTenantId);
|
||||
|
||||
/**
|
||||
* 设置登录租户
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
JSONObject setLoginTenant(String username);
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package org.jeecg.common.api.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 调用AI流程入参
|
||||
* for [QQYUN-13634]在baseapi里面封装方法,方便其他模块调用
|
||||
* @author chenrui
|
||||
* @date 2025/9/2 14:11
|
||||
*/
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class AiragFlowDTO implements Serializable {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 7431775881170684867L;
|
||||
|
||||
/**
|
||||
* 流程id
|
||||
*/
|
||||
private String flowId;
|
||||
|
||||
|
||||
/**
|
||||
* 输入参数
|
||||
*/
|
||||
private Map<String, Object> inputParams;
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package org.jeecg.common.api.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 流程审批意见DTO
|
||||
* @author scott
|
||||
* @date 2025-01-29
|
||||
*/
|
||||
@Data
|
||||
public class ApprovalCommentDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
private String taskId;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
private String taskName;
|
||||
|
||||
/**
|
||||
* 审批人ID
|
||||
*/
|
||||
private String approverId;
|
||||
|
||||
/**
|
||||
* 审批人姓名
|
||||
*/
|
||||
private String approverName;
|
||||
|
||||
/**
|
||||
* 审批意见
|
||||
*/
|
||||
private String approvalComment;
|
||||
|
||||
/**
|
||||
* 审批时间
|
||||
*/
|
||||
private Date approvalTime;
|
||||
}
|
||||
|
||||
@ -17,6 +17,8 @@ public class DataLogDTO {
|
||||
|
||||
private String type;
|
||||
|
||||
private String createName;
|
||||
|
||||
public DataLogDTO(){
|
||||
|
||||
}
|
||||
@ -2,7 +2,7 @@ package org.jeecg.common.api.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
@ -1,5 +1,6 @@
|
||||
package org.jeecg.common.api.dto;
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
@ -50,6 +51,16 @@ public class LogDTO implements Serializable {
|
||||
/**操作人用户账户*/
|
||||
private String userid;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private Integer tenantId;
|
||||
|
||||
/**
|
||||
* 客户终端类型 pc:电脑端 app:手机端 h5:移动网页端
|
||||
*/
|
||||
private String clientType;
|
||||
|
||||
public LogDTO(){
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user