master
commit
c69084691e
|
@ -0,0 +1 @@
|
|||
/target/
|
|
@ -0,0 +1,226 @@
|
|||
#
|
||||
# There is insufficient memory for the Java Runtime Environment to continue.
|
||||
# Native memory allocation (mmap) failed to map 1073741824 bytes for G1 virtual space
|
||||
# Possible reasons:
|
||||
# The system is out of physical RAM or swap space
|
||||
# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap
|
||||
# Possible solutions:
|
||||
# Reduce memory load on the system
|
||||
# Increase physical memory or swap space
|
||||
# Check if swap backing store is full
|
||||
# Decrease Java heap size (-Xmx/-Xms)
|
||||
# Decrease number of Java threads
|
||||
# Decrease Java thread stack sizes (-Xss)
|
||||
# Set larger code cache with -XX:ReservedCodeCacheSize=
|
||||
# JVM is running with Zero Based Compressed Oops mode in which the Java heap is
|
||||
# placed in the first 32GB address space. The Java Heap base address is the
|
||||
# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress
|
||||
# to set the Java Heap base and to place the Java Heap above 32GB virtual address.
|
||||
# This output file may be truncated or incomplete.
|
||||
#
|
||||
# Out of Memory Error (os_windows.cpp:3769), pid=20380, tid=33736
|
||||
#
|
||||
# JRE version: (17.0.6+10) (build )
|
||||
# Java VM: OpenJDK 64-Bit Server VM (17.0.6+10-b829.9, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
|
||||
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
|
||||
#
|
||||
|
||||
--------------- S U M M A R Y ------------
|
||||
|
||||
Command Line: git4idea.http.GitAskPassApp Username for 'http://47.92.113.182:3000':
|
||||
|
||||
Host: 11th Gen Intel(R) Core(TM) i5-11400 @ 2.60GHz, 12 cores, 63G, Windows 10 , 64 bit Build 19041 (10.0.19041.928)
|
||||
Time: Mon May 26 09:10:45 2025 Windows 10 , 64 bit Build 19041 (10.0.19041.928) elapsed time: 0.008138 seconds (0d 0h 0m 0s)
|
||||
|
||||
--------------- T H R E A D ---------------
|
||||
|
||||
Current thread (0x000001720d54dff0): JavaThread "Unknown thread" [_thread_in_vm, id=33736, stack(0x0000006b8b800000,0x0000006b8b900000)]
|
||||
|
||||
Stack: [0x0000006b8b800000,0x0000006b8b900000]
|
||||
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
|
||||
V [jvm.dll+0x683c5a]
|
||||
V [jvm.dll+0x842764]
|
||||
V [jvm.dll+0x843f5e]
|
||||
V [jvm.dll+0x8445c3]
|
||||
V [jvm.dll+0x249b75]
|
||||
V [jvm.dll+0x680b29]
|
||||
V [jvm.dll+0x67501a]
|
||||
V [jvm.dll+0x309acb]
|
||||
V [jvm.dll+0x310f86]
|
||||
V [jvm.dll+0x3608ee]
|
||||
V [jvm.dll+0x360b1f]
|
||||
V [jvm.dll+0x2dfbf8]
|
||||
V [jvm.dll+0x2e0b64]
|
||||
V [jvm.dll+0x814051]
|
||||
V [jvm.dll+0x36e6a1]
|
||||
V [jvm.dll+0x7f358c]
|
||||
V [jvm.dll+0x3f0e8f]
|
||||
V [jvm.dll+0x3f29d1]
|
||||
C [jli.dll+0x526b]
|
||||
C [ucrtbase.dll+0x21bb2]
|
||||
C [KERNEL32.DLL+0x17034]
|
||||
C [ntdll.dll+0x52651]
|
||||
|
||||
|
||||
--------------- P R O C E S S ---------------
|
||||
|
||||
Threads class SMR info:
|
||||
_java_thread_list=0x00007ffab98fc058, length=0, elements={
|
||||
}
|
||||
|
||||
Java Threads: ( => current thread )
|
||||
|
||||
Other Threads:
|
||||
0x000001720f7ebcd0 GCTaskThread "GC Thread#0" [stack: 0x0000006b8b900000,0x0000006b8ba00000] [id=33356]
|
||||
0x000001720f7fc930 ConcurrentGCThread "G1 Main Marker" [stack: 0x0000006b8ba00000,0x0000006b8bb00000] [id=24860]
|
||||
0x000001720f7ff300 ConcurrentGCThread "G1 Conc#0" [stack: 0x0000006b8bb00000,0x0000006b8bc00000] [id=33200]
|
||||
|
||||
[error occurred during error reporting (printing all threads), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab90b0797]
|
||||
|
||||
VM state: not at safepoint (not fully initialized)
|
||||
|
||||
VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event])
|
||||
[0x000001720d54ac80] Heap_lock - owner thread: 0x000001720d54dff0
|
||||
|
||||
Heap address: 0x0000000403800000, size: 16328 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
|
||||
|
||||
CDS archive(s) mapped at: [0x0000000000000000-0x0000000000000000-0x0000000000000000), size 0, SharedBaseAddress: 0x0000000800000000, ArchiveRelocationMode: 0.
|
||||
Narrow klass base: 0x0000000000000000, Narrow klass shift: 0, Narrow klass range: 0x0
|
||||
|
||||
GC Precious Log:
|
||||
<Empty>
|
||||
|
||||
Heap:
|
||||
garbage-first heap total 0K, used 0K [0x0000000403800000, 0x0000000800000000)
|
||||
region size 8192K, 0 young (0K), 0 survivors (0K)
|
||||
|
||||
[error occurred during error reporting (printing heap information), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab949da49]
|
||||
|
||||
GC Heap History (0 events):
|
||||
No events
|
||||
|
||||
Dll operation events (1 events):
|
||||
Event: 0.005 Loaded shared library D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.dll
|
||||
|
||||
Deoptimization events (0 events):
|
||||
No events
|
||||
|
||||
Classes unloaded (0 events):
|
||||
No events
|
||||
|
||||
Classes redefined (0 events):
|
||||
No events
|
||||
|
||||
Internal exceptions (0 events):
|
||||
No events
|
||||
|
||||
VM Operations (0 events):
|
||||
No events
|
||||
|
||||
Events (0 events):
|
||||
No events
|
||||
|
||||
|
||||
Dynamic libraries:
|
||||
0x00007ff6b1c40000 - 0x00007ff6b1c4a000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.exe
|
||||
0x00007ffb55590000 - 0x00007ffb55785000 C:\Windows\SYSTEM32\ntdll.dll
|
||||
0x00007ffb54e90000 - 0x00007ffb54f4d000 C:\Windows\System32\KERNEL32.DLL
|
||||
0x00007ffb52f30000 - 0x00007ffb531f8000 C:\Windows\System32\KERNELBASE.dll
|
||||
0x00007ffb53280000 - 0x00007ffb53380000 C:\Windows\System32\ucrtbase.dll
|
||||
0x00007ffb4d2d0000 - 0x00007ffb4d2e7000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\jli.dll
|
||||
0x00007ffb3fa60000 - 0x00007ffb3fa7b000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\VCRUNTIME140.dll
|
||||
0x00007ffb54880000 - 0x00007ffb54a20000 C:\Windows\System32\USER32.dll
|
||||
0x00007ffb53480000 - 0x00007ffb534a2000 C:\Windows\System32\win32u.dll
|
||||
0x00007ffb55520000 - 0x00007ffb5554a000 C:\Windows\System32\GDI32.dll
|
||||
0x00007ffb20cb0000 - 0x00007ffb20f4a000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.844_none_ca00b6081b84eb1d\COMCTL32.dll
|
||||
0x00007ffb534b0000 - 0x00007ffb535bb000 C:\Windows\System32\gdi32full.dll
|
||||
0x00007ffb54f50000 - 0x00007ffb54fee000 C:\Windows\System32\msvcrt.dll
|
||||
0x00007ffb52cd0000 - 0x00007ffb52d6d000 C:\Windows\System32\msvcp_win.dll
|
||||
0x00007ffb53790000 - 0x00007ffb537c0000 C:\Windows\System32\IMM32.DLL
|
||||
0x00007ffb3ff90000 - 0x00007ffb3ff9c000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\vcruntime140_1.dll
|
||||
0x00007ffb1af00000 - 0x00007ffb1af8d000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\msvcp140.dll
|
||||
0x00007ffab8dc0000 - 0x00007ffab9a2e000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\server\jvm.dll
|
||||
0x00007ffb537c0000 - 0x00007ffb5386c000 C:\Windows\System32\ADVAPI32.dll
|
||||
0x00007ffb553f0000 - 0x00007ffb5548b000 C:\Windows\System32\sechost.dll
|
||||
0x00007ffb53600000 - 0x00007ffb5372b000 C:\Windows\System32\RPCRT4.dll
|
||||
0x00007ffb36c80000 - 0x00007ffb36c89000 C:\Windows\SYSTEM32\WSOCK32.dll
|
||||
0x00007ffb3d3a0000 - 0x00007ffb3d3c7000 C:\Windows\SYSTEM32\WINMM.dll
|
||||
0x00007ffb540c0000 - 0x00007ffb5412b000 C:\Windows\System32\WS2_32.dll
|
||||
0x00007ffb4cb40000 - 0x00007ffb4cb4a000 C:\Windows\SYSTEM32\VERSION.dll
|
||||
0x00007ffb51580000 - 0x00007ffb51592000 C:\Windows\SYSTEM32\kernel.appcore.dll
|
||||
0x00007ffb4f730000 - 0x00007ffb4f73a000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\jimage.dll
|
||||
0x00007ffb50900000 - 0x00007ffb50ae4000 C:\Windows\SYSTEM32\DBGHELP.DLL
|
||||
0x00007ffb3cb60000 - 0x00007ffb3cb8c000 C:\Windows\SYSTEM32\dbgcore.DLL
|
||||
0x00007ffb53200000 - 0x00007ffb53280000 C:\Windows\System32\bcryptPrimitives.dll
|
||||
0x00007ffb41110000 - 0x00007ffb41135000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.dll
|
||||
|
||||
dbghelp: loaded successfully - version: 4.0.5 - missing functions: none
|
||||
symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;D:\IntelliJ IDEA 2023.1.2\jbr\bin;C:\Windows\SYSTEM32;C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.844_none_ca00b6081b84eb1d;D:\IntelliJ IDEA 2023.1.2\jbr\bin\server
|
||||
|
||||
VM Arguments:
|
||||
java_command: git4idea.http.GitAskPassApp Username for 'http://47.92.113.182:3000':
|
||||
java_class_path (initial): D:/IntelliJ IDEA 2023.1.2/plugins/vcs-git/lib/git4idea-rt.jar;D:/IntelliJ IDEA 2023.1.2/lib/externalProcess-rt.jar
|
||||
Launcher Type: SUN_STANDARD
|
||||
|
||||
[Global flags]
|
||||
intx CICompilerCount = 4 {product} {ergonomic}
|
||||
uint ConcGCThreads = 3 {product} {ergonomic}
|
||||
uint G1ConcRefinementThreads = 10 {product} {ergonomic}
|
||||
size_t G1HeapRegionSize = 8388608 {product} {ergonomic}
|
||||
uintx GCDrainStackTargetSize = 64 {product} {ergonomic}
|
||||
size_t InitialHeapSize = 1073741824 {product} {ergonomic}
|
||||
size_t MarkStackSize = 4194304 {product} {ergonomic}
|
||||
size_t MaxHeapSize = 17121148928 {product} {ergonomic}
|
||||
size_t MinHeapDeltaBytes = 8388608 {product} {ergonomic}
|
||||
size_t MinHeapSize = 8388608 {product} {ergonomic}
|
||||
uintx NonNMethodCodeHeapSize = 5839372 {pd product} {ergonomic}
|
||||
uintx NonProfiledCodeHeapSize = 122909434 {pd product} {ergonomic}
|
||||
uintx ProfiledCodeHeapSize = 122909434 {pd product} {ergonomic}
|
||||
uintx ReservedCodeCacheSize = 251658240 {pd product} {ergonomic}
|
||||
bool SegmentedCodeCache = true {product} {ergonomic}
|
||||
size_t SoftMaxHeapSize = 17121148928 {manageable} {ergonomic}
|
||||
bool UseCompressedClassPointers = true {product lp64_product} {ergonomic}
|
||||
bool UseCompressedOops = true {product lp64_product} {ergonomic}
|
||||
bool UseG1GC = true {product} {ergonomic}
|
||||
bool UseLargePagesIndividualAllocation = false {pd product} {ergonomic}
|
||||
|
||||
Logging:
|
||||
Log output configuration:
|
||||
#0: stdout all=warning uptime,level,tags
|
||||
#1: stderr all=off uptime,level,tags
|
||||
|
||||
Environment Variables:
|
||||
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_162
|
||||
PATH=C:/Program Files/Git/mingw64/libexec/git-core;C:/Program Files/Git/mingw64/libexec/git-core;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Users\Administrator\bin;C:\ProgramData\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Program Files\TortoiseSVN\bin;F:\NetSarang\Xmanager 7\;F:\NetSarang\Xshell 7\;F:\NetSarang\Xftp 7\;F:\NetSarang\Xlpd 7\;D:\nvm;C:\Program Files\nodejs;D:\nvm;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts;C:\Pro;ram Files (x86)\NetSarang\Xftp 7\;C:\Program Files\Git\cmd;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\emulator;%ANDROID_HOME%\tools;%ANDROID_HOME%\tools\bin;C:\Users\Administrator\AppData\Local\Yarn\bin;C:\Program Files\dotnet\;C:\Program Files (x86)\NetSarang\Xftp 7\;D:\΢ÐÅweb¿ª·¢Õß¹¤¾ß\dll;C:\Program Files\Docker\Docker\resources\bin;D:\OpenCV\opencv\build\java;C:\Program Files (x86)\NetSarang\Xshell 8\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;H:\QQGameTempest\Hall.57821\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts\pip.exe
|
||||
USERNAME=Administrator
|
||||
DISPLAY=:0.0
|
||||
LC_ALL=en_US.UTF-8
|
||||
TERM=xterm-256color
|
||||
TMPDIR=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
OS=Windows_NT
|
||||
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 167 Stepping 1, GenuineIntel
|
||||
TMP=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
TEMP=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
|
||||
|
||||
JNI global refs:
|
||||
|
||||
[error occurred during error reporting (JNI global references), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab8e77a10]
|
||||
|
||||
|
||||
--------------- S Y S T E M ---------------
|
||||
|
||||
OS:
|
||||
Windows 10 , 64 bit Build 19041 (10.0.19041.928)
|
||||
OS uptime: 11 days 0:51 hours
|
||||
|
||||
CPU: total 12 (initial active 12) (6 cores per cpu, 2 threads per core) family 6 model 167 stepping 1 microcode 0x40, cx8, cmov, fxsr, ht, mmx, 3dnowpref, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, lzcnt, tsc, tscinvbit, avx, avx2, aes, erms, clmul, bmi1, bmi2, adx, avx512f, avx512dq, avx512cd, avx512bw, avx512vl, sha, fma, vzeroupper, avx512_vpopcntdq, avx512_vpclmulqdq, avx512_vaes, avx512_vnni, clflush, clflushopt, avx512_vbmi2, avx512_vbmi
|
||||
|
||||
Memory: 4k page, system-wide physical 65301M (35503M free)
|
||||
TotalPageFile size 112089M (AvailPageFile size 707M)
|
||||
current process WorkingSet (physical memory assigned to process): 11M, peak: 11M
|
||||
current process commit charge ("private bytes"): 64M, peak: 1088M
|
||||
|
||||
vm_info: OpenJDK 64-Bit Server VM (17.0.6+10-b829.9) for windows-amd64 JRE (17.0.6+10-b829.9), built on 2023-04-09 by "builduser" with MS VC++ 16.10 / 16.11 (VS2019)
|
||||
|
||||
END.
|
|
@ -0,0 +1,226 @@
|
|||
#
|
||||
# There is insufficient memory for the Java Runtime Environment to continue.
|
||||
# Native memory allocation (mmap) failed to map 16777216 bytes for G1 virtual space
|
||||
# Possible reasons:
|
||||
# The system is out of physical RAM or swap space
|
||||
# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap
|
||||
# Possible solutions:
|
||||
# Reduce memory load on the system
|
||||
# Increase physical memory or swap space
|
||||
# Check if swap backing store is full
|
||||
# Decrease Java heap size (-Xmx/-Xms)
|
||||
# Decrease number of Java threads
|
||||
# Decrease Java thread stack sizes (-Xss)
|
||||
# Set larger code cache with -XX:ReservedCodeCacheSize=
|
||||
# JVM is running with Zero Based Compressed Oops mode in which the Java heap is
|
||||
# placed in the first 32GB address space. The Java Heap base address is the
|
||||
# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress
|
||||
# to set the Java Heap base and to place the Java Heap above 32GB virtual address.
|
||||
# This output file may be truncated or incomplete.
|
||||
#
|
||||
# Out of Memory Error (os_windows.cpp:3769), pid=34376, tid=13284
|
||||
#
|
||||
# JRE version: (17.0.6+10) (build )
|
||||
# Java VM: OpenJDK 64-Bit Server VM (17.0.6+10-b829.9, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
|
||||
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
|
||||
#
|
||||
|
||||
--------------- S U M M A R Y ------------
|
||||
|
||||
Command Line: git4idea.http.GitAskPassApp Username for 'http://47.92.113.182:3000':
|
||||
|
||||
Host: 11th Gen Intel(R) Core(TM) i5-11400 @ 2.60GHz, 12 cores, 63G, Windows 10 , 64 bit Build 19041 (10.0.19041.928)
|
||||
Time: Mon May 26 08:50:45 2025 Windows 10 , 64 bit Build 19041 (10.0.19041.928) elapsed time: 0.008697 seconds (0d 0h 0m 0s)
|
||||
|
||||
--------------- T H R E A D ---------------
|
||||
|
||||
Current thread (0x000001411897b460): JavaThread "Unknown thread" [_thread_in_vm, id=13284, stack(0x0000001915a00000,0x0000001915b00000)]
|
||||
|
||||
Stack: [0x0000001915a00000,0x0000001915b00000]
|
||||
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
|
||||
V [jvm.dll+0x683c5a]
|
||||
V [jvm.dll+0x842764]
|
||||
V [jvm.dll+0x843f5e]
|
||||
V [jvm.dll+0x8445c3]
|
||||
V [jvm.dll+0x249b75]
|
||||
V [jvm.dll+0x680b29]
|
||||
V [jvm.dll+0x67501a]
|
||||
V [jvm.dll+0x309acb]
|
||||
V [jvm.dll+0x310f86]
|
||||
V [jvm.dll+0x360918]
|
||||
V [jvm.dll+0x360b1f]
|
||||
V [jvm.dll+0x2dfbf8]
|
||||
V [jvm.dll+0x2e0b64]
|
||||
V [jvm.dll+0x814051]
|
||||
V [jvm.dll+0x36e6a1]
|
||||
V [jvm.dll+0x7f358c]
|
||||
V [jvm.dll+0x3f0e8f]
|
||||
V [jvm.dll+0x3f29d1]
|
||||
C [jli.dll+0x526b]
|
||||
C [ucrtbase.dll+0x21bb2]
|
||||
C [KERNEL32.DLL+0x17034]
|
||||
C [ntdll.dll+0x52651]
|
||||
|
||||
|
||||
--------------- P R O C E S S ---------------
|
||||
|
||||
Threads class SMR info:
|
||||
_java_thread_list=0x00007ffab98fc058, length=0, elements={
|
||||
}
|
||||
|
||||
Java Threads: ( => current thread )
|
||||
|
||||
Other Threads:
|
||||
0x0000014118a2b8e0 GCTaskThread "GC Thread#0" [stack: 0x0000001915b00000,0x0000001915c00000] [id=13876]
|
||||
0x0000014118a3c540 ConcurrentGCThread "G1 Main Marker" [stack: 0x0000001915c00000,0x0000001915d00000] [id=29328]
|
||||
0x0000014118a3df60 ConcurrentGCThread "G1 Conc#0" [stack: 0x0000001915d00000,0x0000001915e00000] [id=32564]
|
||||
|
||||
[error occurred during error reporting (printing all threads), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab90b0797]
|
||||
|
||||
VM state: not at safepoint (not fully initialized)
|
||||
|
||||
VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event])
|
||||
[0x0000014118976210] Heap_lock - owner thread: 0x000001411897b460
|
||||
|
||||
Heap address: 0x0000000403800000, size: 16328 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
|
||||
|
||||
CDS archive(s) mapped at: [0x0000000000000000-0x0000000000000000-0x0000000000000000), size 0, SharedBaseAddress: 0x0000000800000000, ArchiveRelocationMode: 0.
|
||||
Narrow klass base: 0x0000000000000000, Narrow klass shift: 0, Narrow klass range: 0x0
|
||||
|
||||
GC Precious Log:
|
||||
<Empty>
|
||||
|
||||
Heap:
|
||||
garbage-first heap total 0K, used 0K [0x0000000403800000, 0x0000000800000000)
|
||||
region size 8192K, 0 young (0K), 0 survivors (0K)
|
||||
|
||||
[error occurred during error reporting (printing heap information), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab949da49]
|
||||
|
||||
GC Heap History (0 events):
|
||||
No events
|
||||
|
||||
Dll operation events (1 events):
|
||||
Event: 0.005 Loaded shared library D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.dll
|
||||
|
||||
Deoptimization events (0 events):
|
||||
No events
|
||||
|
||||
Classes unloaded (0 events):
|
||||
No events
|
||||
|
||||
Classes redefined (0 events):
|
||||
No events
|
||||
|
||||
Internal exceptions (0 events):
|
||||
No events
|
||||
|
||||
VM Operations (0 events):
|
||||
No events
|
||||
|
||||
Events (0 events):
|
||||
No events
|
||||
|
||||
|
||||
Dynamic libraries:
|
||||
0x00007ff6b1c40000 - 0x00007ff6b1c4a000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.exe
|
||||
0x00007ffb55590000 - 0x00007ffb55785000 C:\Windows\SYSTEM32\ntdll.dll
|
||||
0x00007ffb54e90000 - 0x00007ffb54f4d000 C:\Windows\System32\KERNEL32.DLL
|
||||
0x00007ffb52f30000 - 0x00007ffb531f8000 C:\Windows\System32\KERNELBASE.dll
|
||||
0x00007ffb53280000 - 0x00007ffb53380000 C:\Windows\System32\ucrtbase.dll
|
||||
0x00007ffb4d2d0000 - 0x00007ffb4d2e7000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\jli.dll
|
||||
0x00007ffb3fa60000 - 0x00007ffb3fa7b000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\VCRUNTIME140.dll
|
||||
0x00007ffb54880000 - 0x00007ffb54a20000 C:\Windows\System32\USER32.dll
|
||||
0x00007ffb53480000 - 0x00007ffb534a2000 C:\Windows\System32\win32u.dll
|
||||
0x00007ffb55520000 - 0x00007ffb5554a000 C:\Windows\System32\GDI32.dll
|
||||
0x00007ffb20cb0000 - 0x00007ffb20f4a000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.844_none_ca00b6081b84eb1d\COMCTL32.dll
|
||||
0x00007ffb534b0000 - 0x00007ffb535bb000 C:\Windows\System32\gdi32full.dll
|
||||
0x00007ffb54f50000 - 0x00007ffb54fee000 C:\Windows\System32\msvcrt.dll
|
||||
0x00007ffb52cd0000 - 0x00007ffb52d6d000 C:\Windows\System32\msvcp_win.dll
|
||||
0x00007ffb53790000 - 0x00007ffb537c0000 C:\Windows\System32\IMM32.DLL
|
||||
0x00007ffb3ff90000 - 0x00007ffb3ff9c000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\vcruntime140_1.dll
|
||||
0x00007ffb1af00000 - 0x00007ffb1af8d000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\msvcp140.dll
|
||||
0x00007ffab8dc0000 - 0x00007ffab9a2e000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\server\jvm.dll
|
||||
0x00007ffb537c0000 - 0x00007ffb5386c000 C:\Windows\System32\ADVAPI32.dll
|
||||
0x00007ffb553f0000 - 0x00007ffb5548b000 C:\Windows\System32\sechost.dll
|
||||
0x00007ffb53600000 - 0x00007ffb5372b000 C:\Windows\System32\RPCRT4.dll
|
||||
0x00007ffb36c80000 - 0x00007ffb36c89000 C:\Windows\SYSTEM32\WSOCK32.dll
|
||||
0x00007ffb3d3a0000 - 0x00007ffb3d3c7000 C:\Windows\SYSTEM32\WINMM.dll
|
||||
0x00007ffb4cb40000 - 0x00007ffb4cb4a000 C:\Windows\SYSTEM32\VERSION.dll
|
||||
0x00007ffb540c0000 - 0x00007ffb5412b000 C:\Windows\System32\WS2_32.dll
|
||||
0x00007ffb51580000 - 0x00007ffb51592000 C:\Windows\SYSTEM32\kernel.appcore.dll
|
||||
0x00007ffb4f730000 - 0x00007ffb4f73a000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\jimage.dll
|
||||
0x00007ffb50900000 - 0x00007ffb50ae4000 C:\Windows\SYSTEM32\DBGHELP.DLL
|
||||
0x00007ffb3cb60000 - 0x00007ffb3cb8c000 C:\Windows\SYSTEM32\dbgcore.DLL
|
||||
0x00007ffb53200000 - 0x00007ffb53280000 C:\Windows\System32\bcryptPrimitives.dll
|
||||
0x00007ffb41110000 - 0x00007ffb41135000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.dll
|
||||
|
||||
dbghelp: loaded successfully - version: 4.0.5 - missing functions: none
|
||||
symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;D:\IntelliJ IDEA 2023.1.2\jbr\bin;C:\Windows\SYSTEM32;C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.844_none_ca00b6081b84eb1d;D:\IntelliJ IDEA 2023.1.2\jbr\bin\server
|
||||
|
||||
VM Arguments:
|
||||
java_command: git4idea.http.GitAskPassApp Username for 'http://47.92.113.182:3000':
|
||||
java_class_path (initial): D:/IntelliJ IDEA 2023.1.2/plugins/vcs-git/lib/git4idea-rt.jar;D:/IntelliJ IDEA 2023.1.2/lib/externalProcess-rt.jar
|
||||
Launcher Type: SUN_STANDARD
|
||||
|
||||
[Global flags]
|
||||
intx CICompilerCount = 4 {product} {ergonomic}
|
||||
uint ConcGCThreads = 3 {product} {ergonomic}
|
||||
uint G1ConcRefinementThreads = 10 {product} {ergonomic}
|
||||
size_t G1HeapRegionSize = 8388608 {product} {ergonomic}
|
||||
uintx GCDrainStackTargetSize = 64 {product} {ergonomic}
|
||||
size_t InitialHeapSize = 1073741824 {product} {ergonomic}
|
||||
size_t MarkStackSize = 4194304 {product} {ergonomic}
|
||||
size_t MaxHeapSize = 17121148928 {product} {ergonomic}
|
||||
size_t MinHeapDeltaBytes = 8388608 {product} {ergonomic}
|
||||
size_t MinHeapSize = 8388608 {product} {ergonomic}
|
||||
uintx NonNMethodCodeHeapSize = 5839372 {pd product} {ergonomic}
|
||||
uintx NonProfiledCodeHeapSize = 122909434 {pd product} {ergonomic}
|
||||
uintx ProfiledCodeHeapSize = 122909434 {pd product} {ergonomic}
|
||||
uintx ReservedCodeCacheSize = 251658240 {pd product} {ergonomic}
|
||||
bool SegmentedCodeCache = true {product} {ergonomic}
|
||||
size_t SoftMaxHeapSize = 17121148928 {manageable} {ergonomic}
|
||||
bool UseCompressedClassPointers = true {product lp64_product} {ergonomic}
|
||||
bool UseCompressedOops = true {product lp64_product} {ergonomic}
|
||||
bool UseG1GC = true {product} {ergonomic}
|
||||
bool UseLargePagesIndividualAllocation = false {pd product} {ergonomic}
|
||||
|
||||
Logging:
|
||||
Log output configuration:
|
||||
#0: stdout all=warning uptime,level,tags
|
||||
#1: stderr all=off uptime,level,tags
|
||||
|
||||
Environment Variables:
|
||||
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_162
|
||||
PATH=C:/Program Files/Git/mingw64/libexec/git-core;C:/Program Files/Git/mingw64/libexec/git-core;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Users\Administrator\bin;C:\ProgramData\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Program Files\TortoiseSVN\bin;F:\NetSarang\Xmanager 7\;F:\NetSarang\Xshell 7\;F:\NetSarang\Xftp 7\;F:\NetSarang\Xlpd 7\;D:\nvm;C:\Program Files\nodejs;D:\nvm;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts;C:\Pro;ram Files (x86)\NetSarang\Xftp 7\;C:\Program Files\Git\cmd;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\emulator;%ANDROID_HOME%\tools;%ANDROID_HOME%\tools\bin;C:\Users\Administrator\AppData\Local\Yarn\bin;C:\Program Files\dotnet\;C:\Program Files (x86)\NetSarang\Xftp 7\;D:\΢ÐÅweb¿ª·¢Õß¹¤¾ß\dll;C:\Program Files\Docker\Docker\resources\bin;D:\OpenCV\opencv\build\java;C:\Program Files (x86)\NetSarang\Xshell 8\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;H:\QQGameTempest\Hall.57821\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts\pip.exe
|
||||
USERNAME=Administrator
|
||||
DISPLAY=:0.0
|
||||
LC_ALL=en_US.UTF-8
|
||||
TERM=xterm-256color
|
||||
TMPDIR=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
OS=Windows_NT
|
||||
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 167 Stepping 1, GenuineIntel
|
||||
TMP=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
TEMP=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
|
||||
|
||||
JNI global refs:
|
||||
|
||||
[error occurred during error reporting (JNI global references), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab8e77a10]
|
||||
|
||||
|
||||
--------------- S Y S T E M ---------------
|
||||
|
||||
OS:
|
||||
Windows 10 , 64 bit Build 19041 (10.0.19041.928)
|
||||
OS uptime: 11 days 0:31 hours
|
||||
|
||||
CPU: total 12 (initial active 12) (6 cores per cpu, 2 threads per core) family 6 model 167 stepping 1 microcode 0x40, cx8, cmov, fxsr, ht, mmx, 3dnowpref, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, lzcnt, tsc, tscinvbit, avx, avx2, aes, erms, clmul, bmi1, bmi2, adx, avx512f, avx512dq, avx512cd, avx512bw, avx512vl, sha, fma, vzeroupper, avx512_vpopcntdq, avx512_vpclmulqdq, avx512_vaes, avx512_vnni, clflush, clflushopt, avx512_vbmi2, avx512_vbmi
|
||||
|
||||
Memory: 4k page, system-wide physical 65301M (35603M free)
|
||||
TotalPageFile size 112089M (AvailPageFile size 18M)
|
||||
current process WorkingSet (physical memory assigned to process): 11M, peak: 11M
|
||||
current process commit charge ("private bytes"): 1106M, peak: 1122M
|
||||
|
||||
vm_info: OpenJDK 64-Bit Server VM (17.0.6+10-b829.9) for windows-amd64 JRE (17.0.6+10-b829.9), built on 2023-04-09 by "builduser" with MS VC++ 16.10 / 16.11 (VS2019)
|
||||
|
||||
END.
|
|
@ -0,0 +1,222 @@
|
|||
#
|
||||
# There is insufficient memory for the Java Runtime Environment to continue.
|
||||
# Native memory allocation (mmap) failed to map 1073741824 bytes for G1 virtual space
|
||||
# Possible reasons:
|
||||
# The system is out of physical RAM or swap space
|
||||
# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap
|
||||
# Possible solutions:
|
||||
# Reduce memory load on the system
|
||||
# Increase physical memory or swap space
|
||||
# Check if swap backing store is full
|
||||
# Decrease Java heap size (-Xmx/-Xms)
|
||||
# Decrease number of Java threads
|
||||
# Decrease Java thread stack sizes (-Xss)
|
||||
# Set larger code cache with -XX:ReservedCodeCacheSize=
|
||||
# This output file may be truncated or incomplete.
|
||||
#
|
||||
# Out of Memory Error (os_windows.cpp:3769), pid=9004, tid=34776
|
||||
#
|
||||
# JRE version: (17.0.6+10) (build )
|
||||
# Java VM: OpenJDK 64-Bit Server VM (17.0.6+10-b829.9, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
|
||||
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
|
||||
#
|
||||
|
||||
--------------- S U M M A R Y ------------
|
||||
|
||||
Command Line: git4idea.http.GitAskPassApp Username for 'http://47.92.113.182:3000':
|
||||
|
||||
Host: 11th Gen Intel(R) Core(TM) i5-11400 @ 2.60GHz, 12 cores, 63G, Windows 10 , 64 bit Build 19041 (10.0.19041.928)
|
||||
Time: Mon May 26 09:50:45 2025 Windows 10 , 64 bit Build 19041 (10.0.19041.928) elapsed time: 0.008095 seconds (0d 0h 0m 0s)
|
||||
|
||||
--------------- T H R E A D ---------------
|
||||
|
||||
Current thread (0x0000010662dbb330): JavaThread "Unknown thread" [_thread_in_vm, id=34776, stack(0x0000000582300000,0x0000000582400000)]
|
||||
|
||||
Stack: [0x0000000582300000,0x0000000582400000]
|
||||
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
|
||||
V [jvm.dll+0x683c5a]
|
||||
V [jvm.dll+0x842764]
|
||||
V [jvm.dll+0x843f5e]
|
||||
V [jvm.dll+0x8445c3]
|
||||
V [jvm.dll+0x249b75]
|
||||
V [jvm.dll+0x680b29]
|
||||
V [jvm.dll+0x67501a]
|
||||
V [jvm.dll+0x309acb]
|
||||
V [jvm.dll+0x310f86]
|
||||
V [jvm.dll+0x3608ee]
|
||||
V [jvm.dll+0x360b1f]
|
||||
V [jvm.dll+0x2dfbf8]
|
||||
V [jvm.dll+0x2e0b64]
|
||||
V [jvm.dll+0x814051]
|
||||
V [jvm.dll+0x36e6a1]
|
||||
V [jvm.dll+0x7f358c]
|
||||
V [jvm.dll+0x3f0e8f]
|
||||
V [jvm.dll+0x3f29d1]
|
||||
C [jli.dll+0x526b]
|
||||
C [ucrtbase.dll+0x21bb2]
|
||||
C [KERNEL32.DLL+0x17034]
|
||||
C [ntdll.dll+0x52651]
|
||||
|
||||
|
||||
--------------- P R O C E S S ---------------
|
||||
|
||||
Threads class SMR info:
|
||||
_java_thread_list=0x00007ffab98fc058, length=0, elements={
|
||||
}
|
||||
|
||||
Java Threads: ( => current thread )
|
||||
|
||||
Other Threads:
|
||||
0x0000010662e6a690 GCTaskThread "GC Thread#0" [stack: 0x0000000582400000,0x0000000582500000] [id=34376]
|
||||
0x0000010662e7b2f0 ConcurrentGCThread "G1 Main Marker" [stack: 0x0000000582500000,0x0000000582600000] [id=29108]
|
||||
0x0000010662e7cd10 ConcurrentGCThread "G1 Conc#0" [stack: 0x0000000582600000,0x0000000582700000] [id=3396]
|
||||
|
||||
[error occurred during error reporting (printing all threads), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab90b0797]
|
||||
|
||||
VM state: not at safepoint (not fully initialized)
|
||||
|
||||
VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event])
|
||||
[0x0000010662db6d40] Heap_lock - owner thread: 0x0000010662dbb330
|
||||
|
||||
Heap address: 0x0000001000800000, size: 16328 MB, Compressed Oops mode: Non-zero disjoint base: 0x0000001000000000, Oop shift amount: 3
|
||||
|
||||
CDS archive(s) mapped at: [0x0000000000000000-0x0000000000000000-0x0000000000000000), size 0, SharedBaseAddress: 0x0000000800000000, ArchiveRelocationMode: 0.
|
||||
Narrow klass base: 0x0000000000000000, Narrow klass shift: 0, Narrow klass range: 0x0
|
||||
|
||||
GC Precious Log:
|
||||
<Empty>
|
||||
|
||||
Heap:
|
||||
garbage-first heap total 0K, used 0K [0x0000001000800000, 0x00000013fd000000)
|
||||
region size 8192K, 0 young (0K), 0 survivors (0K)
|
||||
|
||||
[error occurred during error reporting (printing heap information), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab949da49]
|
||||
|
||||
GC Heap History (0 events):
|
||||
No events
|
||||
|
||||
Dll operation events (1 events):
|
||||
Event: 0.005 Loaded shared library D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.dll
|
||||
|
||||
Deoptimization events (0 events):
|
||||
No events
|
||||
|
||||
Classes unloaded (0 events):
|
||||
No events
|
||||
|
||||
Classes redefined (0 events):
|
||||
No events
|
||||
|
||||
Internal exceptions (0 events):
|
||||
No events
|
||||
|
||||
VM Operations (0 events):
|
||||
No events
|
||||
|
||||
Events (0 events):
|
||||
No events
|
||||
|
||||
|
||||
Dynamic libraries:
|
||||
0x00007ff6b1c40000 - 0x00007ff6b1c4a000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.exe
|
||||
0x00007ffb55590000 - 0x00007ffb55785000 C:\Windows\SYSTEM32\ntdll.dll
|
||||
0x00007ffb54e90000 - 0x00007ffb54f4d000 C:\Windows\System32\KERNEL32.DLL
|
||||
0x00007ffb52f30000 - 0x00007ffb531f8000 C:\Windows\System32\KERNELBASE.dll
|
||||
0x00007ffb53280000 - 0x00007ffb53380000 C:\Windows\System32\ucrtbase.dll
|
||||
0x00007ffb3fa60000 - 0x00007ffb3fa7b000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\VCRUNTIME140.dll
|
||||
0x00007ffb4d2d0000 - 0x00007ffb4d2e7000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\jli.dll
|
||||
0x00007ffb54880000 - 0x00007ffb54a20000 C:\Windows\System32\USER32.dll
|
||||
0x00007ffb53480000 - 0x00007ffb534a2000 C:\Windows\System32\win32u.dll
|
||||
0x00007ffb55520000 - 0x00007ffb5554a000 C:\Windows\System32\GDI32.dll
|
||||
0x00007ffb20cb0000 - 0x00007ffb20f4a000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.844_none_ca00b6081b84eb1d\COMCTL32.dll
|
||||
0x00007ffb534b0000 - 0x00007ffb535bb000 C:\Windows\System32\gdi32full.dll
|
||||
0x00007ffb54f50000 - 0x00007ffb54fee000 C:\Windows\System32\msvcrt.dll
|
||||
0x00007ffb52cd0000 - 0x00007ffb52d6d000 C:\Windows\System32\msvcp_win.dll
|
||||
0x00007ffb53790000 - 0x00007ffb537c0000 C:\Windows\System32\IMM32.DLL
|
||||
0x00007ffb3ff90000 - 0x00007ffb3ff9c000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\vcruntime140_1.dll
|
||||
0x00007ffb1af00000 - 0x00007ffb1af8d000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\msvcp140.dll
|
||||
0x00007ffab8dc0000 - 0x00007ffab9a2e000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\server\jvm.dll
|
||||
0x00007ffb537c0000 - 0x00007ffb5386c000 C:\Windows\System32\ADVAPI32.dll
|
||||
0x00007ffb553f0000 - 0x00007ffb5548b000 C:\Windows\System32\sechost.dll
|
||||
0x00007ffb53600000 - 0x00007ffb5372b000 C:\Windows\System32\RPCRT4.dll
|
||||
0x00007ffb36c80000 - 0x00007ffb36c89000 C:\Windows\SYSTEM32\WSOCK32.dll
|
||||
0x00007ffb3d3a0000 - 0x00007ffb3d3c7000 C:\Windows\SYSTEM32\WINMM.dll
|
||||
0x00007ffb540c0000 - 0x00007ffb5412b000 C:\Windows\System32\WS2_32.dll
|
||||
0x00007ffb4cb40000 - 0x00007ffb4cb4a000 C:\Windows\SYSTEM32\VERSION.dll
|
||||
0x00007ffb51580000 - 0x00007ffb51592000 C:\Windows\SYSTEM32\kernel.appcore.dll
|
||||
0x00007ffb4f730000 - 0x00007ffb4f73a000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\jimage.dll
|
||||
0x00007ffb50900000 - 0x00007ffb50ae4000 C:\Windows\SYSTEM32\DBGHELP.DLL
|
||||
0x00007ffb3cb60000 - 0x00007ffb3cb8c000 C:\Windows\SYSTEM32\dbgcore.DLL
|
||||
0x00007ffb53200000 - 0x00007ffb53280000 C:\Windows\System32\bcryptPrimitives.dll
|
||||
0x00007ffb41110000 - 0x00007ffb41135000 D:\IntelliJ IDEA 2023.1.2\jbr\bin\java.dll
|
||||
|
||||
dbghelp: loaded successfully - version: 4.0.5 - missing functions: none
|
||||
symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;D:\IntelliJ IDEA 2023.1.2\jbr\bin;C:\Windows\SYSTEM32;C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.844_none_ca00b6081b84eb1d;D:\IntelliJ IDEA 2023.1.2\jbr\bin\server
|
||||
|
||||
VM Arguments:
|
||||
java_command: git4idea.http.GitAskPassApp Username for 'http://47.92.113.182:3000':
|
||||
java_class_path (initial): D:/IntelliJ IDEA 2023.1.2/plugins/vcs-git/lib/git4idea-rt.jar;D:/IntelliJ IDEA 2023.1.2/lib/externalProcess-rt.jar
|
||||
Launcher Type: SUN_STANDARD
|
||||
|
||||
[Global flags]
|
||||
intx CICompilerCount = 4 {product} {ergonomic}
|
||||
uint ConcGCThreads = 3 {product} {ergonomic}
|
||||
uint G1ConcRefinementThreads = 10 {product} {ergonomic}
|
||||
size_t G1HeapRegionSize = 8388608 {product} {ergonomic}
|
||||
uintx GCDrainStackTargetSize = 64 {product} {ergonomic}
|
||||
size_t InitialHeapSize = 1073741824 {product} {ergonomic}
|
||||
size_t MarkStackSize = 4194304 {product} {ergonomic}
|
||||
size_t MaxHeapSize = 17121148928 {product} {ergonomic}
|
||||
size_t MinHeapDeltaBytes = 8388608 {product} {ergonomic}
|
||||
size_t MinHeapSize = 8388608 {product} {ergonomic}
|
||||
uintx NonNMethodCodeHeapSize = 5839372 {pd product} {ergonomic}
|
||||
uintx NonProfiledCodeHeapSize = 122909434 {pd product} {ergonomic}
|
||||
uintx ProfiledCodeHeapSize = 122909434 {pd product} {ergonomic}
|
||||
uintx ReservedCodeCacheSize = 251658240 {pd product} {ergonomic}
|
||||
bool SegmentedCodeCache = true {product} {ergonomic}
|
||||
size_t SoftMaxHeapSize = 17121148928 {manageable} {ergonomic}
|
||||
bool UseCompressedClassPointers = true {product lp64_product} {ergonomic}
|
||||
bool UseCompressedOops = true {product lp64_product} {ergonomic}
|
||||
bool UseG1GC = true {product} {ergonomic}
|
||||
bool UseLargePagesIndividualAllocation = false {pd product} {ergonomic}
|
||||
|
||||
Logging:
|
||||
Log output configuration:
|
||||
#0: stdout all=warning uptime,level,tags
|
||||
#1: stderr all=off uptime,level,tags
|
||||
|
||||
Environment Variables:
|
||||
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_162
|
||||
PATH=C:/Program Files/Git/mingw64/libexec/git-core;C:/Program Files/Git/mingw64/libexec/git-core;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Users\Administrator\bin;C:\ProgramData\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Program Files\TortoiseSVN\bin;F:\NetSarang\Xmanager 7\;F:\NetSarang\Xshell 7\;F:\NetSarang\Xftp 7\;F:\NetSarang\Xlpd 7\;D:\nvm;C:\Program Files\nodejs;D:\nvm;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts;C:\Pro;ram Files (x86)\NetSarang\Xftp 7\;C:\Program Files\Git\cmd;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\emulator;%ANDROID_HOME%\tools;%ANDROID_HOME%\tools\bin;C:\Users\Administrator\AppData\Local\Yarn\bin;C:\Program Files\dotnet\;C:\Program Files (x86)\NetSarang\Xftp 7\;D:\΢ÐÅweb¿ª·¢Õß¹¤¾ß\dll;C:\Program Files\Docker\Docker\resources\bin;D:\OpenCV\opencv\build\java;C:\Program Files (x86)\NetSarang\Xshell 8\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;H:\QQGameTempest\Hall.57821\;C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Scripts\pip.exe
|
||||
USERNAME=Administrator
|
||||
DISPLAY=:0.0
|
||||
LC_ALL=en_US.UTF-8
|
||||
TERM=xterm-256color
|
||||
TMPDIR=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
OS=Windows_NT
|
||||
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 167 Stepping 1, GenuineIntel
|
||||
TMP=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
TEMP=C:\Users\ADMINI~1\AppData\Local\Temp
|
||||
|
||||
|
||||
JNI global refs:
|
||||
|
||||
[error occurred during error reporting (JNI global references), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffab8e77a10]
|
||||
|
||||
|
||||
--------------- S Y S T E M ---------------
|
||||
|
||||
OS:
|
||||
Windows 10 , 64 bit Build 19041 (10.0.19041.928)
|
||||
OS uptime: 11 days 1:31 hours
|
||||
|
||||
CPU: total 12 (initial active 12) (6 cores per cpu, 2 threads per core) family 6 model 167 stepping 1 microcode 0x40, cx8, cmov, fxsr, ht, mmx, 3dnowpref, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, lzcnt, tsc, tscinvbit, avx, avx2, aes, erms, clmul, bmi1, bmi2, adx, avx512f, avx512dq, avx512cd, avx512bw, avx512vl, sha, fma, vzeroupper, avx512_vpopcntdq, avx512_vpclmulqdq, avx512_vaes, avx512_vnni, clflush, clflushopt, avx512_vbmi2, avx512_vbmi
|
||||
|
||||
Memory: 4k page, system-wide physical 65301M (35293M free)
|
||||
TotalPageFile size 112089M (AvailPageFile size 775M)
|
||||
current process WorkingSet (physical memory assigned to process): 11M, peak: 11M
|
||||
current process commit charge ("private bytes"): 72M, peak: 1096M
|
||||
|
||||
vm_info: OpenJDK 64-Bit Server VM (17.0.6+10-b829.9) for windows-amd64 JRE (17.0.6+10-b829.9), built on 2023-04-09 by "builduser" with MS VC++ 16.10 / 16.11 (VS2019)
|
||||
|
||||
END.
|
|
@ -0,0 +1,394 @@
|
|||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>qa_kangzai</artifactId>
|
||||
<version>1.0</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<name>qa_kangzai</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.6</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<mybatisplus.version>3.5.6</mybatisplus.version>
|
||||
<mysql.version>8.0.28</mysql.version>
|
||||
<mssql.version>4.0</mssql.version>
|
||||
<oracle.version>11.2.0.3</oracle.version>
|
||||
<druid.version>1.1.13</druid.version>
|
||||
<quartz.version>2.3.0</quartz.version>
|
||||
<commons.lang.version>2.6</commons.lang.version>
|
||||
<commons.fileupload.version>1.2.2</commons.fileupload.version>
|
||||
<commons.io.version>2.11.0</commons.io.version>
|
||||
<commons.codec.version>1.10</commons.codec.version>
|
||||
<commons.configuration.version>1.10</commons.configuration.version>
|
||||
<shiro.version>1.9.0</shiro.version>
|
||||
<jwt.version>0.7.0</jwt.version>
|
||||
<kaptcha.version>0.0.9</kaptcha.version>
|
||||
<qiniu.version>7.2.23</qiniu.version>
|
||||
<aliyun.oss.version>2.8.3</aliyun.oss.version>
|
||||
<qcloud.cos.version>4.4</qcloud.cos.version>
|
||||
<swagger.version>2.7.0</swagger.version>
|
||||
<joda.time.version>2.9.9</joda.time.version>
|
||||
<gson.version>2.8.5</gson.version>
|
||||
<fastjson.version>1.2.79</fastjson.version>
|
||||
<hutool.version>4.1.1</hutool.version>
|
||||
<lombok.version>1.18.4</lombok.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- DevTools 热部署 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatisplus.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.yulichang</groupId>
|
||||
<artifactId>mybatis-plus-join-boot-starter</artifactId>
|
||||
<version>1.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
</dependency>
|
||||
<!--mssql驱动-->
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>sqljdbc4</artifactId>
|
||||
<version>${mssql.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>${quartz.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.mchange</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>${commons.lang.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>${commons.fileupload.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons.codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<version>${commons.configuration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>${jwt.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.axet</groupId>
|
||||
<artifactId>kaptcha</artifactId>
|
||||
<version>${kaptcha.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiniu</groupId>
|
||||
<artifactId>qiniu-java-sdk</artifactId>
|
||||
<version>${qiniu.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qcloud</groupId>
|
||||
<artifactId>cos_api</artifactId>
|
||||
<version>${qcloud.cos.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${joda.time.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>5.2.9.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- OSS -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.10.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MP4视频解析 -->
|
||||
<dependency>
|
||||
<groupId>ws.schild</groupId>
|
||||
<artifactId>jave-all-deps</artifactId>
|
||||
<version>2.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 文件上传 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
<version>4.5.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- POI -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>5.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>5.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
<!-- poi模板导入,主力包 -->
|
||||
<dependency>
|
||||
<groupId>com.deepoove</groupId>
|
||||
<artifactId>poi-tl</artifactId>
|
||||
<version>1.12.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 短信服务 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<!--多环境⽂件配置-->
|
||||
<profiles>
|
||||
<!--开发环境-->
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<!--默认激活-->
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<spring.profiles.active>dev</spring.profiles.active>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>test</id>
|
||||
<properties>
|
||||
<spring.profiles.active>test</spring.profiles.active>
|
||||
</properties>
|
||||
</profile>
|
||||
<!--正式环境-->
|
||||
<profile>
|
||||
<id>prod</id>
|
||||
<properties>
|
||||
<spring.profiles.active>prod</spring.profiles.active>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<extensions>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.wagon</groupId>
|
||||
<artifactId>wagon-ssh</artifactId>
|
||||
<version>2.8</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.6.6</version>
|
||||
<configuration>
|
||||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- 跳过单元测试 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.2</version>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<version>0.4.14</version>
|
||||
<!--<executions>-->
|
||||
<!--<execution>-->
|
||||
<!--<phase>package</phase>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>build</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--</execution>-->
|
||||
<!--</executions>-->
|
||||
<configuration>
|
||||
<imageName>check_repo</imageName>
|
||||
<dockerDirectory>${project.basedir}</dockerDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>/</targetPath>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<include>${project.build.finalName}.jar</include>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
<!-- 运行命令 mvn clean package docker:build 打包并生成docker镜像 -->
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>https://maven.aliyun.com/repository/public/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>https://maven.aliyun.com/repository/public/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</project>
|
|
@ -0,0 +1,14 @@
|
|||
package com.zcloud;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
|
||||
@SpringBootApplication
|
||||
public class MainApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MainApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.zcloud;
|
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
/**
|
||||
* 说明:项目以war包方式运行时用到
|
||||
*/
|
||||
public class SpringBootStartApplication extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
||||
return builder.sources(MainApplication.class); //这里要指向原先用main方法执行的FHmainApplication启动类
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.zcloud.common.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 系统日志注解
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SysLog {
|
||||
String value() default "";
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
|
||||
package com.zcloud.common.aspect;
|
||||
|
||||
import com.zcloud.common.exception.ZException;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Redis切面处理类
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Aspect
|
||||
@Configuration
|
||||
public class RedisAspect {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
//是否开启redis缓存 true开启 false关闭
|
||||
@Value("${spring.redis.open: false}")
|
||||
private boolean open;
|
||||
|
||||
@Around("execution(* com.zcloud.common.utils.RedisUtils.*(..))")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
Object result = null;
|
||||
if(open){
|
||||
try{
|
||||
result = point.proceed();
|
||||
}catch (Exception e){
|
||||
logger.error("redis error", e);
|
||||
throw new ZException("Redis服务异常");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
|
||||
package com.zcloud.common.aspect;
|
||||
import com.google.gson.Gson;
|
||||
import com.zcloud.common.annotation.SysLog;
|
||||
import com.zcloud.common.utils.HttpContextUtils;
|
||||
import com.zcloud.common.utils.IPUtils;
|
||||
import com.zcloud.modules.sys.entity.SysLogEntity;
|
||||
import com.zcloud.modules.sys.entity.SysUserEntity;
|
||||
import com.zcloud.modules.sys.service.SysLogService;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 系统日志,切面处理类
|
||||
*
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class SysLogAspect {
|
||||
@Autowired
|
||||
private SysLogService sysLogService;
|
||||
|
||||
@Pointcut("@annotation(com.zcloud.common.annotation.SysLog)")
|
||||
public void logPointCut() {
|
||||
|
||||
}
|
||||
|
||||
@Around("logPointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
//执行方法
|
||||
Object result = point.proceed();
|
||||
//执行时长(毫秒)
|
||||
long time = System.currentTimeMillis() - beginTime;
|
||||
|
||||
//保存日志
|
||||
saveSysLog(point, time);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
|
||||
SysLogEntity sysLog = new SysLogEntity();
|
||||
SysLog syslog = method.getAnnotation(SysLog.class);
|
||||
if(syslog != null){
|
||||
//注解上的描述
|
||||
sysLog.setOperation(syslog.value());
|
||||
}
|
||||
|
||||
//请求的方法名
|
||||
String className = joinPoint.getTarget().getClass().getName();
|
||||
String methodName = signature.getName();
|
||||
sysLog.setMethod(className + "." + methodName + "()");
|
||||
|
||||
//请求的参数
|
||||
Object[] args = joinPoint.getArgs();
|
||||
try{
|
||||
String params = new Gson().toJson(args);
|
||||
sysLog.setParams(params);
|
||||
}catch (Exception e){
|
||||
|
||||
}
|
||||
|
||||
//获取request
|
||||
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
||||
//设置IP地址
|
||||
sysLog.setIp(IPUtils.getIpAddr(request));
|
||||
|
||||
//用户名
|
||||
String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
|
||||
sysLog.setUsername(username);
|
||||
sysLog.setCorpinfoId(((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getCorpinfoId());
|
||||
|
||||
sysLog.setTime(time);
|
||||
sysLog.setCreateDate(new Date());
|
||||
//保存系统日志
|
||||
sysLogService.saveLog(sysLog);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.zcloud.common.eunm;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author liuxia
|
||||
* @description TODO
|
||||
* @date 2025/5/15/周四 9:58
|
||||
*/
|
||||
@Getter
|
||||
public enum CheckTeamMemberTypeEnum {
|
||||
|
||||
EXPERT_LEADER(1,"专家组长"),
|
||||
EXPERT_MEMBER( 2,"专家组员");
|
||||
|
||||
private Integer type;
|
||||
|
||||
private String desc;
|
||||
|
||||
CheckTeamMemberTypeEnum(Integer type, String desc) {
|
||||
this.type = type;
|
||||
this.desc = desc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.zcloud.common.eunm;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author chenke
|
||||
* @description TODO
|
||||
* @date 2025/5/13/周二 13:07
|
||||
*/
|
||||
@Getter
|
||||
public enum DistributeEnum {
|
||||
|
||||
NOT_DISTRIBUTED(0,"未下发"),
|
||||
ALREADY_DISTRIBUTED(1,"已下发");
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String desc;
|
||||
|
||||
DistributeEnum(Integer status, String desc) {
|
||||
this.status = status;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.zcloud.common.eunm;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author chenk
|
||||
* @description TODO
|
||||
* @date 2025/5/14/周三 14:56
|
||||
*/
|
||||
@Getter
|
||||
public enum TroubleshootTypeEnum {
|
||||
|
||||
TROUBLESHOOT("pc","排查"),
|
||||
RECHECK( "fc","复查");
|
||||
|
||||
private String type;
|
||||
|
||||
private String desc;
|
||||
|
||||
TroubleshootTypeEnum(String type, String desc) {
|
||||
this.type = type;
|
||||
this.desc = desc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
|
||||
package com.zcloud.common.exception;
|
||||
|
||||
/**
|
||||
* 自定义异常
|
||||
*
|
||||
*/
|
||||
public class ZException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String msg;
|
||||
private int code = 500;
|
||||
|
||||
public ZException(String msg) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public ZException(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public ZException(String msg, int code) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public ZException(String msg, int code, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.zcloud.common.exception;
|
||||
|
||||
import com.zcloud.common.utils.R;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
*
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
public class ZExceptionHandler {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(ZException.class)
|
||||
public R handleRRException(ZException e){
|
||||
R r = new R();
|
||||
r.put("code", e.getCode());
|
||||
r.put("msg", e.getMessage());
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoHandlerFoundException.class)
|
||||
public R handlerNoFoundException(Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error(404, "路径不存在,请检查路径是否正确");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public R handleDuplicateKeyException(DuplicateKeyException e){
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error("数据库中已存在该记录");
|
||||
}
|
||||
|
||||
@ExceptionHandler(AuthorizationException.class)
|
||||
public R handleAuthorizationException(AuthorizationException e){
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error("没有权限,请联系管理员授权");
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public R handleException(Exception e){
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.zcloud.common.handler;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.zcloud.common.utils.AesEncryptor;
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class EncryptTypeHandler<T> extends BaseTypeHandler<T> {
|
||||
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
|
||||
ps.setString(i, AesEncryptor.aesEncrypt((String)parameter));
|
||||
}
|
||||
@Override
|
||||
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
String columnValue = rs.getString(columnName);
|
||||
//有一些可能是空字符
|
||||
return StrUtil.isBlank(columnValue) ? (T)columnValue : (T)AesEncryptor.aesDecrypt(columnValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
String columnValue = rs.getString(columnIndex);
|
||||
return StrUtil.isBlank(columnValue) ? (T)columnValue : (T)AesEncryptor.aesDecrypt(columnValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
String columnValue = cs.getString(columnIndex);
|
||||
return StrUtil.isBlank(columnValue) ? (T)columnValue : (T)AesEncryptor.aesDecrypt(columnValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.zcloud.common.handler;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
@Component
|
||||
public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
|
||||
|
||||
/**
|
||||
* Converter for support http request with header Content-Type: multipart/form-data
|
||||
*/
|
||||
public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) {
|
||||
super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canWrite(MediaType mediaType) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.zcloud.common.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import com.zcloud.common.utils.DateUtil;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
this.strictInsertFill(metaObject,"isDelete", Integer.class, 0);
|
||||
this.setFieldValByName("createTime", DateUtil.date2Str(new Date()), metaObject);
|
||||
this.setFieldValByName("operatTime", DateUtil.date2Str(new Date()), metaObject);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
this.setFieldValByName("operatTime", DateUtil.date2Str(new Date()), metaObject);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
package com.zcloud.common.handler;
|
||||
|
||||
import cn.hutool.log.Log;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.zcloud.common.utils.HttpRequestUtil;
|
||||
import com.zcloud.common.utils.MD5;
|
||||
import com.zcloud.common.utils.PageUtils;
|
||||
import com.zcloud.common.utils.R;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author fangjiakai
|
||||
* @date 2023/10/19 10:44
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "customer")
|
||||
@Component
|
||||
public class PlatVideoHandler {
|
||||
private String id;
|
||||
private String secret_key;
|
||||
private String url;
|
||||
private String domain;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSecret_key() {
|
||||
return secret_key;
|
||||
}
|
||||
|
||||
public void setSecret_key(String secret_key) {
|
||||
this.secret_key = secret_key;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
public PageUtils syncCurList(Map<String, Object> params) {
|
||||
HashMap<String, String> request = new HashMap<>();
|
||||
request.put("id", id);
|
||||
String key = MD5.md5(secret_key + domain);
|
||||
request.put("SECRET_KEY", key);
|
||||
if(params.get("name")!=null) request.put("KEYWORDS", params.get("name").toString());
|
||||
request.put("showCount", params.get("limit").toString());
|
||||
request.put("currentPage", params.get("curPage").toString());
|
||||
String _response = HttpRequestUtil.doPost(url + "/curriculum/getCurList", JSONObject.toJSONString(request));
|
||||
JSONObject responseResult = JSONObject.parseObject(_response);
|
||||
System.out.println(responseResult);
|
||||
Page page = new Page();
|
||||
page.setRecords(responseResult.getJSONArray("curriculumList"));
|
||||
page.setTotal(Long.parseLong(responseResult.getJSONObject("page").getString("totalResult")));
|
||||
page.setSize(Long.parseLong(params.get("limit").toString()));
|
||||
page.setCurrent(Long.parseLong(responseResult.getJSONObject("page").getString("currentPage")));
|
||||
page.setPages(Long.parseLong(responseResult.getJSONObject("page").getString("totalPage")));
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
public JSONObject syncCurInfo(Map<String, Object> params) {
|
||||
HashMap<String, String> request = new HashMap<>();
|
||||
request.put("CURRICULUM_ID", params.get("curriculum_id").toString());
|
||||
request.put("id", id);
|
||||
String key = MD5.md5(secret_key + domain);
|
||||
request.put("SECRET_KEY", key);
|
||||
String _response = HttpRequestUtil.doPost(url + "/curriculum/getCurInfo", JSONObject.toJSONString(request));
|
||||
JSONObject responseResult = JSONObject.parseObject(_response);
|
||||
System.out.println(responseResult);
|
||||
if(responseResult != null && responseResult.get("code") != null && StringUtils.isNotBlank(responseResult.get("code").toString()) && "0".equals(responseResult.get("code"))){
|
||||
return responseResult;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public R syncVideoPlayAuth(Map<String, Object> video) {
|
||||
HashMap<String, String> request = new HashMap<>();
|
||||
request.put("id", this.id);
|
||||
request.put("videoId", video.get("video_id_remote").toString());
|
||||
request.put("curriculumId", video.get("curriculum_id_remote").toString());
|
||||
request.put("type", "0");
|
||||
String key = MD5.md5(secret_key + domain);
|
||||
request.put("SECRET_KEY", key);
|
||||
String _response = HttpRequestUtil.doPost(url + "/videoCourseware/getPlayInfo", JSONObject.toJSONString(request));
|
||||
Map response = JSONObject.parseObject(_response, Map.class);
|
||||
return R.ok().put("responseBody",response);
|
||||
}
|
||||
|
||||
/**
|
||||
* description: 获取视频封面<p/>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public Map syncVideoInfo(Map video) {
|
||||
HashMap<String, String> request = new HashMap<>();
|
||||
request.put("id", id);
|
||||
request.put("videoId", video.get("videocourseware_id_remote").toString());
|
||||
request.put("curriculumId", video.get("curriculum_id_remote").toString());
|
||||
request.put("type", "0");
|
||||
String key = MD5.md5(secret_key + domain);
|
||||
request.put("SECRET_KEY", key);
|
||||
String _response = HttpRequestUtil.doPost(url + "/videoCourseware/getPlayUrl", JSONObject.toJSONString(request));
|
||||
Map response = JSONObject.parseObject(_response, Map.class);
|
||||
return response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import sun.misc.BASE64Decoder;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* AES的加密和解密
|
||||
* @author libo
|
||||
*/
|
||||
public class AesEncryptor {
|
||||
//密钥 (需要前端和后端保持一致)
|
||||
// private static final String KEY = "qwertyuiqwertyui";
|
||||
private static final String KEY = "daac3ae52eff4cec";
|
||||
//算法
|
||||
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
|
||||
|
||||
/**
|
||||
* aes解密
|
||||
* @param encrypt 内容
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesDecrypt(String encrypt) {
|
||||
try {
|
||||
return aesDecrypt(encrypt, KEY);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* aes加密
|
||||
* @param content
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesEncrypt(String content) {
|
||||
try {
|
||||
return aesEncrypt(content, KEY);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将byte[]转为各种进制的字符串
|
||||
* @param bytes byte[]
|
||||
* @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制
|
||||
* @return 转换后的字符串
|
||||
*/
|
||||
public static String binary(byte[] bytes, int radix){
|
||||
return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
|
||||
}
|
||||
|
||||
/**
|
||||
* base 64 encode
|
||||
* @param bytes 待编码的byte[]
|
||||
* @return 编码后的base 64 code
|
||||
*/
|
||||
public static String base64Encode(byte[] bytes){
|
||||
return Base64.encodeBase64String(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* base 64 decode
|
||||
* @param base64Code 待解码的base 64 code
|
||||
* @return 解码后的byte[]
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] base64Decode(String base64Code) throws Exception{
|
||||
return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AES加密
|
||||
* @param content 待加密的内容
|
||||
* @param encryptKey 加密密钥
|
||||
* @return 加密后的byte[]
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");
|
||||
kgen.init(128);
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
|
||||
|
||||
return cipher.doFinal(content.getBytes("utf-8"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AES加密为base 64 code
|
||||
* @param content 待加密的内容
|
||||
* @param encryptKey 加密密钥
|
||||
* @return 加密后的base 64 code
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesEncrypt(String content, String encryptKey) throws Exception {
|
||||
return base64Encode(aesEncryptToBytes(content, encryptKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* AES解密
|
||||
* @param encryptBytes 待解密的byte[]
|
||||
* @param decryptKey 解密密钥
|
||||
* @return 解密后的String
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");
|
||||
kgen.init(128);
|
||||
|
||||
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
|
||||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
|
||||
byte[] decryptBytes = cipher.doFinal(encryptBytes);
|
||||
return new String(decryptBytes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将base 64 code AES解密
|
||||
* @param encryptStr 待解密的base 64 code
|
||||
* @param decryptKey 解密密钥
|
||||
* @return 解密后的string
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
|
||||
return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
String content = "123";
|
||||
System.out.println("加密前:" + content);
|
||||
System.out.println("加密密钥和解密密钥:" + KEY);
|
||||
String encrypt = aesEncrypt(content, KEY);
|
||||
System.out.println("加密后:" + encrypt);
|
||||
String decrypt = aesDecrypt(encrypt, KEY);
|
||||
System.out.println("解密后:" + decrypt);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
|
||||
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;
|
||||
import com.zcloud.modules.sys.entity.PageData;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
// 有限空间发送短信工具类
|
||||
public class AliSmsToolUtil {
|
||||
|
||||
//产品名称:云通信短信API产品,开发者无需替换
|
||||
static final String product = "Dysmsapi";
|
||||
//产品域名,开发者无需替换
|
||||
static final String domain = "dysmsapi.aliyuncs.com";
|
||||
|
||||
// TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
|
||||
static final String accessKeyId = "LTAI5tK134ZzXPEwykAdpVn2";//LTAI4G7hRf3LqVGvobYRFxW2
|
||||
static final String accessKeySecret = "XCEMY8FG52cXImFMeIiH4tDJ9BIN3N";//T43mhQvHiEPt9oBmWP3BLFuqtaYKhr
|
||||
|
||||
public static SendSmsResponse sendSms(Map<String,Object> sendmap, List<PageData> paramsList) throws ClientException {
|
||||
Map<String,Object> map = new HashMap<String,Object>();
|
||||
//可自助调整超时时间
|
||||
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
|
||||
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
|
||||
|
||||
//初始化acsClient,暂不支持region化
|
||||
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
|
||||
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
|
||||
IAcsClient acsClient = new DefaultAcsClient(profile);
|
||||
// String alipaysms = Tools.readTxtFile("admin/config/alipaysms.txt");//读取WEBSOCKET配置
|
||||
// if(null != alipaysms && !"".equals(alipaysms)){
|
||||
// String strIW[] = alipaysms.split(",");
|
||||
// if(strIW.length == 3){
|
||||
// map.put("phoneNumber", strIW[0]); //待发送手机号
|
||||
// map.put("signName", strIW[1]); //短信签名
|
||||
// map.put("templateCode", strIW[2]); //短信模板
|
||||
// }
|
||||
// }
|
||||
//组装请求对象-具体描述见控制台-文档部分内容
|
||||
SendSmsRequest request = new SendSmsRequest();
|
||||
//必填:待发送手机号18630110835
|
||||
request.setPhoneNumbers(sendmap.get("phone").toString());
|
||||
//必填:短信签名-可在短信控制台中找到
|
||||
request.setSignName("秦安双控");
|
||||
//必填:短信模板-可在短信控制台中找到
|
||||
request.setTemplateCode(sendmap.get("templateCode").toString());
|
||||
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
|
||||
// if(sendmap.get("paytype").toString().equals("zfb")){
|
||||
// paytype="支付宝";
|
||||
// }else{
|
||||
// paytype="网银";
|
||||
// }
|
||||
// 遍历参数
|
||||
if(paramsList != null && paramsList.size() > 0) {
|
||||
StringBuffer parStr = new StringBuffer();
|
||||
for(PageData par: paramsList) {
|
||||
par.toString();
|
||||
parStr.append("\""+par.get("name").toString()+"\":"+par.get("value").toString()+", ");
|
||||
}
|
||||
request.setTemplateParam("{"+parStr.substring(0, parStr.length() -2)+"}");
|
||||
} else {
|
||||
request.setTemplateParam("{}");
|
||||
}
|
||||
//request.setTemplateParam("{\"code\":\""+234+"\",\"\code\":\""+234+"\"}");
|
||||
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
|
||||
//request.setSmsUpExtendCode("90997");
|
||||
|
||||
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
|
||||
request.setOutId("yourOutId");
|
||||
|
||||
//hint 此处可能会抛出异常,注意catch
|
||||
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
|
||||
return sendSmsResponse;
|
||||
}
|
||||
|
||||
public static QuerySendDetailsResponse querySendDetails(String bizId) throws ClientException {
|
||||
|
||||
//可自助调整超时时间
|
||||
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
|
||||
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
|
||||
|
||||
//初始化acsClient,暂不支持region化
|
||||
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
|
||||
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
|
||||
IAcsClient acsClient = new DefaultAcsClient(profile);
|
||||
|
||||
//组装请求对象
|
||||
QuerySendDetailsRequest request = new QuerySendDetailsRequest();
|
||||
//必填-号码
|
||||
request.setPhoneNumber("18630363710");
|
||||
//可选-流水号
|
||||
request.setBizId(bizId);
|
||||
//必填-发送日期 支持30天内记录查询,格式yyyyMMdd
|
||||
SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
|
||||
request.setSendDate(ft.format(new Date()));
|
||||
//必填-页大小
|
||||
request.setPageSize(10L);
|
||||
//必填-当前页码从1开始计数
|
||||
request.setCurrentPage(1L);
|
||||
|
||||
//hint 此处可能会抛出异常,注意catch
|
||||
QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
|
||||
|
||||
return querySendDetailsResponse;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* 百度地图工具类
|
||||
*/
|
||||
public class BaiduMapUtil {
|
||||
// 需替换为实际的百度地图AK(从配置中心获取更佳)
|
||||
private static final String BAIDU_AK = "OElqFYoKiAH8KFtph8ftLKF5NlNrbCUr";
|
||||
|
||||
/**
|
||||
* 根据经纬度获取详细地址
|
||||
* @param lng 经度
|
||||
* @param lat 纬度
|
||||
* @param coordtype 坐标系类型(wgs84ll/gcj02等)
|
||||
* @return 格式化地址
|
||||
*/
|
||||
public static String getAddressByLocation(double lng, double lat, String coordtype) throws Exception {
|
||||
String url = String.format(
|
||||
"http://api.map.baidu.com/reverse_geocoding/v3/?ak=%s&output=json&coordtype=%s&location=%s,%s",
|
||||
BAIDU_AK, coordtype, lat, lng); // 注意百度坐标系是纬度在前
|
||||
|
||||
String response = HttpRequestUtil.doGet(url);
|
||||
JSONObject result = JSONObject.parseObject(response);
|
||||
|
||||
if (result.getInteger("status") == 0) {
|
||||
return result.getJSONObject("result")
|
||||
.getString("formatted_address");
|
||||
}
|
||||
throw new RuntimeException("地址解析失败:" + result.getString("message"));
|
||||
}
|
||||
|
||||
// 方法重载(默认使用wgs84坐标系)
|
||||
public static String getAddressByLocation(double lng, double lat) throws Exception {
|
||||
return getAddressByLocation(lng, lat, "wgs84ll");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import org.apache.shiro.codec.Base64;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* BASE64编码解码工具包
|
||||
* </p>
|
||||
*/
|
||||
public class Base64Utils {
|
||||
|
||||
/** */
|
||||
/**
|
||||
* 文件读取缓冲区大小
|
||||
*/
|
||||
private static final int CACHE_SIZE = 1024;
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* BASE64字符串解码为二进制数据
|
||||
* </p>
|
||||
*
|
||||
* @param base64
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decode(String base64) throws Exception {
|
||||
return Base64.decode(base64.getBytes());
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 二进制数据编码为BASE64字符串
|
||||
* </p>
|
||||
*
|
||||
* @param bytes
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encode(byte[] bytes) throws Exception {
|
||||
return new String(Base64.encode(bytes));
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 将文件编码为BASE64字符串
|
||||
* </p>
|
||||
* <p>
|
||||
* 大文件慎用,可能会导致内存溢出
|
||||
* </p>
|
||||
*
|
||||
* @param filePath
|
||||
* 文件绝对路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encodeFile(String filePath) throws Exception {
|
||||
byte[] bytes = fileToByte(filePath);
|
||||
return encode(bytes);
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* BASE64字符串转回文件
|
||||
* </p>
|
||||
*
|
||||
* @param filePath
|
||||
* 文件绝对路径
|
||||
* @param base64
|
||||
* 编码字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void decodeToFile(String filePath, String base64) throws Exception {
|
||||
byte[] bytes = decode(base64);
|
||||
byteArrayToFile(bytes, filePath);
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 文件转换为二进制数组
|
||||
* </p>
|
||||
*
|
||||
* @param filePath
|
||||
* 文件路径
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] fileToByte(String filePath) throws Exception {
|
||||
byte[] data = new byte[0];
|
||||
File file = new File(filePath);
|
||||
if (file.exists()) {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
|
||||
byte[] cache = new byte[CACHE_SIZE];
|
||||
int nRead = 0;
|
||||
while ((nRead = in.read(cache)) != -1) {
|
||||
out.write(cache, 0, nRead);
|
||||
out.flush();
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
data = out.toByteArray();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 二进制数据写文件
|
||||
* </p>
|
||||
*
|
||||
* @param bytes
|
||||
* 二进制数据
|
||||
* @param filePath
|
||||
* 文件生成目录
|
||||
*/
|
||||
public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
|
||||
InputStream in = new ByteArrayInputStream(bytes);
|
||||
File destFile = new File(filePath);
|
||||
if (!destFile.getParentFile().exists()) {
|
||||
destFile.getParentFile().mkdirs();
|
||||
}
|
||||
destFile.createNewFile();
|
||||
OutputStream out = new FileOutputStream(destFile);
|
||||
byte[] cache = new byte[CACHE_SIZE];
|
||||
int nRead = 0;
|
||||
while ((nRead = in.read(cache)) != -1) {
|
||||
out.write(cache, 0, nRead);
|
||||
out.flush();
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CamelCaseUtil {
|
||||
|
||||
public static <V> Map<String, V> camelToUnderline(Map<String, V> sourceMap) {
|
||||
Map<String, V> targetMap = new HashMap<>();
|
||||
for (Map.Entry<String, V> entry : sourceMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String newKey = camelToUnderline(key);
|
||||
targetMap.put(newKey, entry.getValue());
|
||||
}
|
||||
return targetMap;
|
||||
}
|
||||
|
||||
private static String camelToUnderline(String camelCase) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < camelCase.length(); i++) {
|
||||
char c = camelCase.charAt(i);
|
||||
if (Character.isUpperCase(c)) {
|
||||
sb.append("_").append(Character.toLowerCase(c));
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Map<String, String> sourceMap = new HashMap<>();
|
||||
sourceMap.put("helloWorld", "value1");
|
||||
sourceMap.put("exampleKey", "value2");
|
||||
Map<String, String> targetMap = camelToUnderline(sourceMap);
|
||||
System.out.println(targetMap); // 输出: {hello_world=value1, example_key=value2}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
/**
|
||||
* 系统参数相关Key
|
||||
*
|
||||
*/
|
||||
public class ConfigConstant {
|
||||
/**
|
||||
* 云存储配置KEY
|
||||
*/
|
||||
public final static String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY";
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
/**
|
||||
* 说明:常量
|
||||
* 作者:luoxiaobao
|
||||
* 官网:www.qdkjchina.com
|
||||
*/
|
||||
public class Const {
|
||||
|
||||
public static final String SESSION_USER = "SESSION_USER"; //session用的用户
|
||||
public static final String SESSION_USERROL = "SESSION_USERROL"; //用户对象(包含角色信息)
|
||||
public static final String SESSION_ROLE_RIGHTS = "SESSION_ROLE_RIGHTS"; //角色菜单权限
|
||||
public static final String SHIROSET = "SHIROSET"; //菜单权限标识
|
||||
public static final String SESSION_USERNAME = "USERNAME"; //用户名
|
||||
public static final String SESSION_U_NAME = "SESSION_U_NAME"; //用户姓名
|
||||
public static final String SESSION_ROLE = "SESSION_ROLE"; //主职角色信息
|
||||
public static final String SESSION_RNUMBERS = "RNUMBERS"; //角色编码数组
|
||||
public static final String SESSION_ALLMENU = "SESSION_ALLMENU"; //全部菜单
|
||||
public static final String SKIN = "SKIN"; //用户皮肤
|
||||
|
||||
public static final String SYSSET = "config/sysSet.ini"; //系统设置配置文件路径
|
||||
public static final String SYSNAME = "sysName"; //系统名称
|
||||
public static final String SHOWCOUNT = "showCount"; //每页条数
|
||||
|
||||
public static final String FILEPATHFILE = "/uploadFiles/file/"; //文件上传路径
|
||||
public static final String BIFILEPATHFILE = "/uploadFiles/Bfile/"; //文件上传路径
|
||||
public static final String FILEPATHIMG = "/uploadFiles/imgs/"; //图片上传路径
|
||||
public static final String FILEPATHIMGSPECIAL = "/uploadFiles/imgs/special/"; //图片上传路径(特种装备)
|
||||
public static final String FILEPATHDZJM = "/uploadFiles/dzjm/"; //图片上传路径
|
||||
public static final String FILEPATHYHTP = "/uploadFiles/yhtp/"; //图片上传路径
|
||||
public static final String FILEPATHFXSST = "/uploadFiles/fxsst/"; //图片上传路径 风险四色图
|
||||
|
||||
public static final String FILEACTIVITI = "/uploadFiles/activitiFile/"; //工作流生成XML和PNG目录
|
||||
|
||||
public static final String DEPARTMENT_IDS = "DEPARTMENT_IDS"; //当前用户拥有的最高部门权限集合
|
||||
public static final String DEPARTMENT_ID = "DEPARTMENT_ID"; //当前用户拥有的最高部门权限
|
||||
public static final String CORPINFO_ID = "CORPINFO_ID"; //当前用户所属企业
|
||||
public static final String POST_ID = "POST_ID"; //当前用户所属企业
|
||||
public static final String PRECINCT_ID = "PRECINCT_ID"; //当前用户拥有的最高部门权限
|
||||
public static final String USER_ID = "USER_ID"; //当前用户userid
|
||||
public static final String IS_MAIN = "IS_MAIN"; //是否主账号
|
||||
public static final String ISSUPERVISE = "ISSUPERVISE"; //是否监管部门
|
||||
|
||||
|
||||
public static final String FILEURL = "/mnt/qyag/file/"; //文件服务器地址
|
||||
public static final String HTTPFILEURL = "https://qyag.zcloudchina.com/file/"; //文件服务器地址
|
||||
|
||||
|
||||
public final static String APPID = "wx9199de454d31b016";
|
||||
public final static String SECRET = "183cdcac380e1f98f00c793491e27d88";
|
||||
public static final String XCX_MCH_ID = "1607757714";
|
||||
public static final String XCX_KEY = "zhuoyunkeji88888zhuoyunkeji88888";
|
||||
|
||||
public final static String OA_APPID = "wx69f7e25b3760001c";//公众号
|
||||
public final static String OA_SECRET = "087fe91f660300df63d0ef16fd162124";//公众号
|
||||
public static final String CORP_TRAINTYPE = "CORP_TRAINTYPE"; //当前用户所属企业的培训行业类型
|
||||
|
||||
|
||||
public static final String ALI_ACCESSKEY = "LTAI5tK134ZzXPEwykAdpVn2"; // 阿里云视频点播ak
|
||||
public static final String ALI_ACCESSKEY_SECRET = "XCEMY8FG52cXImFMeIiH4tDJ9BIN3N"; //阿里云视频点播sk
|
||||
//public static final String ALI_TEMPLATEGROUPID = "8666384eef7d52b290ba661d5e2684ab"; //阿里云视频转码模板id
|
||||
public static final String ALI_TEMPLATEGROUPID = "eda7780b4706ec92ea47a79b6e6bcad1"; // 阿里云视频转码模板id
|
||||
public static final String ALIYUN_REGIONID = "cn-beijing"; // 点播服务接入地域
|
||||
public static final String ENDPOINT = "vod.cn-beijing.aliyuncs.com";// 访问的域名
|
||||
|
||||
// 试题导入模板地址
|
||||
public static final String QUESTION_EXCEL_URL = "https://file.zcloudchina.com/busTripFile/template/questionExcelTemplate.xls";
|
||||
// 平台课件默认封面地址
|
||||
public static final String COURSEWARE_URL = "https://file.zcloudchina.com/knowledgeFile/template/courseware.png";
|
||||
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.zcloud.common.validator.group.AliyunGroup;
|
||||
import com.zcloud.common.validator.group.QcloudGroup;
|
||||
import com.zcloud.common.validator.group.QiniuGroup;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 常量
|
||||
*/
|
||||
public class Constant {
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
public static final String PAGE = "curPage";
|
||||
/**
|
||||
* 每页显示记录数
|
||||
*/
|
||||
public static final String LIMIT = "limit";
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
public static final String ORDER_FIELD = "sidx";
|
||||
/**
|
||||
* 排序方式
|
||||
*/
|
||||
public static final String ORDER = "order";
|
||||
/**
|
||||
* 升序
|
||||
*/
|
||||
public static final String ASC = "asc";
|
||||
|
||||
/**
|
||||
* 菜单类型
|
||||
*
|
||||
* @author chenshun
|
||||
* @email sunlightcs@gmail.com
|
||||
* @date 2016年11月15日 下午1:24:29
|
||||
*/
|
||||
public enum MenuType {
|
||||
/**
|
||||
* 目录
|
||||
*/
|
||||
CATALOG(0),
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
MENU(1),
|
||||
/**
|
||||
* 按钮
|
||||
*/
|
||||
BUTTON(2);
|
||||
|
||||
private int value;
|
||||
|
||||
MenuType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务状态
|
||||
*
|
||||
* @author chenshun
|
||||
* @email sunlightcs@gmail.com
|
||||
* @date 2016年12月3日 上午12:07:22
|
||||
*/
|
||||
public enum ScheduleStatus {
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
NORMAL(0),
|
||||
/**
|
||||
* 暂停
|
||||
*/
|
||||
PAUSE(1);
|
||||
|
||||
private int value;
|
||||
|
||||
ScheduleStatus(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 云服务商
|
||||
*/
|
||||
public enum CloudService {
|
||||
/**
|
||||
* 七牛云
|
||||
*/
|
||||
QINIU(1, QiniuGroup.class),
|
||||
/**
|
||||
* 阿里云
|
||||
*/
|
||||
ALIYUN(2, AliyunGroup.class),
|
||||
/**
|
||||
* 腾讯云
|
||||
*/
|
||||
QCLOUD(3, QcloudGroup.class);
|
||||
|
||||
private int value;
|
||||
|
||||
private Class<?> validatorGroupClass;
|
||||
|
||||
CloudService(int value, Class<?> validatorGroupClass) {
|
||||
this.value = value;
|
||||
this.validatorGroupClass = validatorGroupClass;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Class<?> getValidatorGroupClass() {
|
||||
return this.validatorGroupClass;
|
||||
}
|
||||
|
||||
public static CloudService getByValue(Integer value) {
|
||||
Optional<CloudService> first = Stream.of(CloudService.values()).filter(cs -> value.equals(cs.value)).findFirst();
|
||||
if (!first.isPresent()) {
|
||||
throw new IllegalArgumentException("非法的枚举值:" + value);
|
||||
}
|
||||
return first.get();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,450 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 说明:日期处理
|
||||
* 作者:luoxiaobao
|
||||
* 官网:www.qdkjchina.com
|
||||
*/
|
||||
public class DateUtil {
|
||||
|
||||
private final static SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
|
||||
private final static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private final static SimpleDateFormat sdfYearMonth = new SimpleDateFormat("yyyy-MM");
|
||||
private final static SimpleDateFormat sdfDays = new SimpleDateFormat("yyyyMMdd");
|
||||
private final static SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");
|
||||
private final static SimpleDateFormat sdfTimes = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
|
||||
private final static SimpleDateFormat sdfDayTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
/**
|
||||
* 获取YYYY格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getSdfTimes() {
|
||||
return sdfTimes.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getYear() {
|
||||
return sdfYear.format(new Date());
|
||||
}
|
||||
|
||||
public static String getYear(Date date) {
|
||||
return sdfYear.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY-MM-DD格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getDay() {
|
||||
return sdfDay.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY-MM格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getYearMonth(Date date) {
|
||||
return sdfYearMonth.format(date);
|
||||
}
|
||||
|
||||
// 获取季度数字
|
||||
public static int getYearQuarter(Date date) {
|
||||
return Integer.parseInt(sdfYearMonth.format(date).substring(5, 7)) / 3 + 1;
|
||||
}
|
||||
|
||||
//获取月份数字
|
||||
public static int getMonth(Date date) {
|
||||
return Integer.parseInt(sdfDay.format(date).substring(5, 7));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYYMMDD格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getDays() {
|
||||
return sdfDays.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取YYYY-MM-DD HH:mm:ss格式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getTime() {
|
||||
return sdfTime.format(new Date());
|
||||
}
|
||||
|
||||
public static String getDayTime() {
|
||||
return sdfDayTime.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s
|
||||
* @param e
|
||||
* @return boolean
|
||||
* @throws
|
||||
* @Title: compareDate
|
||||
* @Description: TODO(日期比较 , 如果s > = e 返回true 否则返回false)
|
||||
* @author fh
|
||||
*/
|
||||
public static boolean compareDate(String s, String e) {
|
||||
if (fomatDate(s) == null || fomatDate(e) == null) {
|
||||
return false;
|
||||
}
|
||||
return fomatDate(s).getTime() >= fomatDate(e).getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Date fomatDate(String date) {
|
||||
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
|
||||
try {
|
||||
return fmt.parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验日期是否合法
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean isValidDate(String s) {
|
||||
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
|
||||
try {
|
||||
fmt.parse(s);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false; // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param startTime
|
||||
* @param endTime
|
||||
* @return
|
||||
*/
|
||||
public static int getDiffYear(String startTime, String endTime) {
|
||||
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
|
||||
try {
|
||||
int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);
|
||||
return years;
|
||||
} catch (Exception e) {
|
||||
return 0; // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <li>功能描述:时间相减得到天数
|
||||
*
|
||||
* @param beginDateStr
|
||||
* @param endDateStr
|
||||
* @return long
|
||||
* @author Administrator
|
||||
*/
|
||||
public static long getDaySub(String beginDateStr, String endDateStr) {
|
||||
long day = 0;
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date beginDate = null;
|
||||
Date endDate = null;
|
||||
try {
|
||||
beginDate = format.parse(beginDateStr);
|
||||
endDate = format.parse(endDateStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
|
||||
//System.out.println("相隔的天数="+day);
|
||||
return day;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到n天之后的日期
|
||||
*
|
||||
* @param days
|
||||
* @return
|
||||
*/
|
||||
public static String getAfterDayDate(String days) {
|
||||
int daysInt = Integer.parseInt(days);
|
||||
Calendar canlendar = Calendar.getInstance(); // java.util包
|
||||
canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
|
||||
Date date = canlendar.getTime();
|
||||
SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String dateStr = sdfd.format(date);
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到n天之后是周几
|
||||
*
|
||||
* @param days
|
||||
* @return
|
||||
*/
|
||||
public static String getAfterDayWeek(String days) {
|
||||
int daysInt = Integer.parseInt(days);
|
||||
Calendar canlendar = Calendar.getInstance(); // java.util包
|
||||
canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
|
||||
Date date = canlendar.getTime();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E");
|
||||
String dateStr = sdf.format(date);
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照yyyy-MM-dd HH:mm:ss的格式,日期转字符串
|
||||
*
|
||||
* @param date
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String date2Str(Date date) {
|
||||
return date2Str(date, "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照yyyy-MM-dd HH:mm:ss的格式,字符串转日期
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static Date str2Date(String date) {
|
||||
if (StringUtils.isNotBlank(date)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
try {
|
||||
return sdf.parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new Date();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 把时间根据时、分、秒转换为时间段
|
||||
*
|
||||
* @param StrDate
|
||||
*/
|
||||
public static String getTimes(String StrDate) {
|
||||
String resultTimes = "";
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date now;
|
||||
try {
|
||||
now = new Date();
|
||||
Date date = df.parse(StrDate);
|
||||
long times = now.getTime() - date.getTime();
|
||||
long day = times / (24 * 60 * 60 * 1000);
|
||||
long hour = (times / (60 * 60 * 1000) - day * 24);
|
||||
long min = ((times / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||
long sec = (times / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
//sb.append("发表于:");
|
||||
if (hour > 0) {
|
||||
sb.append(hour + "小时前");
|
||||
} else if (min > 0) {
|
||||
sb.append(min + "分钟前");
|
||||
} else {
|
||||
sb.append(sec + "秒前");
|
||||
}
|
||||
resultTimes = sb.toString();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return resultTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照参数format的格式,日期转字符串
|
||||
*
|
||||
* @param date
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static String date2Str(Date date, String format) {
|
||||
if (date != null) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
return sdf.format(date);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当年的第一天
|
||||
*
|
||||
* @param year
|
||||
* @return
|
||||
* @author zhangyue
|
||||
*/
|
||||
public static String getCurrYearFirst() {
|
||||
Calendar currCal = Calendar.getInstance();
|
||||
int currentYear = currCal.get(Calendar.YEAR);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.clear();
|
||||
calendar.set(Calendar.YEAR, currentYear);
|
||||
Date currYearFirst = calendar.getTime();
|
||||
return sdfDay.format(currYearFirst);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当年的最后一天
|
||||
*
|
||||
* @param year
|
||||
* @return
|
||||
* @author zhangyue
|
||||
*/
|
||||
public static String getCurrYearLast() {
|
||||
Calendar currCal = Calendar.getInstance();
|
||||
int currentYear = currCal.get(Calendar.YEAR);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.clear();
|
||||
calendar.set(Calendar.YEAR, currentYear);
|
||||
calendar.roll(Calendar.DAY_OF_YEAR, -1);
|
||||
Date currYearLast = calendar.getTime();
|
||||
return sdfDay.format(currYearLast);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前季度第一天
|
||||
*
|
||||
* @return
|
||||
* @author zhangyue
|
||||
*/
|
||||
public static String quarterStart() {
|
||||
Date dBegin = new Date();
|
||||
Calendar calBegin = Calendar.getInstance();
|
||||
calBegin.setTime(dBegin);
|
||||
int remainder = calBegin.get(Calendar.MONTH) % 3;
|
||||
int month = remainder != 0 ? calBegin.get(Calendar.MONTH) - remainder : calBegin.get(Calendar.MONTH);
|
||||
|
||||
calBegin.set(Calendar.MONTH, month);
|
||||
calBegin.set(Calendar.DAY_OF_MONTH, calBegin.getActualMinimum(Calendar.DAY_OF_MONTH));
|
||||
|
||||
calBegin.setTime(calBegin.getTime());
|
||||
return sdfDay.format(calBegin.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前季度最后一天
|
||||
*
|
||||
* @return
|
||||
* @author zhangyue
|
||||
*/
|
||||
public static String quarterEnd() {
|
||||
Date dEnd = new Date();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(dEnd);
|
||||
int remainder = (calendar.get(Calendar.MONTH) + 1) % 3;
|
||||
int month = remainder != 0 ? calendar.get(Calendar.MONTH) + (3 - remainder) : calendar.get(Calendar.MONTH);
|
||||
calendar.set(Calendar.MONTH, month);
|
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
|
||||
calendar.setTime(calendar.getTime());
|
||||
return sdfDay.format(calendar.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本月第一天日期
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getMonthFirstDay() {
|
||||
Calendar thisMonthFirstDateCal = Calendar.getInstance();
|
||||
thisMonthFirstDateCal.set(Calendar.DAY_OF_MONTH, 1);
|
||||
String thisMonthFirstTime = sdfDay.format(thisMonthFirstDateCal.getTime());
|
||||
return thisMonthFirstTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本月最后一天日期
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getMonthEndDay() {
|
||||
Calendar thisMonthEndDateCal = Calendar.getInstance();
|
||||
thisMonthEndDateCal.set(Calendar.DAY_OF_MONTH, thisMonthEndDateCal.getActualMaximum(Calendar.DAY_OF_MONTH));
|
||||
String thisMonthEndTime = sdfDay.format(thisMonthEndDateCal.getTime());
|
||||
return thisMonthEndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断两个日期字符串是否相差半年或半年的倍数。
|
||||
*
|
||||
* @param dateStr1 第一个日期字符串
|
||||
* @param dateStr2 第二个日期字符串
|
||||
* @param formatter 日期格式
|
||||
* @return 如果两个日期相差半年或半年的倍数,返回true,否则返回false。
|
||||
*/
|
||||
public static boolean isHalfYearApart(String dateStr1, String dateStr2, DateTimeFormatter formatter) {
|
||||
LocalDate date1 = LocalDate.parse(dateStr1, formatter);
|
||||
LocalDate date2 = LocalDate.parse(dateStr2, formatter);
|
||||
|
||||
long monthsBetween = ChronoUnit.MONTHS.between(date1, date2);
|
||||
return monthsBetween % 6 == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定一个日期,增加半年。
|
||||
*
|
||||
* @param dateStr 需要增加半年的日期
|
||||
* @param formatter 日期格式
|
||||
* @return 增加半年后的日期
|
||||
*/
|
||||
public static String addHalfYear(String dateStr, DateTimeFormatter formatter) {
|
||||
LocalDate date = LocalDate.parse(dateStr, formatter);
|
||||
LocalDate newDate = date.plus(Period.ofMonths(6));
|
||||
return newDate.format(formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定一个日期,减n个月。
|
||||
*
|
||||
* @param date 需要计算的日期
|
||||
* @param n 月数
|
||||
* @return 增加半年后的日期
|
||||
*/
|
||||
public static Date getLastMonth(Date date,int n) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.add(Calendar.MONTH, -n);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
String dateStr1 = "2023-09-01";
|
||||
String dateStr2 = "2024-03-01";
|
||||
Date newDateStr = getLastMonth(fomatDate(dateStr1), 12);
|
||||
System.out.println(newDateStr);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
|
||||
|
||||
package com.zcloud.common.utils;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日期处理
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DateUtils {
|
||||
/** 时间格式(yyyy-MM-dd) */
|
||||
public final static String DATE_PATTERN = "yyyy-MM-dd";
|
||||
/** 时间格式(yyyy-MM-dd HH:mm:ss) */
|
||||
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 日期格式化 日期格式为:yyyy-MM-dd
|
||||
* @param date 日期
|
||||
* @return 返回yyyy-MM-dd格式日期
|
||||
*/
|
||||
public static String format(Date date) {
|
||||
return format(date, DATE_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期格式化 日期格式为:yyyy-MM-dd
|
||||
* @param date 日期
|
||||
* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN
|
||||
* @return 返回yyyy-MM-dd格式日期
|
||||
*/
|
||||
public static String format(Date date, String pattern) {
|
||||
if(date != null){
|
||||
SimpleDateFormat df = new SimpleDateFormat(pattern);
|
||||
return df.format(date);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转换成日期
|
||||
* @param strDate 日期字符串
|
||||
* @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN
|
||||
*/
|
||||
public static Date stringToDate(String strDate, String pattern) {
|
||||
if (StringUtils.isBlank(strDate)){
|
||||
return null;
|
||||
}
|
||||
|
||||
DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);
|
||||
return fmt.parseLocalDateTime(strDate).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据周数,获取开始日期、结束日期
|
||||
* @param week 周期 0本周,-1上周,-2上上周,1下周,2下下周
|
||||
* @return 返回date[0]开始日期、date[1]结束日期
|
||||
*/
|
||||
public static Date[] getWeekStartAndEnd(int week) {
|
||||
DateTime dateTime = new DateTime();
|
||||
LocalDate date = new LocalDate(dateTime.plusWeeks(week));
|
||||
|
||||
date = date.dayOfWeek().withMinimumValue();
|
||||
Date beginDate = date.toDate();
|
||||
Date endDate = date.plusDays(6).toDate();
|
||||
return new Date[]{beginDate, endDate};
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【秒】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param seconds 秒数,负数为减
|
||||
* @return 加/减几秒后的日期
|
||||
*/
|
||||
public static Date addDateSeconds(Date date, int seconds) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusSeconds(seconds).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【分钟】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param minutes 分钟数,负数为减
|
||||
* @return 加/减几分钟后的日期
|
||||
*/
|
||||
public static Date addDateMinutes(Date date, int minutes) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusMinutes(minutes).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【小时】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param hours 小时数,负数为减
|
||||
* @return 加/减几小时后的日期
|
||||
*/
|
||||
public static Date addDateHours(Date date, int hours) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusHours(hours).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【天】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param days 天数,负数为减
|
||||
* @return 加/减几天后的日期
|
||||
*/
|
||||
public static Date addDateDays(Date date, int days) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusDays(days).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【周】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param weeks 周数,负数为减
|
||||
* @return 加/减几周后的日期
|
||||
*/
|
||||
public static Date addDateWeeks(Date date, int weeks) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusWeeks(weeks).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【月】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param months 月数,负数为减
|
||||
* @return 加/减几月后的日期
|
||||
*/
|
||||
public static Date addDateMonths(Date date, int months) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusMonths(months).toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对日期的【年】进行加/减
|
||||
*
|
||||
* @param date 日期
|
||||
* @param years 年数,负数为减
|
||||
* @return 加/减几年后的日期
|
||||
*/
|
||||
public static Date addDateYears(Date date, int years) {
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.plusYears(years).toDate();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* 说明:上传文件
|
||||
|
||||
|
||||
*/
|
||||
public class FileUpload {
|
||||
|
||||
/**上传文件
|
||||
* @param file //文件对象
|
||||
* @param filePath //上传路径
|
||||
* @param fileName //文件名
|
||||
* @return 文件名
|
||||
*/
|
||||
public static String fileUp(MultipartFile file, String filePath, String fileName){
|
||||
String extName = ""; // 扩展名格式:
|
||||
try {
|
||||
if (file.getOriginalFilename().lastIndexOf(".") >= 0){
|
||||
extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
}
|
||||
copyFile(file.getInputStream(), filePath, fileName+extName).replaceAll("-", "");
|
||||
} catch (IOException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
return fileName+extName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写文件到当前目录的upload目录中
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String copyFile(InputStream in, String dir, String realName)
|
||||
throws IOException {
|
||||
File file = mkdirsmy(dir,realName);
|
||||
FileUtils.copyInputStreamToFile(in, file);
|
||||
in.close();
|
||||
return realName;
|
||||
}
|
||||
|
||||
|
||||
/**判断路径是否存在,否:创建此路径
|
||||
* @param dir 文件路径
|
||||
* @param realName 文件名
|
||||
* @throws IOException
|
||||
*/
|
||||
public static File mkdirsmy(String dir, String realName) throws IOException{
|
||||
File file = new File(dir, realName);
|
||||
if (!file.exists()) {
|
||||
if (!file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
file.createNewFile();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
/**下载网络图片上传到服务器上
|
||||
* @param httpUrl 图片网络地址
|
||||
* @param filePath 图片保存路径
|
||||
* @param myFileName 图片文件名(null时用网络图片原名)
|
||||
* @return 返回图片名称
|
||||
*/
|
||||
public static String getHtmlPicture(String httpUrl, String filePath , String myFileName) {
|
||||
|
||||
URL url; //定义URL对象url
|
||||
BufferedInputStream in; //定义输入字节缓冲流对象in
|
||||
FileOutputStream file; //定义文件输出流对象file
|
||||
try {
|
||||
String fileName = null == myFileName?httpUrl.substring(httpUrl.lastIndexOf("/")).replace("/", ""):myFileName; //图片文件名(null时用网络图片原名)
|
||||
url = new URL(httpUrl); //初始化url对象
|
||||
in = new BufferedInputStream(url.openStream()); //初始化in对象,也就是获得url字节流
|
||||
//file = new FileOutputStream(new File(filePath +"\\"+ fileName));
|
||||
file = new FileOutputStream(mkdirsmy(filePath,fileName));
|
||||
int t;
|
||||
while ((t = in.read()) != -1) {
|
||||
file.write(t);
|
||||
}
|
||||
file.close();
|
||||
in.close();
|
||||
return fileName;
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.aliyun.oss.ClientException;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.OSSException;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
@Component
|
||||
public class FileUploadUtil {
|
||||
|
||||
private static String endpoint = "https://oss-cn-zhangjiakou.aliyuncs.com";
|
||||
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
|
||||
private static String accessKeyId = "LTAI5tK134ZzXPEwykAdpVn2";
|
||||
private static String accessKeySecret = "XCEMY8FG52cXImFMeIiH4tDJ9BIN3N";
|
||||
// 填写Bucket名称。
|
||||
private static String bucketName = "qyag";
|
||||
|
||||
public static void sshSftp(MultipartFile file, String fileName, String path){
|
||||
String objectName = "qaMineFile" + path + "/" + fileName;
|
||||
// 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
|
||||
// 创建OSSClient实例。
|
||||
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||
|
||||
try {
|
||||
|
||||
// 创建PutObject请求。
|
||||
ossClient.putObject(bucketName, objectName, file.getInputStream());
|
||||
|
||||
// 创建PutObjectRequest对象。
|
||||
// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
|
||||
// ObjectMetadata metadata = new ObjectMetadata();
|
||||
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
|
||||
// metadata.setObjectAcl(CannedAccessControlList.Private);
|
||||
// putObjectRequest.setMetadata(metadata);
|
||||
|
||||
// 上传文件。
|
||||
} catch (OSSException oe) {
|
||||
System.out.println("Caught an OSSException, which means your request made it to OSS, "
|
||||
+ "but was rejected with an error response for some reason.");
|
||||
System.out.println("Error Message:" + oe.getErrorMessage());
|
||||
System.out.println("Error Code:" + oe.getErrorCode());
|
||||
System.out.println("Request ID:" + oe.getRequestId());
|
||||
System.out.println("Host ID:" + oe.getHostId());
|
||||
} catch (ClientException ce) {
|
||||
System.out.println("Caught an ClientException, which means the client encountered "
|
||||
+ "a serious internal problem while trying to communicate with OSS, "
|
||||
+ "such as not being able to access the network.");
|
||||
System.out.println("Error Message:" + ce.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error Message:" + e.getMessage());
|
||||
} finally {
|
||||
if (ossClient != null) {
|
||||
ossClient.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*/
|
||||
public static void deleteFile(String directoryFile) {
|
||||
|
||||
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
|
||||
|
||||
try {
|
||||
// 删除文件或目录。如果要删除目录,目录必须为空。
|
||||
ossClient.deleteObject(bucketName, "busTripFile" + directoryFile);
|
||||
} catch (OSSException oe) {
|
||||
System.out.println("Caught an OSSException, which means your request made it to OSS, "
|
||||
+ "but was rejected with an error response for some reason.");
|
||||
System.out.println("Error Message:" + oe.getErrorMessage());
|
||||
System.out.println("Error Code:" + oe.getErrorCode());
|
||||
System.out.println("Request ID:" + oe.getRequestId());
|
||||
System.out.println("Host ID:" + oe.getHostId());
|
||||
} catch (ClientException ce) {
|
||||
System.out.println("Caught an ClientException, which means the client encountered "
|
||||
+ "a serious internal problem while trying to communicate with OSS, "
|
||||
+ "such as not being able to access the network.");
|
||||
System.out.println("Error Message:" + ce.getMessage());
|
||||
} finally {
|
||||
if (ossClient != null) {
|
||||
ossClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class HttpContextUtils {
|
||||
|
||||
public static HttpServletRequest getHttpServletRequest() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
}
|
||||
|
||||
public static String getDomain(){
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
StringBuffer url = request.getRequestURL();
|
||||
return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
|
||||
}
|
||||
|
||||
public static String getOrigin(){
|
||||
HttpServletRequest request = getHttpServletRequest();
|
||||
return request.getHeader("Origin");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
/**
|
||||
* description: http请求工具类
|
||||
*
|
||||
* @date 2022-07-01
|
||||
*/
|
||||
public class HttpRequestUtil {
|
||||
|
||||
public static String sendRequest(String urlParam) throws Exception {
|
||||
InputStream inputStream = null;
|
||||
BufferedReader buffer = null;
|
||||
try {
|
||||
URL url = new URL(urlParam);
|
||||
URLConnection con = url.openConnection();
|
||||
//设置请求需要返回的数据类型和字符集类型
|
||||
con.setRequestProperty("Content-Type", "application/json;charset=GBK");
|
||||
//允许写出
|
||||
con.setDoOutput(true);
|
||||
//允许读入
|
||||
con.setDoInput(true);
|
||||
//不使用缓存
|
||||
con.setUseCaches(false);
|
||||
//得到响应流
|
||||
inputStream = con.getInputStream();
|
||||
//将响应流转换成字符串
|
||||
StringBuffer resultBuffer = new StringBuffer();
|
||||
String line;
|
||||
buffer = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
|
||||
while ((line = buffer.readLine()) != null) {
|
||||
resultBuffer.append(line);
|
||||
}
|
||||
return resultBuffer.toString();
|
||||
} catch (Exception e) {
|
||||
buffer.close();
|
||||
inputStream.close();
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getRestInformation(HttpServletRequest request) throws Exception {
|
||||
return getRestInformation(request,String.class);
|
||||
}
|
||||
|
||||
public static <T> T getRestInformation(HttpServletRequest request, Class<T> clazz) throws Exception {
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
|
||||
StringBuffer data = new StringBuffer();
|
||||
String line = null;
|
||||
reader = request.getReader();
|
||||
while (null != (line = reader.readLine())) data.append(line);
|
||||
reader.close();
|
||||
T result = JSONObject.parseObject(data.toString(), clazz);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("解析请求报文出错");
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Http get请求
|
||||
* @param httpUrl 连接
|
||||
* @return 响应数据
|
||||
*/
|
||||
public static String doGet(String httpUrl) throws Exception{
|
||||
//链接
|
||||
HttpURLConnection connection = null;
|
||||
InputStream is = null;
|
||||
BufferedReader br = null;
|
||||
StringBuffer result = new StringBuffer();
|
||||
try {
|
||||
//创建连接
|
||||
URL url = new URL(httpUrl);
|
||||
connection = (HttpURLConnection) url.openConnection();
|
||||
//设置请求方式
|
||||
connection.setRequestMethod("GET");
|
||||
//设置连接超时时间
|
||||
connection.setReadTimeout(15000);
|
||||
//开始连接
|
||||
connection.connect();
|
||||
//获取响应数据
|
||||
if (connection.getResponseCode() == 200) {
|
||||
//获取返回的数据
|
||||
is = connection.getInputStream();
|
||||
if (null != is) {
|
||||
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
|
||||
String temp = null;
|
||||
while (null != (temp = br.readLine())) {
|
||||
result.append(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (null != br) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (null != is) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭远程连接
|
||||
connection.disconnect();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Http post请求
|
||||
* @param httpUrl 连接
|
||||
* @param param 参数
|
||||
* @return
|
||||
*/
|
||||
public static String doPost(String httpUrl, @Nullable String param) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
//连接
|
||||
HttpURLConnection connection = null;
|
||||
OutputStream os = null;
|
||||
InputStream is = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
//创建连接对象
|
||||
URL url = new URL(httpUrl);
|
||||
//创建连接
|
||||
connection = (HttpURLConnection) url.openConnection();
|
||||
//设置请求方法
|
||||
connection.setRequestMethod("POST");
|
||||
//设置连接超时时间
|
||||
connection.setConnectTimeout(15000);
|
||||
//设置读取超时时间
|
||||
connection.setReadTimeout(15000);
|
||||
//DoOutput设置是否向httpUrlConnection输出,DoInput设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个
|
||||
//设置是否可读取
|
||||
connection.setDoOutput(true);
|
||||
connection.setDoInput(true);
|
||||
//设置通用的请求属性
|
||||
// connection.setRequestProperty("accept", "*/*");
|
||||
// connection.setRequestProperty("connection", "Keep-Alive");
|
||||
// connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
|
||||
connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
|
||||
System.out.println(param);
|
||||
//拼装参数
|
||||
if (null != param && !param.equals("")) {
|
||||
//设置参数
|
||||
os = connection.getOutputStream();
|
||||
//拼装参数
|
||||
os.write(param.getBytes());
|
||||
}
|
||||
//设置权限
|
||||
//设置请求头等
|
||||
//开启连接
|
||||
//connection.connect();
|
||||
//读取响应
|
||||
if (connection.getResponseCode() == 200) {
|
||||
is = connection.getInputStream();
|
||||
if (null != is) {
|
||||
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
|
||||
String temp = null;
|
||||
while (null != (temp = br.readLine())) {
|
||||
result.append(temp);
|
||||
result.append("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
//关闭连接
|
||||
if(br!=null){
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(os!=null){
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(is!=null){
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//关闭连接
|
||||
connection.disconnect();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
|
||||
package com.zcloud.common.utils;
|
||||
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
*
|
||||
*
|
||||
*/
|
||||
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) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (StringUtils.isEmpty(ip) || "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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* 说明:MD5处理
|
||||
|
||||
|
||||
*/
|
||||
public class MD5 {
|
||||
|
||||
public static String md5(String str) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(str.getBytes());
|
||||
byte b[] = md.digest();
|
||||
|
||||
int i;
|
||||
|
||||
StringBuffer buf = new StringBuffer("");
|
||||
for (int offset = 0; offset < b.length; offset++) {
|
||||
i = b[offset];
|
||||
if (i < 0)
|
||||
i += 256;
|
||||
if (i < 16)
|
||||
buf.append("0");
|
||||
buf.append(Integer.toHexString(i));
|
||||
}
|
||||
str = buf.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
return str;
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
System.out.println(md5("313596790@qq.com"+"123456"));
|
||||
System.out.println(md5("mj1"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import ws.schild.jave.MultimediaInfo;
|
||||
import ws.schild.jave.MultimediaObject;
|
||||
import ws.schild.jave.VideoInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* @author fangjiakai
|
||||
* @date 2023/10/20 10:10
|
||||
*/
|
||||
public class MP4Util {
|
||||
public static String getMP4Time(File video) {
|
||||
// 视频时长
|
||||
String time = "0";
|
||||
try {
|
||||
MultimediaObject media = new MultimediaObject(video);
|
||||
MultimediaInfo info = media.getInfo();
|
||||
// 时长,毫秒级
|
||||
long duration = info.getDuration();
|
||||
// 毫秒级时长转化为秒
|
||||
BigDecimal bigDecimal1 = new BigDecimal(duration);
|
||||
BigDecimal bigDecimal2 = new BigDecimal(1000);
|
||||
// 四舍五入,只保留整数
|
||||
time = bigDecimal1.divide(bigDecimal2, 0, RoundingMode.HALF_UP).toString();
|
||||
// // 获取媒体视频对象
|
||||
// VideoInfo video = info.getVideo();
|
||||
// // 码率
|
||||
// int bitRate = video.getBitRate();
|
||||
// // 帧率
|
||||
// float frameRate = video.getFrameRate();
|
||||
// // 分辨率-高
|
||||
// int height = video.getSize().getHeight();
|
||||
// // 分辨率-宽
|
||||
// int width = video.getSize().getWidth();
|
||||
// // 视频解码器名称
|
||||
// String decoder = video.getDecoder();
|
||||
} catch (Exception e) {
|
||||
e.getMessage();
|
||||
}
|
||||
return time;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
|
||||
package com.zcloud.common.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* Map工具类
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class MapUtils extends HashMap<String, Object> {
|
||||
|
||||
@Override
|
||||
public MapUtils put(String key, Object value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.zcloud.modules.sys.entity.PageData;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 说明:从EXCEL导入到系统
|
||||
*/
|
||||
public class ObjectExcelRead {
|
||||
|
||||
/**
|
||||
* @param filepath //文件路径
|
||||
* @param filename //文件名
|
||||
* @param startrow //开始行号
|
||||
* @param startcol //开始列号
|
||||
* @param sheetnum //sheet
|
||||
* @return list
|
||||
*/
|
||||
public static List<Object> readExcel(String filepath, String filename, int startrow, int startcol, int sheetnum) {
|
||||
List<Object> varList = new ArrayList<Object>();
|
||||
|
||||
try {
|
||||
File target = new File(filepath, filename);
|
||||
FileInputStream fi = new FileInputStream(target);
|
||||
HSSFWorkbook wb = new HSSFWorkbook(fi);
|
||||
HSSFSheet sheet = wb.getSheetAt(sheetnum); //sheet 从0开始
|
||||
int rowNum = sheet.getLastRowNum() + 1; //取得最后一行的行号
|
||||
|
||||
for (int i = startrow; i < rowNum; i++) { //行循环开始
|
||||
|
||||
PageData varpd = new PageData();
|
||||
HSSFRow row = sheet.getRow(i); //行
|
||||
int cellNum = row.getLastCellNum(); //每行的最后一个单元格位置
|
||||
|
||||
for (int j = startcol; j < cellNum; j++) { //列循环开始
|
||||
|
||||
HSSFCell cell = row.getCell(Short.parseShort(j + ""));
|
||||
if (cell != null) {
|
||||
varpd.put("var" + j, cell.toString());
|
||||
}
|
||||
|
||||
}
|
||||
varList.add(varpd);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
|
||||
return varList;
|
||||
}
|
||||
|
||||
|
||||
public static List<Map<Integer, String>> readExcel(MultipartFile file, int startrow, int startcol, int sheetnum) throws Exception {
|
||||
List<Map<Integer, String>> dataList = new ArrayList<>();
|
||||
try (InputStream inputStream = file.getInputStream()) {
|
||||
Workbook workbook = WorkbookFactory.create(inputStream);
|
||||
Sheet sheet = workbook.getSheetAt(sheetnum); // 取第一个sheet
|
||||
|
||||
for (int i = startrow; i < sheet.getPhysicalNumberOfRows(); i++) {
|
||||
Row row = sheet.getRow(i);
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
Map<Integer, String> rowData = new HashMap<>();
|
||||
for (int j = startcol; j < row.getPhysicalNumberOfCells(); j++) {
|
||||
Cell cell = row.getCell(j);
|
||||
String cellValue = getCellValueAsString(cell);
|
||||
rowData.put(j, cellValue);
|
||||
}
|
||||
dataList.add(rowData);
|
||||
}
|
||||
}
|
||||
return dataList;
|
||||
}
|
||||
|
||||
private static String getCellValueAsString(Cell cell) {
|
||||
if (cell == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
switch (cell.getCellType()) {
|
||||
case STRING:
|
||||
return cell.getStringCellValue();
|
||||
case NUMERIC:
|
||||
return String.valueOf((int) cell.getNumericCellValue());
|
||||
case BOOLEAN:
|
||||
return String.valueOf(cell.getBooleanCellValue());
|
||||
case FORMULA:
|
||||
return cell.getCellFormula();
|
||||
case BLANK:
|
||||
return "";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出数据为 Excel 格式
|
||||
*/
|
||||
public static ResponseEntity<byte[]> exportToExcelForImport(List<String> headerFileds, List<List<String>> data, String outputFileName) throws IOException {
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet();
|
||||
|
||||
// // 创建表头
|
||||
Row headerRow = sheet.createRow(0);
|
||||
for (int i = 0; i < headerFileds.size(); i++) {
|
||||
Cell cell = headerRow.createCell(i);
|
||||
cell.setCellValue(headerFileds.get(i));
|
||||
}
|
||||
|
||||
// 填充数据行
|
||||
int rowNum = 1;
|
||||
for (List<String> rowData : data) {
|
||||
Row dataRow = sheet.createRow(rowNum++);
|
||||
for (int i = 0; i < rowData.size(); i++) {
|
||||
Cell cell = dataRow.createCell(i);
|
||||
cell.setCellValue(rowData.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
// 自动调整列宽
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
sheet.autoSizeColumn(i);
|
||||
}
|
||||
|
||||
// 将工作簿写入字节数组
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
workbook.write(byteArrayOutputStream);
|
||||
workbook.close();
|
||||
|
||||
// 构建响应头
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
headers.setContentDispositionFormData("attachment", outputFileName);
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.headers(headers)
|
||||
.body(byteArrayOutputStream.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
|
||||
|
||||
package com.zcloud.common.utils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页工具类
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class PageUtils implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 总记录数
|
||||
*/
|
||||
private int totalCount;
|
||||
/**
|
||||
* 每页记录数
|
||||
*/
|
||||
private int pageSize;
|
||||
/**
|
||||
* 总页数
|
||||
*/
|
||||
private int totalPage;
|
||||
/**
|
||||
* 当前页数
|
||||
*/
|
||||
private int currPage;
|
||||
/**
|
||||
* 列表数据
|
||||
*/
|
||||
private List<?> list;
|
||||
|
||||
/**
|
||||
* 分页
|
||||
* @param list 列表数据
|
||||
* @param totalCount 总记录数
|
||||
* @param pageSize 每页记录数
|
||||
* @param currPage 当前页数
|
||||
*/
|
||||
public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
|
||||
this.list = list;
|
||||
this.totalCount = totalCount;
|
||||
this.pageSize = pageSize;
|
||||
this.currPage = currPage;
|
||||
this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
public PageUtils(IPage<?> page) {
|
||||
this.list = page.getRecords();
|
||||
this.totalCount = (int)page.getTotal();
|
||||
this.pageSize = (int)page.getSize();
|
||||
this.currPage = (int)page.getCurrent();
|
||||
this.totalPage = (int)page.getPages();
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
public void setTotalCount(int totalCount) {
|
||||
this.totalCount = totalCount;
|
||||
}
|
||||
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setPageSize(int pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
public int getTotalPage() {
|
||||
return totalPage;
|
||||
}
|
||||
|
||||
public void setTotalPage(int totalPage) {
|
||||
this.totalPage = totalPage;
|
||||
}
|
||||
|
||||
public int getCurrPage() {
|
||||
return currPage;
|
||||
}
|
||||
|
||||
public void setCurrPage(int currPage) {
|
||||
this.currPage = currPage;
|
||||
}
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 说明:路径工具类
|
||||
|
||||
|
||||
*/
|
||||
public class PathUtil {
|
||||
|
||||
/**获取Projectpath
|
||||
* @return
|
||||
*/
|
||||
public static String getProjectpath(){
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
String path = request.getServletContext().getRealPath("/").replaceAll("%20", " ").replaceAll("file:/", "").trim();
|
||||
return path;
|
||||
}
|
||||
|
||||
/**获取Classpath
|
||||
* @return
|
||||
*/
|
||||
public static String getClasspath(){
|
||||
String path = (String.valueOf(Thread.currentThread().getContextClassLoader().getResource(""))).replaceAll("file:/", "").replaceAll("%20", " ").trim();
|
||||
if(path.indexOf(":") != 1){
|
||||
path = File.separator + path;
|
||||
|
||||
}
|
||||
//path = "H:\\"; //当项目以jar、war包运行时,路径改成实际硬盘位置
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.zcloud.common.xss.SQLFilter;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 查询参数
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class Query<T> {
|
||||
|
||||
public IPage<T> getPage(Map<String, Object> params) {
|
||||
return this.getPage(params, null, false);
|
||||
}
|
||||
|
||||
public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
|
||||
//分页参数
|
||||
long curPage = 1;
|
||||
long limit = 10;
|
||||
|
||||
if(params.get(Constant.PAGE) != null){
|
||||
curPage = Long.parseLong(params.get(Constant.PAGE).toString());
|
||||
}
|
||||
if(params.get(Constant.LIMIT) != null){
|
||||
limit = Long.parseLong(params.get(Constant.LIMIT).toString());
|
||||
}
|
||||
|
||||
//分页对象
|
||||
Page<T> page = new Page<>(curPage, limit);
|
||||
|
||||
//分页参数
|
||||
params.put(Constant.PAGE, page);
|
||||
|
||||
//排序字段
|
||||
//防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
|
||||
String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
|
||||
String order = (String)params.get(Constant.ORDER);
|
||||
|
||||
|
||||
//前端字段排序
|
||||
if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
|
||||
if(Constant.ASC.equalsIgnoreCase(order)) {
|
||||
return page.addOrder(OrderItem.asc(orderField));
|
||||
}else {
|
||||
return page.addOrder(OrderItem.desc(orderField));
|
||||
}
|
||||
}
|
||||
|
||||
//没有排序字段,则不排序
|
||||
if(StringUtils.isBlank(defaultOrderField)){
|
||||
return page;
|
||||
}
|
||||
|
||||
//默认排序
|
||||
if(isAsc) {
|
||||
page.addOrder(OrderItem.asc(defaultOrderField));
|
||||
}else {
|
||||
page.addOrder(OrderItem.desc(defaultOrderField));
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
|
||||
package com.zcloud.common.utils;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 返回数据
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class R extends HashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public R() {
|
||||
put("code", 200);
|
||||
put("result", "success");
|
||||
}
|
||||
|
||||
public static R error() {
|
||||
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
|
||||
}
|
||||
|
||||
public static R error(String msg) {
|
||||
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
|
||||
}
|
||||
|
||||
public static R error(int code, String msg) {
|
||||
R r = new R();
|
||||
r.put("code", code);
|
||||
r.put("result", "failed");
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok(String msg) {
|
||||
R r = new R();
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok(Map<String, Object> map) {
|
||||
R r = new R();
|
||||
r.putAll(map);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok() {
|
||||
return new R();
|
||||
}
|
||||
|
||||
public R put(String key, Object value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,404 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* RSA公钥/私钥/签名工具包
|
||||
* <p>
|
||||
* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
|
||||
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
|
||||
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
|
||||
* </p>
|
||||
*
|
||||
*/
|
||||
public class RSAUtils {
|
||||
|
||||
/** */
|
||||
/**
|
||||
* 加密算法RSA
|
||||
*/
|
||||
public static final String KEY_ALGORITHM = "RSA";
|
||||
|
||||
/** */
|
||||
/**
|
||||
* 签名算法
|
||||
*/
|
||||
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
|
||||
|
||||
/** */
|
||||
/**
|
||||
* 获取公钥的key
|
||||
*/
|
||||
private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUoHAavCikaZxjlDM6Km8cX+ye78F4oF39AcEfnE1p2Yn9pJ9WFxYZ4Vkh6F8SKMi7k4nYsKceqB1RwG996SvHQ5C3pM3nbXCP4K15ad6QhN4a7lzlbLhiJcyIKszvvK8ncUDw8mVQ0j/2mwxv05yH6LN9OKU6Hzm1ninpWeE+awIDAQAB\n";
|
||||
|
||||
/** */
|
||||
/**
|
||||
* 获取私钥的key
|
||||
*/
|
||||
private static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANSgcBq8KKRpnGOUMzoqbxxf7J7vwXigXf0BwR+cTWnZif2kn1YXFhnhWSHoXxIoyLuTidiwpx6oHVHAb33pK8dDkLekzedtcI/grXlp3pCE3hruXOVsuGIlzIgqzO+8rydxQPDyZVDSP/abDG/TnIfos304pTofObWeKelZ4T5rAgMBAAECgYEAt2Dvjn885h+Xm2JTlBTI40Xvw1uwFqLorK54qxSYx3OwySrTqOIcU5HA17ebVwQJq40hU9t3Jr+DGeDHx2X0NEJ0LXuDMzeWxUwUMbdxxM7OXS6Zuhy73C99DyAweLP9K1H2J/y1+eJ4Zx/0mTiAgCKJFNWAQBZwGl5Zu2zoHOECQQDw0UlrOUfloxK3hfVSWlfL7+onP+z/qa9bzemSg676sAJqA8d5ao8V532OBOtZxfPSlh4igC0lpY2vnCRHrwJZAkEA4ggpMS4o+rfFmNslNzI0m3VFDiLYmghYIqTLHtLYqAbY8QVfFd8bl920t5LQAlTsI3q9Spsu8y7AnAWmYydGYwJAN+tBMya/7TDqvbbbel4EGRUCuE59x/gtAhJUdHMjhI6uYNOz1BvMUffJDdtSkywGLBYztSsyUJWayvZk7khTMQJAALM7xW46LESjdQzAucILDaw4UYnkF94Mv9a41lia2TJkO6Ljn4K4aCkEpUjsIgW3UYjQy0ldxN0RNaqC0G3PtwJAFafiLzcls6qzyAlh5PqM5cJrs+Xa0rHR322/AlSyuxW6wRzUX/zSoorP34JCjRPT5DzUeHMVvr6S2BE8k/8XYg==";
|
||||
|
||||
/** */
|
||||
/**
|
||||
* RSA最大加密明文大小
|
||||
*/
|
||||
private static final int MAX_ENCRYPT_BLOCK = 117;
|
||||
|
||||
/** */
|
||||
/**
|
||||
* RSA最大解密密文大小
|
||||
*/
|
||||
private static final int MAX_DECRYPT_BLOCK = 128;
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 生成密钥对(公钥和私钥)
|
||||
* </p>
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Map<String, Object> genKeyPair() throws Exception {
|
||||
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
|
||||
keyPairGen.initialize(1024);
|
||||
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
Map<String, Object> keyMap = new HashMap<String, Object>(2);
|
||||
keyMap.put(PUBLIC_KEY, publicKey);
|
||||
keyMap.put(PRIVATE_KEY, privateKey);
|
||||
return keyMap;
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 用私钥对信息生成数字签名
|
||||
* </p>
|
||||
*
|
||||
* @param data
|
||||
* 已加密数据
|
||||
* @param privateKey
|
||||
* 私钥(BASE64编码)
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String sign(byte[] data, String privateKey) throws Exception {
|
||||
byte[] keyBytes = Base64Utils.decode(privateKey);
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||
signature.initSign(privateK);
|
||||
signature.update(data);
|
||||
return Base64Utils.encode(signature.sign());
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 校验数字签名
|
||||
* </p>
|
||||
*
|
||||
* @param data
|
||||
* 已加密数据
|
||||
* @param publicKey
|
||||
* 公钥(BASE64编码)
|
||||
* @param sign
|
||||
* 数字签名
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*
|
||||
*/
|
||||
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
|
||||
byte[] keyBytes = Base64Utils.decode(publicKey);
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
PublicKey publicK = keyFactory.generatePublic(keySpec);
|
||||
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||
signature.initVerify(publicK);
|
||||
signature.update(data);
|
||||
return signature.verify(Base64Utils.decode(sign));
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <P>
|
||||
* 私钥解密
|
||||
* </p>
|
||||
*
|
||||
* @param encryptedData
|
||||
* 已加密数据
|
||||
* @param privateKey
|
||||
* 私钥(BASE64编码)
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
|
||||
byte[] keyBytes = Base64Utils.decode(privateKey);
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateK);
|
||||
int inputLen = encryptedData.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 公钥解密
|
||||
* </p>
|
||||
*
|
||||
* @param encryptedData
|
||||
* 已加密数据
|
||||
* @param publicKey
|
||||
* 公钥(BASE64编码)
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
|
||||
byte[] keyBytes = Base64Utils.decode(publicKey);
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicK);
|
||||
int inputLen = encryptedData.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 公钥加密
|
||||
* </p>
|
||||
*
|
||||
* @param data
|
||||
* 源数据
|
||||
* @param publicKey
|
||||
* 公钥(BASE64编码)
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
|
||||
byte[] keyBytes = Base64Utils.decode(publicKey);
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||||
// 对数据加密
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicK);
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段加密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
byte[] encryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 私钥加密
|
||||
* </p>
|
||||
*
|
||||
* @param data
|
||||
* 源数据
|
||||
* @param privateKey
|
||||
* 私钥(BASE64编码)
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
|
||||
byte[] keyBytes = Base64Utils.decode(privateKey);
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateK);
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段加密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
byte[] encryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 获取私钥
|
||||
* </p>
|
||||
*
|
||||
* @param keyMap
|
||||
* 密钥对
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
|
||||
Key key = (Key) keyMap.get(PRIVATE_KEY);
|
||||
return Base64Utils.encode(key.getEncoded());
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 获取私钥
|
||||
* </p>
|
||||
*
|
||||
* @param keyMap
|
||||
* 密钥对
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPrivateKey() {
|
||||
return PRIVATE_KEY;
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 获取公钥
|
||||
* </p>
|
||||
*
|
||||
* @param keyMap
|
||||
* 密钥对
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
|
||||
Key key = (Key) keyMap.get(PUBLIC_KEY);
|
||||
return Base64Utils.encode(key.getEncoded());
|
||||
}
|
||||
|
||||
/** */
|
||||
/**
|
||||
* <p>
|
||||
* 获取公钥
|
||||
* </p>
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPublicKey() throws Exception {
|
||||
return PUBLIC_KEY;
|
||||
}
|
||||
|
||||
/**
|
||||
* java端公钥加密
|
||||
*/
|
||||
public static String encryptedDataOnJava(String data, String PUBLICKEY) {
|
||||
try {
|
||||
data = Base64Utils.encode(encryptByPublicKey(data.getBytes(), PUBLICKEY));
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* java端私钥解密
|
||||
*/
|
||||
public static String decryptDataOnJava(String data, String PRIVATEKEY) {
|
||||
String temp = "";
|
||||
try {
|
||||
byte[] rs = Base64Utils.decode(data);
|
||||
temp = new String(RSAUtils.decryptByPrivateKey(rs, PRIVATEKEY),"UTF-8"); //以utf-8的方式生成字符串
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Map<String, Object> keyMap = null;
|
||||
try {
|
||||
keyMap = RSAUtils.genKeyPair();
|
||||
String publicKey = RSAUtils.getPublicKey(keyMap);
|
||||
String privateKey = RSAUtils.getPrivateKey(keyMap);
|
||||
System.err.println("公钥: \n\r" + publicKey);
|
||||
System.err.println("私钥: \n\r" + privateKey);
|
||||
// 公钥:
|
||||
// MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDE8aNkz3X5f96bW2EJ3fRQsEmtgrIzLSCSJZLf1WBay0ihEideK45md5UZIFB6HSWwBaKD4z1uAMdt5esn0AIvrQS8+nlnB+Fohzxg7yY2ooDLP2az0WVKzepbeg8igq+jflUh7/+rvndiJAnv+mnMbibFqhYsDAJ3Zq82FkOeXQIDAQAB
|
||||
// 私钥:
|
||||
// MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMTxo2TPdfl/3ptbYQnd9FCwSa2CsjMtIJIlkt/VYFrLSKESJ14rjmZ3lRkgUHodJbAFooPjPW4Ax23l6yfQAi+tBLz6eWcH4WiHPGDvJjaigMs/ZrPRZUrN6lt6DyKCr6N+VSHv/6u+d2IkCe/6acxuJsWqFiwMAndmrzYWQ55dAgMBAAECgYB1gfPKz5oFjw0ERyaEG6GNj1G2rFek/1UCvlZ/JTJDmi0wpcNFhdmGO+2DO2upIMD+4K3R4YEipGZZpSiE7bCPM1uIerVAi0efTQMZKSrreud29Z/6xN0166GthAj30AjrwxfNAhoUNQXcG2NQJmfUpPlV95Cjh2b6tTlLdU9foQJBAO2zrzYeLiBrhEOZqr5JC8zUdseGSKCwIvZDwQ+s8GuuSVpm1q9mHOL3TODNlawfst78o9QBkk2MyKP7Voe6C6UCQQDUGr/A7XTvV39fqO4V+BcSLDCpxTHJ8UUWiRovXhDMn0TjqeRnDiRC9YuMf5XCXwDkYnK/u3O2maZugrcgUqpZAkBgd4zC9MqZg6jg2mtN4E02qn8uCFRPSkxWDzc5ymCkAs5oLtYvxswwXFbJ4QU+Hns0Pemq75xVdq4yxpzeZmW1AkEAvOi+FJTpaypg9dA9jS+TTMoy5WIOgC/1OqcNvVZoW/cWojZ0iRzdSw3rJk2UErQO1VqhnQbVfrLGuvKNK6q0sQJATbmrgK1KDaAS3Ns8MI6pDKWWHaAy8Vrnwz4nRIX2C0FKLTYwbNPrvVHdpD0ItZ8p9wiAL6HVn5ipxbz6v0l1uA==
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
package com.zcloud.common.utils;
|
||||
|
||||
/**
|
||||
* Redis所有Keys
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class RedisKeys {
|
||||
|
||||
public static String getSysConfigKey(String key){
|
||||
return "sys:config:" + key;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
|
||||
package com.zcloud.common.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Redis工具类
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class RedisUtils {
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
@Autowired
|
||||
private ValueOperations<String, String> valueOperations;
|
||||
@Autowired
|
||||
private HashOperations<String, String, Object> hashOperations;
|
||||
@Autowired
|
||||
private ListOperations<String, Object> listOperations;
|
||||
@Autowired
|
||||
private SetOperations<String, Object> setOperations;
|
||||
@Autowired
|
||||
private ZSetOperations<String, Object> zSetOperations;
|
||||
/** 默认过期时长,单位:秒 */
|
||||
public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
|
||||
/** 不设置过期时长 */
|
||||
public final static long NOT_EXPIRE = -1;
|
||||
private final static Gson gson = new Gson();
|
||||
|
||||
public void set(String key, Object value, long expire){
|
||||
valueOperations.set(key, toJson(value));
|
||||
if(expire != NOT_EXPIRE){
|
||||
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(String key, Object value){
|
||||
set(key, value, DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
public <T> T get(String key, Class<T> clazz, long expire) {
|
||||
String value = valueOperations.get(key);
|
||||
if(expire != NOT_EXPIRE){
|
||||
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
|
||||
}
|
||||
return value == null ? null : fromJson(value, clazz);
|
||||
}
|
||||
|
||||
public <T> T get(String key, Class<T> clazz) {
|
||||
return get(key, clazz, NOT_EXPIRE);
|
||||
}
|
||||
|
||||
public String get(String key, long expire) {
|
||||
String value = valueOperations.get(key);
|
||||
if(expire != NOT_EXPIRE){
|
||||
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String get(String key) {
|
||||
return get(key, NOT_EXPIRE);
|
||||
}
|
||||
|
||||
public void delete(String key) {
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Object转成JSON数据
|
||||
*/
|
||||
private String toJson(Object object){
|
||||
if(object instanceof Integer || object instanceof Long || object instanceof Float ||
|
||||
object instanceof Double || object instanceof Boolean || object instanceof String){
|
||||
return String.valueOf(object);
|
||||
}
|
||||
return gson.toJson(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON数据,转成Object
|
||||
*/
|
||||
private <T> T fromJson(String json, Class<T> clazz){
|
||||
return gson.fromJson(json, clazz);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.zcloud.common.exception.ZException;
|
||||
import com.zcloud.modules.sys.entity.SysUserEntity;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
/**
|
||||
* Shiro工具类
|
||||
*/
|
||||
public class ShiroUtils {
|
||||
|
||||
public static Session getSession() {
|
||||
return SecurityUtils.getSubject().getSession();
|
||||
}
|
||||
|
||||
public static Subject getSubject() {
|
||||
return SecurityUtils.getSubject();
|
||||
}
|
||||
|
||||
public static SysUserEntity getUserEntity() {
|
||||
return (SysUserEntity)SecurityUtils.getSubject().getPrincipal();
|
||||
}
|
||||
|
||||
public static String getUserId() {
|
||||
return getUserEntity().getUserId();
|
||||
}
|
||||
|
||||
public static void setSessionAttribute(Object key, Object value) {
|
||||
getSession().setAttribute(key, value);
|
||||
}
|
||||
|
||||
public static Object getSessionAttribute(Object key) {
|
||||
return getSession().getAttribute(key);
|
||||
}
|
||||
|
||||
public static boolean isLogin() {
|
||||
return SecurityUtils.getSubject().getPrincipal() != null;
|
||||
}
|
||||
|
||||
public static String getKaptcha(String key) {
|
||||
Object kaptcha = getSessionAttribute(key);
|
||||
if(kaptcha == null){
|
||||
throw new ZException("验证码已失效");
|
||||
}
|
||||
getSession().removeAttribute(key);
|
||||
return kaptcha.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
|
||||
package com.zcloud.common.utils;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Spring Context 工具类
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class SpringContextUtils implements ApplicationContextAware {
|
||||
public static ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
SpringContextUtils.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public static Object getBean(String name) {
|
||||
return applicationContext.getBean(name);
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name, Class<T> requiredType) {
|
||||
return applicationContext.getBean(name, requiredType);
|
||||
}
|
||||
|
||||
public static boolean containsBean(String name) {
|
||||
return applicationContext.containsBean(name);
|
||||
}
|
||||
|
||||
public static boolean isSingleton(String name) {
|
||||
return applicationContext.isSingleton(name);
|
||||
}
|
||||
|
||||
public static Class<? extends Object> getType(String name) {
|
||||
return applicationContext.getType(name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
public class TemplateData {
|
||||
|
||||
//keyword1:订单类型,keyword2:下单金额,keyword3:配送地址,keyword4:取件地址,keyword5备注
|
||||
private String value;//,,依次排下去
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,355 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.deepoove.poi.XWPFTemplate;
|
||||
import com.deepoove.poi.config.Configure;
|
||||
import com.deepoove.poi.config.ConfigureBuilder;
|
||||
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* 说明:常用工具
|
||||
* 作者:luoxiaobao
|
||||
* 官网:www.qdkjchina.com
|
||||
*/
|
||||
public class Tools {
|
||||
|
||||
/**
|
||||
* 随机生成六位数验证码
|
||||
* @return
|
||||
*/
|
||||
public static int getRandomNum(){
|
||||
Random r = new Random();
|
||||
return r.nextInt(900000)+100000;//(Math.random()*(999999-100000)+100000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成四位数验证码
|
||||
* @return
|
||||
*/
|
||||
public static int getRandomNum4(){
|
||||
Random r = new Random();
|
||||
return r.nextInt(9000)+1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测字符串是否不为空(null,"","null")
|
||||
* @param s
|
||||
* @return 不为空则返回true,否则返回false
|
||||
*/
|
||||
public static boolean notEmpty(String s){
|
||||
return s!=null && !"".equals(s) && !"null".equals(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测字符串是否为空(null,"","null")
|
||||
* @param s
|
||||
* @return 为空则返回true,不否则返回false
|
||||
*/
|
||||
public static boolean isEmpty(String s){
|
||||
return s==null || "".equals(s) || "null".equals(s);
|
||||
}
|
||||
public static boolean isEmpty (Object obj) {
|
||||
return obj ==null || "".equals(obj);
|
||||
}
|
||||
/**
|
||||
* 字符串转换为字符串数组
|
||||
* @param str 字符串
|
||||
* @param splitRegex 分隔符
|
||||
* @return
|
||||
*/
|
||||
public static String[] str2StrArray(String str,String splitRegex){
|
||||
if(isEmpty(str)){
|
||||
return null;
|
||||
}
|
||||
return str.split(splitRegex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用默认的分隔符(,)将字符串转换为字符串数组
|
||||
* @param str 字符串
|
||||
* @return
|
||||
*/
|
||||
public static String[] str2StrArray(String str){
|
||||
return str2StrArray(str,",\\s*");
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证邮箱
|
||||
* @param email
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkEmail(String email){
|
||||
boolean flag = false;
|
||||
try{
|
||||
String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
|
||||
Pattern regex = Pattern.compile(check);
|
||||
Matcher matcher = regex.matcher(email);
|
||||
flag = matcher.matches();
|
||||
}catch(Exception e){
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证手机号码
|
||||
* @param mobileNumber
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkMobileNumber(String mobileNumber){
|
||||
boolean flag = false;
|
||||
try{
|
||||
Pattern regex = Pattern.compile("^(((13[0-9])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8})|(0\\d{2}-\\d{8})|(0\\d{3}-\\d{7})$");
|
||||
Matcher matcher = regex.matcher(mobileNumber);
|
||||
flag = matcher.matches();
|
||||
}catch(Exception e){
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测KEY是否正确
|
||||
* @param paraname 传入参数
|
||||
* @param FKEY 接收的 KEY
|
||||
* @return 为空则返回true,不否则返回false
|
||||
*/
|
||||
public static boolean checkKey(String paraname, String FKEY){
|
||||
paraname = (null == paraname)? "":paraname;
|
||||
return MD5.md5(paraname+DateUtil.getDays()+",fh,").equals(FKEY);
|
||||
}
|
||||
/**
|
||||
转半角的函数(DBC case)<br/><br/>
|
||||
全角空格为12288,半角空格为32
|
||||
其他字符半角(33-126)与全角(65281-65374)的对应关系是:均相差65248
|
||||
* @param input 任意字符串
|
||||
* @return 半角字符串
|
||||
*
|
||||
*/
|
||||
public static String ToDBC(String input) {
|
||||
char[] c = input.toCharArray();
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
if (c[i] == 12288) {
|
||||
//全角空格为12288,半角空格为32
|
||||
c[i] = (char) 32;
|
||||
continue;
|
||||
}
|
||||
if (c[i] > 65280 && c[i] < 65375)
|
||||
//其他字符半角(33-126)与全角(65281-65374)的对应关系是:均相差65248
|
||||
c[i] = (char) (c[i] - 65248);
|
||||
}
|
||||
return new String(c);
|
||||
}
|
||||
|
||||
public static String replaceBlank(String str) {
|
||||
String dest = "";
|
||||
if (str != null) {
|
||||
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
|
||||
Matcher m = p.matcher(str);
|
||||
dest = m.replaceAll("");
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
public static String excelHandle (String string) {
|
||||
String aString = string.replaceAll(" ", "");
|
||||
aString = ToDBC(aString);
|
||||
aString = replaceBlank(aString);
|
||||
return aString;
|
||||
}
|
||||
public static String excelHandle (Object object) {
|
||||
String aString = object.toString().replaceAll(" ", "");
|
||||
aString = ToDBC(aString);
|
||||
aString = replaceBlank(aString);
|
||||
return aString;
|
||||
}
|
||||
public static String get32UUID() {
|
||||
String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public static String uploadFile(MultipartFile file, String folder) {
|
||||
String ffile = DateUtil.getDays();
|
||||
String fileName = get32UUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
String path = "/uploadFiles/" + folder + "/" + ffile;
|
||||
FileUploadUtil.sshSftp(file, fileName, path);
|
||||
return "/uploadFiles/" + folder + "/" + ffile +"/" + fileName;
|
||||
}
|
||||
|
||||
public static boolean isNotBlank(Object obj){
|
||||
return obj!=null &&!"".equals(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 构建树形结构
|
||||
*
|
||||
* @param entities 实体集合
|
||||
* idFieldName id字段名称
|
||||
* parentIdFieldName parentId字段名称
|
||||
* childrenFieldName children字段名称
|
||||
* rootId 根节点id
|
||||
**/
|
||||
public static <T> List<T> buildEntityTree(List<T> entities, String idFieldName, String parentIdFieldName, String childrenFieldName,String rootId) {
|
||||
if (entities == null || entities.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<T> result = new ArrayList<>();
|
||||
|
||||
try {
|
||||
Field idField = getField(entities.get(0).getClass(), idFieldName);
|
||||
Field parentIdField = getField(entities.get(0).getClass(), parentIdFieldName);
|
||||
Field childrenField = getField(entities.get(0).getClass(), childrenFieldName);
|
||||
|
||||
if (idField == null || parentIdField == null) {
|
||||
throw new IllegalArgumentException("Invalid idFieldName or parentIdFieldName or childrenField");
|
||||
}
|
||||
|
||||
Map<Object, T> entityMap = new HashMap<>();
|
||||
for (T entity : entities) {
|
||||
idField.setAccessible(true);
|
||||
Object id = idField.get(entity);
|
||||
entityMap.put(id, entity);
|
||||
}
|
||||
|
||||
for (T entity : entities) {
|
||||
parentIdField.setAccessible(true);
|
||||
Object parentId = parentIdField.get(entity);
|
||||
if(parentId.equals(rootId)){
|
||||
result.add(entity); // 根节点
|
||||
|
||||
}else{
|
||||
T parentEntity = entityMap.get(parentId);
|
||||
if (parentEntity != null) {
|
||||
if (childrenField != null) {
|
||||
childrenField.setAccessible(true);
|
||||
List<T> children = (List<T>) childrenField.get(parentEntity);
|
||||
if (children == null) {
|
||||
children = new ArrayList<>();
|
||||
}
|
||||
children.add(entity);
|
||||
childrenField.set(parentEntity, children);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static Field getField(Class<?> clazz, String fieldName) {
|
||||
try {
|
||||
return clazz.getDeclaredField(fieldName);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// 若当前类不存在指定字段,则尝试从父类中获取
|
||||
Class<?> superClass = clazz.getSuperclass();
|
||||
if (superClass != null && superClass != Object.class) {
|
||||
return getField(superClass, fieldName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件的后缀名
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 文件后缀名,如果没有后缀名则返回空字符串
|
||||
*/
|
||||
public static String getFileExtension(String fileName) {
|
||||
if (fileName == null || fileName.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
int lastDotIndex = fileName.lastIndexOf('.');
|
||||
if (lastDotIndex == -1) {
|
||||
return ""; // 没有后缀名
|
||||
}
|
||||
|
||||
return fileName.substring(lastDotIndex + 1).toLowerCase();
|
||||
}
|
||||
|
||||
public static String toString(Object obj) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
public static Integer toInteger(Object obj) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
return Integer.valueOf(obj.toString());
|
||||
}
|
||||
|
||||
public static Double toDouble(Object obj) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
return Double.valueOf(obj.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算给定年份属于第几个周期。
|
||||
* @param startYear 起始年份
|
||||
* @param year 给定的年份
|
||||
* @param cycle 周期数
|
||||
* @return 返回周期编号
|
||||
*/
|
||||
public static int calculateCycle(int startYear,int year,int cycle) {
|
||||
int yearsDifference = year - startYear;
|
||||
return yearsDifference / cycle + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染模板并写入文件
|
||||
*
|
||||
* @param templatePath 模板文件路径(相对于类路径)
|
||||
* @param dataMap 数据映射,键为占位符名称,值为占位符数据
|
||||
* @throws IOException 如果文件操作失败
|
||||
*/
|
||||
public static ByteArrayOutputStream renderTemplate(String templatePath, Map<String, Object> dataMap) throws IOException {
|
||||
// 获取模板流
|
||||
InputStream templateStream = Tools.class.getClassLoader().getResourceAsStream(templatePath);
|
||||
if (templateStream == null) {
|
||||
throw new IOException("模板文件未找到: " + templatePath);
|
||||
}
|
||||
|
||||
// 创建配置并绑定渲染策略
|
||||
ConfigureBuilder builder = Configure.builder();
|
||||
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof List) {
|
||||
// 如果值是列表,则绑定 LoopRowTableRenderPolicy
|
||||
builder.bind(new LoopRowTableRenderPolicy(), key);
|
||||
}
|
||||
}
|
||||
Configure build = builder.build();
|
||||
|
||||
// 编译和渲染模板
|
||||
XWPFTemplate render = XWPFTemplate.compile(templateStream, build).render(dataMap);
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
render.write(outputStream);
|
||||
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import org.apache.logging.log4j.util.Base64Util;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
public class VerifyCodeUtil {
|
||||
//使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符
|
||||
public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
|
||||
private static Random random = new Random();
|
||||
|
||||
/**
|
||||
* 使用系统默认字符源生成验证码
|
||||
*
|
||||
* @param verifySize 验证码长度
|
||||
* @return
|
||||
*/
|
||||
public static String generateVerifyCode(int verifySize) {
|
||||
return generateVerifyCode(verifySize, VERIFY_CODES);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用指定源生成验证码
|
||||
*
|
||||
* @param verifySize 验证码长度
|
||||
* @param sources 验证码字符源
|
||||
* @return
|
||||
*/
|
||||
public static String generateVerifyCode(int verifySize, String sources) {
|
||||
if (sources == null || sources.length() == 0) {
|
||||
sources = VERIFY_CODES;
|
||||
}
|
||||
int codesLen = sources.length();
|
||||
Random rand = new Random(System.currentTimeMillis());
|
||||
StringBuilder verifyCode = new StringBuilder(verifySize);
|
||||
for (int i = 0; i < verifySize; i++) {
|
||||
verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
|
||||
}
|
||||
return verifyCode.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定数据的验证码并以Base64编码一字符串形式返回,用于前后分离
|
||||
* @param w
|
||||
* @param h
|
||||
* @param code
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String outputImage(int w, int h, String code) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
VerifyCodeUtil.outputImage(100, 39, baos, code);
|
||||
final String BASE64_IMAGE = "data:image/jpeg;base64,%s";
|
||||
String base64Img = String.format(BASE64_IMAGE, Base64Util.encode(Arrays.toString(baos.toByteArray())));
|
||||
return base64Img;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成指定验证码图像文件
|
||||
*
|
||||
* @param w
|
||||
* @param h
|
||||
* @param outputFile
|
||||
* @param code
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void outputImage(int w, int h, File outputFile, String code) throws IOException {
|
||||
if (outputFile == null) {
|
||||
return;
|
||||
}
|
||||
File dir = outputFile.getParentFile();
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
try {
|
||||
outputFile.createNewFile();
|
||||
FileOutputStream fos = new FileOutputStream(outputFile);
|
||||
outputImage(w, h, fos, code);
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出指定验证码图片流
|
||||
*
|
||||
* @param w
|
||||
* @param h
|
||||
* @param os
|
||||
* @param code
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
|
||||
int verifySize = code.length();
|
||||
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
Random rand = new Random();
|
||||
Graphics2D g2 = image.createGraphics();
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
Color[] colors = new Color[5];
|
||||
Color[] colorSpaces = new Color[]{Color.WHITE, Color.CYAN,
|
||||
Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
|
||||
Color.PINK, Color.YELLOW};
|
||||
float[] fractions = new float[colors.length];
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
|
||||
fractions[i] = rand.nextFloat();
|
||||
}
|
||||
Arrays.sort(fractions);
|
||||
|
||||
g2.setColor(Color.GRAY);// 设置边框色
|
||||
g2.fillRect(0, 0, w, h);
|
||||
|
||||
Color c = getRandColor(200, 250);
|
||||
g2.setColor(c);// 设置背景色
|
||||
g2.fillRect(0, 2, w, h - 4);
|
||||
|
||||
//绘制干扰线
|
||||
Random random = new Random();
|
||||
g2.setColor(getRandColor(160, 200));// 设置线条的颜色
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int x = random.nextInt(w - 1);
|
||||
int y = random.nextInt(h - 1);
|
||||
int xl = random.nextInt(6) + 1;
|
||||
int yl = random.nextInt(12) + 1;
|
||||
g2.drawLine(x, y, x + xl + 40, y + yl + 20);
|
||||
}
|
||||
|
||||
// 添加噪点
|
||||
float yawpRate = 0.05f;// 噪声率
|
||||
int area = (int) (yawpRate * w * h);
|
||||
for (int i = 0; i < area; i++) {
|
||||
int x = random.nextInt(w);
|
||||
int y = random.nextInt(h);
|
||||
int rgb = getRandomIntColor();
|
||||
image.setRGB(x, y, rgb);
|
||||
}
|
||||
|
||||
shear(g2, w, h, c);// 使图片扭曲
|
||||
|
||||
g2.setColor(getRandColor(100, 160));
|
||||
int fontSize = h - 6;
|
||||
Font font = new Font("Algerian", Font.ITALIC, fontSize);
|
||||
g2.setFont(font);
|
||||
char[] chars = code.toCharArray();
|
||||
for (int i = 0; i < verifySize; i++) {
|
||||
AffineTransform affine = new AffineTransform();
|
||||
affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize / 2, h / 2);
|
||||
g2.setTransform(affine);
|
||||
g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
|
||||
}
|
||||
|
||||
g2.dispose();
|
||||
ImageIO.write(image, "jpg", os);
|
||||
}
|
||||
|
||||
|
||||
private static Color getRandColor(int fc, int bc) {
|
||||
if (fc > 255) {
|
||||
fc = 255;
|
||||
}
|
||||
if (bc > 255) {
|
||||
bc = 255;
|
||||
}
|
||||
int r = fc + random.nextInt(bc - fc);
|
||||
int g = fc + random.nextInt(bc - fc);
|
||||
int b = fc + random.nextInt(bc - fc);
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
private static int getRandomIntColor() {
|
||||
int[] rgb = getRandomRgb();
|
||||
int color = 0;
|
||||
for (int c : rgb) {
|
||||
color = color << 8;
|
||||
color = color | c;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
private static int[] getRandomRgb() {
|
||||
int[] rgb = new int[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
rgb[i] = random.nextInt(255);
|
||||
}
|
||||
return rgb;
|
||||
}
|
||||
|
||||
private static void shear(Graphics g, int w1, int h1, Color color) {
|
||||
shearX(g, w1, h1, color);
|
||||
shearY(g, w1, h1, color);
|
||||
}
|
||||
|
||||
private static void shearX(Graphics g, int w1, int h1, Color color) {
|
||||
int period = random.nextInt(2);
|
||||
|
||||
boolean borderGap = true;
|
||||
int frames = 1;
|
||||
int phase = random.nextInt(2);
|
||||
|
||||
for (int i = 0; i < h1; i++) {
|
||||
double d = (double) (period >> 1)
|
||||
* Math.sin((double) i / (double) period
|
||||
+ (6.2831853071795862D * (double) phase)
|
||||
/ (double) frames);
|
||||
g.copyArea(0, i, w1, 1, (int) d, 0);
|
||||
if (borderGap) {
|
||||
g.setColor(color);
|
||||
g.drawLine((int) d, i, 0, i);
|
||||
g.drawLine((int) d + w1, i, w1, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void shearY(Graphics g, int w1, int h1, Color color) {
|
||||
int period = random.nextInt(40) + 10; // 50;
|
||||
boolean borderGap = true;
|
||||
int frames = 20;
|
||||
int phase = 7;
|
||||
for (int i = 0; i < w1; i++) {
|
||||
double d = (double) (period >> 1)
|
||||
* Math.sin((double) i / (double) period
|
||||
+ (6.2831853071795862D * (double) phase)
|
||||
/ (double) frames);
|
||||
g.copyArea(i, 0, 1, h1, 0, (int) d);
|
||||
if (borderGap) {
|
||||
g.setColor(color);
|
||||
g.drawLine(i, (int) d, i, 0);
|
||||
g.drawLine(i, (int) d + h1, i, h1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
File dir = new File("D:/upload/verifyCode");
|
||||
int w = 200, h = 80;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
String verifyCode = generateVerifyCode(4);
|
||||
File file = new File(dir, verifyCode + ".jpg");
|
||||
outputImage(w, h, file, verifyCode);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* 小程序推送所需数据
|
||||
* */
|
||||
public class WxMssVo {
|
||||
private String touser;//用户openid
|
||||
private String template_id;//模版id
|
||||
private String page = "index";//默认跳到小程序首页
|
||||
private String url = "";//默认跳到小程序首页
|
||||
// private String form_id;//收集到的用户formid
|
||||
private String emphasis_keyword = "keyword1.DATA";//放大那个推送字段
|
||||
private Map<String,TemplateData> data;//推送文字
|
||||
|
||||
public String getTouser() {
|
||||
return touser;
|
||||
}
|
||||
public void setTouser(String touser) {
|
||||
this.touser = touser;
|
||||
}
|
||||
public String getTemplate_id() {
|
||||
return template_id;
|
||||
}
|
||||
public void setTemplate_id(String template_id) {
|
||||
this.template_id = template_id;
|
||||
}
|
||||
public String getPage() {
|
||||
return page;
|
||||
}
|
||||
public void setPage(String page) {
|
||||
this.page = page;
|
||||
}
|
||||
// public String getForm_id() {
|
||||
// return form_id;
|
||||
// }
|
||||
// public void setForm_id(String form_id) {
|
||||
// this.form_id = form_id;
|
||||
// }
|
||||
public String getEmphasis_keyword() {
|
||||
return emphasis_keyword;
|
||||
}
|
||||
public void setEmphasis_keyword(String emphasis_keyword) {
|
||||
this.emphasis_keyword = emphasis_keyword;
|
||||
}
|
||||
public Map<String,TemplateData> getData() {
|
||||
return data;
|
||||
}
|
||||
public void setData(Map<String,TemplateData> data) {
|
||||
this.data = data;
|
||||
}
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
package com.zcloud.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.zcloud.modules.sys.entity.PageData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author fangjiakai
|
||||
* @date 2025/01/22 15:44
|
||||
*/
|
||||
@Component
|
||||
public class WxPushUtil {
|
||||
@Autowired
|
||||
private RedisUtils redisUtil;
|
||||
private static final String APPID = "wx641d6a98d89ddd03";
|
||||
private static final String SECRET = "22cd2198a03e5a1a70351f55b3d7687d";
|
||||
|
||||
public static String getOpenid(String code){
|
||||
String wxLoginUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
|
||||
String param = "appid=" + APPID + "&secret=" + SECRET + "&code=" + code + "&grant_type=authorization_code";
|
||||
String jsonString = sendGet(wxLoginUrl, param);
|
||||
JSONObject json = JSONObject.parseObject(jsonString);
|
||||
System.out.println(json);
|
||||
return json.get("openid").toString();
|
||||
}
|
||||
public static String sendGet(String url, String param) {
|
||||
String result = "";
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
String urlNameString = url + "?" + param;
|
||||
URL realUrl = new URL(urlNameString);
|
||||
// 打开和URL之间的连接
|
||||
URLConnection connection = realUrl.openConnection();
|
||||
// 设置通用的请求属性
|
||||
connection.setRequestProperty("accept", "*/*");
|
||||
connection.setRequestProperty("connection", "Keep-Alive");
|
||||
connection.setRequestProperty("user-agent",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
// 建立实际的连接
|
||||
connection.connect();
|
||||
// 获取所有响应头字段
|
||||
Map<String, List<String>> map = connection.getHeaderFields();
|
||||
// 遍历所有的响应头字段
|
||||
for (String key : map.keySet()) {
|
||||
System.out.println(key + "--->" + map.get(key));
|
||||
}
|
||||
// 定义 BufferedReader输入流来读取URL的响应
|
||||
in = new BufferedReader(new InputStreamReader(
|
||||
connection.getInputStream()));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("发送GET请求出现异常!" + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 使用finally块来关闭输入流
|
||||
finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* 微信推送新消息
|
||||
* */
|
||||
public void pushWxNotice(String openid,String name,String content) throws Exception{
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
try {
|
||||
Object o = redisUtil.get("WeChatOfficialAccount");
|
||||
String access_token = "";
|
||||
if (Tools.isEmpty(o)) {
|
||||
access_token = getAccess_token(APPID, SECRET);
|
||||
redisUtil.set("WeChatOfficialAccount", access_token,30);
|
||||
} else {
|
||||
access_token = o.toString();
|
||||
}
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token;
|
||||
|
||||
//拼接推送的模版
|
||||
WxMssVo wxMssVo = new WxMssVo();
|
||||
wxMssVo.setTouser(openid);//用户openid
|
||||
wxMssVo.setTemplate_id("5InweJzYRkmP9FhCE4V_X9m1_OgDGM141mLRio4AE6s");//模版id
|
||||
|
||||
Map<String, TemplateData> m = new HashMap();
|
||||
TemplateData keyword1 = new TemplateData();
|
||||
keyword1.setValue("安全检查工作提醒");
|
||||
m.put("first", keyword1);
|
||||
|
||||
TemplateData keyword2 = new TemplateData();
|
||||
keyword2.setValue(name);
|
||||
m.put("keyword1", keyword2);
|
||||
|
||||
TemplateData keyword3 = new TemplateData();
|
||||
keyword3.setValue(DateUtil.date2Str(new Date()));
|
||||
m.put("keyword2", keyword3);
|
||||
|
||||
TemplateData keyword4 = new TemplateData();
|
||||
keyword4.setValue(content);
|
||||
m.put("keyword3", keyword4);
|
||||
wxMssVo.setData(m);
|
||||
|
||||
ResponseEntity<String> responseEntity =
|
||||
restTemplate.postForEntity(url, wxMssVo, String.class);
|
||||
System.out.println("pushNotice:" + responseEntity.getBody());
|
||||
} catch (Exception e) {
|
||||
System.out.println("微信推送异常 => " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取access_token
|
||||
* appid和appsecret到小程序后台获取,当然也可以让小程序开发人员给你传过来
|
||||
* */
|
||||
private String getAccess_token(String appid, String appsecret) {
|
||||
//获取access_token
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
|
||||
"&appid=" + appid + "&secret=" + appsecret;
|
||||
String json = restTemplate.getForObject(url, String.class);
|
||||
System.out.println("微信access_token的json信息 => " + json);
|
||||
JSONObject jsonObject = JSONObject.parseObject(json);
|
||||
return jsonObject.get("access_token").toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
|
||||
package com.zcloud.common.validator;
|
||||
|
||||
import com.zcloud.common.exception.ZException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* 数据校验
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class Assert {
|
||||
|
||||
public static void isBlank(String str, String message) {
|
||||
if (StringUtils.isBlank(str)) {
|
||||
throw new ZException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void isNull(Object object, String message) {
|
||||
if (object == null) {
|
||||
throw new ZException(message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.zcloud.common.validator;
|
||||
|
||||
import com.zcloud.common.exception.ZException;
|
||||
import com.zcloud.common.utils.Constant;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* hibernate-validator校验工具类
|
||||
*
|
||||
* 参考文档:http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ValidatorUtils {
|
||||
private static Validator validator;
|
||||
|
||||
static {
|
||||
validator = Validation.buildDefaultValidatorFactory().getValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验对象
|
||||
* @param object 待校验对象
|
||||
* @param groups 待校验的组
|
||||
* @throws ZException 校验不通过,则报RRException异常
|
||||
*/
|
||||
public static void validateEntity(Object object, Class<?>... groups)
|
||||
throws ZException {
|
||||
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
|
||||
if (!constraintViolations.isEmpty()) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
for (ConstraintViolation<Object> constraint : constraintViolations) {
|
||||
msg.append(constraint.getMessage()).append("<br>");
|
||||
}
|
||||
throw new ZException(msg.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateEntity(Object object, Constant.CloudService type) {
|
||||
validateEntity(object, type.getValidatorGroupClass());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
package com.zcloud.common.validator.group;
|
||||
|
||||
/**
|
||||
* 新增数据 Group
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface AddGroup {
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
package com.zcloud.common.validator.group;
|
||||
|
||||
/**
|
||||
* 阿里云
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface AliyunGroup {
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
package com.zcloud.common.validator.group;
|
||||
|
||||
import javax.validation.GroupSequence;
|
||||
|
||||
/**
|
||||
* 定义校验顺序,如果AddGroup组失败,则UpdateGroup组不会再校验
|
||||
*
|
||||
*
|
||||
*/
|
||||
@GroupSequence({AddGroup.class, UpdateGroup.class})
|
||||
public interface Group {
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
package com.zcloud.common.validator.group;
|
||||
|
||||
/**
|
||||
* 腾讯云
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface QcloudGroup {
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
package com.zcloud.common.validator.group;
|
||||
|
||||
/**
|
||||
* 七牛
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface QiniuGroup {
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.zcloud.common.validator.group;
|
||||
|
||||
/**
|
||||
* 更新数据 Group
|
||||
*/
|
||||
|
||||
public interface UpdateGroup {
|
||||
|
||||
}
|
|
@ -0,0 +1,530 @@
|
|||
package com.zcloud.common.xss;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* HTML filtering utility for protecting against XSS (Cross Site Scripting).
|
||||
*
|
||||
* This code is licensed LGPLv3
|
||||
*
|
||||
* This code is a Java port of the original work in PHP by Cal Hendersen.
|
||||
* http://code.iamcal.com/php/lib_filter/
|
||||
*
|
||||
* The trickiest part of the translation was handling the differences in regex handling
|
||||
* between PHP and Java. These resources were helpful in the process:
|
||||
*
|
||||
* http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html
|
||||
* http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php
|
||||
* http://www.regular-expressions.info/modifiers.html
|
||||
*
|
||||
* A note on naming conventions: instance variables are prefixed with a "v"; global
|
||||
* constants are in all caps.
|
||||
*
|
||||
* Sample use:
|
||||
* String input = ...
|
||||
* String clean = new HTMLFilter().filter( input );
|
||||
*
|
||||
* The class is not thread safe. Create a new instance if in doubt.
|
||||
*
|
||||
* If you find bugs or have suggestions on improvement (especially regarding
|
||||
* performance), please contact us. The latest version of this
|
||||
* source, and our contact details, can be found at http://xss-html-filter.sf.net
|
||||
*
|
||||
* @author Joseph O'Connell
|
||||
* @author Cal Hendersen
|
||||
* @author Michael Semb Wever
|
||||
*/
|
||||
public final class HTMLFilter {
|
||||
|
||||
/** regex flag union representing /si modifiers in php **/
|
||||
private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
|
||||
private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL);
|
||||
private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL);
|
||||
private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?");
|
||||
private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?");
|
||||
private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?");
|
||||
private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))");
|
||||
private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL);
|
||||
private static final Pattern P_END_ARROW = Pattern.compile("^>");
|
||||
private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)");
|
||||
private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)");
|
||||
private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)");
|
||||
private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)");
|
||||
private static final Pattern P_AMP = Pattern.compile("&");
|
||||
private static final Pattern P_QUOTE = Pattern.compile("<");
|
||||
private static final Pattern P_LEFT_ARROW = Pattern.compile("<");
|
||||
private static final Pattern P_RIGHT_ARROW = Pattern.compile(">");
|
||||
private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");
|
||||
|
||||
// @xxx could grow large... maybe use sesat's ReferenceMap
|
||||
private static final ConcurrentMap<String,Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<String, Pattern>();
|
||||
private static final ConcurrentMap<String,Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<String, Pattern>();
|
||||
|
||||
/** set of allowed html elements, along with allowed attributes for each element **/
|
||||
private final Map<String, List<String>> vAllowed;
|
||||
/** counts of open tags for each (allowable) html element **/
|
||||
private final Map<String, Integer> vTagCounts = new HashMap<String, Integer>();
|
||||
|
||||
/** html elements which must always be self-closing (e.g. "<img />") **/
|
||||
private final String[] vSelfClosingTags;
|
||||
/** html elements which must always have separate opening and closing tags (e.g. "<b></b>") **/
|
||||
private final String[] vNeedClosingTags;
|
||||
/** set of disallowed html elements **/
|
||||
private final String[] vDisallowed;
|
||||
/** attributes which should be checked for valid protocols **/
|
||||
private final String[] vProtocolAtts;
|
||||
/** allowed protocols **/
|
||||
private final String[] vAllowedProtocols;
|
||||
/** tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") **/
|
||||
private final String[] vRemoveBlanks;
|
||||
/** entities allowed within html markup **/
|
||||
private final String[] vAllowedEntities;
|
||||
/** flag determining whether comments are allowed in input String. */
|
||||
private final boolean stripComment;
|
||||
private final boolean encodeQuotes;
|
||||
private boolean vDebug = false;
|
||||
/**
|
||||
* flag determining whether to try to make tags when presented with "unbalanced"
|
||||
* angle brackets (e.g. "<b text </b>" becomes "<b> text </b>"). If set to false,
|
||||
* unbalanced angle brackets will be html escaped.
|
||||
*/
|
||||
private final boolean alwaysMakeTags;
|
||||
|
||||
/** Default constructor.
|
||||
*
|
||||
*/
|
||||
public HTMLFilter() {
|
||||
vAllowed = new HashMap<>();
|
||||
|
||||
final ArrayList<String> a_atts = new ArrayList<String>();
|
||||
a_atts.add("href");
|
||||
a_atts.add("target");
|
||||
vAllowed.put("a", a_atts);
|
||||
|
||||
final ArrayList<String> img_atts = new ArrayList<String>();
|
||||
img_atts.add("src");
|
||||
img_atts.add("width");
|
||||
img_atts.add("height");
|
||||
img_atts.add("alt");
|
||||
vAllowed.put("img", img_atts);
|
||||
|
||||
final ArrayList<String> no_atts = new ArrayList<String>();
|
||||
vAllowed.put("b", no_atts);
|
||||
vAllowed.put("strong", no_atts);
|
||||
vAllowed.put("i", no_atts);
|
||||
vAllowed.put("em", no_atts);
|
||||
|
||||
vSelfClosingTags = new String[]{"img"};
|
||||
vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"};
|
||||
vDisallowed = new String[]{};
|
||||
vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp.
|
||||
vProtocolAtts = new String[]{"src", "href"};
|
||||
vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"};
|
||||
vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"};
|
||||
stripComment = true;
|
||||
encodeQuotes = true;
|
||||
alwaysMakeTags = true;
|
||||
}
|
||||
|
||||
/** Set debug flag to true. Otherwise use default settings. See the default constructor.
|
||||
*
|
||||
* @param debug turn debug on with a true argument
|
||||
*/
|
||||
public HTMLFilter(final boolean debug) {
|
||||
this();
|
||||
vDebug = debug;
|
||||
|
||||
}
|
||||
|
||||
/** Map-parameter configurable constructor.
|
||||
*
|
||||
* @param conf map containing configuration. keys match field names.
|
||||
*/
|
||||
public HTMLFilter(final Map<String,Object> conf) {
|
||||
|
||||
assert conf.containsKey("vAllowed") : "configuration requires vAllowed";
|
||||
assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";
|
||||
assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags";
|
||||
assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed";
|
||||
assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols";
|
||||
assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts";
|
||||
assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks";
|
||||
assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities";
|
||||
|
||||
vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed"));
|
||||
vSelfClosingTags = (String[]) conf.get("vSelfClosingTags");
|
||||
vNeedClosingTags = (String[]) conf.get("vNeedClosingTags");
|
||||
vDisallowed = (String[]) conf.get("vDisallowed");
|
||||
vAllowedProtocols = (String[]) conf.get("vAllowedProtocols");
|
||||
vProtocolAtts = (String[]) conf.get("vProtocolAtts");
|
||||
vRemoveBlanks = (String[]) conf.get("vRemoveBlanks");
|
||||
vAllowedEntities = (String[]) conf.get("vAllowedEntities");
|
||||
stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true;
|
||||
encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true;
|
||||
alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
vTagCounts.clear();
|
||||
}
|
||||
|
||||
private void debug(final String msg) {
|
||||
if (vDebug) {
|
||||
Logger.getAnonymousLogger().info(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// my versions of some PHP library functions
|
||||
public static String chr(final int decimal) {
|
||||
return String.valueOf((char) decimal);
|
||||
}
|
||||
|
||||
public static String htmlSpecialChars(final String s) {
|
||||
String result = s;
|
||||
result = regexReplace(P_AMP, "&", result);
|
||||
result = regexReplace(P_QUOTE, """, result);
|
||||
result = regexReplace(P_LEFT_ARROW, "<", result);
|
||||
result = regexReplace(P_RIGHT_ARROW, ">", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
/**
|
||||
* given a user submitted input String, filter out any invalid or restricted
|
||||
* html.
|
||||
*
|
||||
* @param input text (i.e. submitted by a user) than may contain html
|
||||
* @return "clean" version of input, with only valid, whitelisted html elements allowed
|
||||
*/
|
||||
public String filter(final String input) {
|
||||
reset();
|
||||
String s = input;
|
||||
|
||||
debug("************************************************");
|
||||
debug(" INPUT: " + input);
|
||||
|
||||
s = escapeComments(s);
|
||||
debug(" escapeComments: " + s);
|
||||
|
||||
s = balanceHTML(s);
|
||||
debug(" balanceHTML: " + s);
|
||||
|
||||
s = checkTags(s);
|
||||
debug(" checkTags: " + s);
|
||||
|
||||
s = processRemoveBlanks(s);
|
||||
debug("processRemoveBlanks: " + s);
|
||||
|
||||
s = validateEntities(s);
|
||||
debug(" validateEntites: " + s);
|
||||
|
||||
debug("************************************************\n\n");
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean isAlwaysMakeTags(){
|
||||
return alwaysMakeTags;
|
||||
}
|
||||
|
||||
public boolean isStripComments(){
|
||||
return stripComment;
|
||||
}
|
||||
|
||||
private String escapeComments(final String s) {
|
||||
final Matcher m = P_COMMENTS.matcher(s);
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
if (m.find()) {
|
||||
final String match = m.group(1); //(.*?)
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->"));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String balanceHTML(String s) {
|
||||
if (alwaysMakeTags) {
|
||||
//
|
||||
// try and form html
|
||||
//
|
||||
s = regexReplace(P_END_ARROW, "", s);
|
||||
s = regexReplace(P_BODY_TO_END, "<$1>", s);
|
||||
s = regexReplace(P_XML_CONTENT, "$1<$2", s);
|
||||
|
||||
} else {
|
||||
//
|
||||
// escape stray brackets
|
||||
//
|
||||
s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s);
|
||||
s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s);
|
||||
|
||||
//
|
||||
// the last regexp causes '<>' entities to appear
|
||||
// (we need to do a lookahead assertion so that the last bracket can
|
||||
// be used in the next pass of the regexp)
|
||||
//
|
||||
s = regexReplace(P_BOTH_ARROWS, "", s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String checkTags(String s) {
|
||||
Matcher m = P_TAGS.matcher(s);
|
||||
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
while (m.find()) {
|
||||
String replaceStr = m.group(1);
|
||||
replaceStr = processTag(replaceStr);
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
s = buf.toString();
|
||||
|
||||
// these get tallied in processTag
|
||||
// (remember to reset before subsequent calls to filter method)
|
||||
for (String key : vTagCounts.keySet()) {
|
||||
for (int ii = 0; ii < vTagCounts.get(key); ii++) {
|
||||
s += "</" + key + ">";
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String processRemoveBlanks(final String s) {
|
||||
String result = s;
|
||||
for (String tag : vRemoveBlanks) {
|
||||
if(!P_REMOVE_PAIR_BLANKS.containsKey(tag)){
|
||||
P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">"));
|
||||
}
|
||||
result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);
|
||||
if(!P_REMOVE_SELF_BLANKS.containsKey(tag)){
|
||||
P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));
|
||||
}
|
||||
result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) {
|
||||
Matcher m = regex_pattern.matcher(s);
|
||||
return m.replaceAll(replacement);
|
||||
}
|
||||
|
||||
private String processTag(final String s) {
|
||||
// ending tags
|
||||
Matcher m = P_END_TAG.matcher(s);
|
||||
if (m.find()) {
|
||||
final String name = m.group(1).toLowerCase();
|
||||
if (allowed(name)) {
|
||||
if (!inArray(name, vSelfClosingTags)) {
|
||||
if (vTagCounts.containsKey(name)) {
|
||||
vTagCounts.put(name, vTagCounts.get(name) - 1);
|
||||
return "</" + name + ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// starting tags
|
||||
m = P_START_TAG.matcher(s);
|
||||
if (m.find()) {
|
||||
final String name = m.group(1).toLowerCase();
|
||||
final String body = m.group(2);
|
||||
String ending = m.group(3);
|
||||
|
||||
//debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
|
||||
if (allowed(name)) {
|
||||
String params = "";
|
||||
|
||||
final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);
|
||||
final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);
|
||||
final List<String> paramNames = new ArrayList<String>();
|
||||
final List<String> paramValues = new ArrayList<String>();
|
||||
while (m2.find()) {
|
||||
paramNames.add(m2.group(1)); //([a-z0-9]+)
|
||||
paramValues.add(m2.group(3)); //(.*?)
|
||||
}
|
||||
while (m3.find()) {
|
||||
paramNames.add(m3.group(1)); //([a-z0-9]+)
|
||||
paramValues.add(m3.group(3)); //([^\"\\s']+)
|
||||
}
|
||||
|
||||
String paramName, paramValue;
|
||||
for (int ii = 0; ii < paramNames.size(); ii++) {
|
||||
paramName = paramNames.get(ii).toLowerCase();
|
||||
paramValue = paramValues.get(ii);
|
||||
|
||||
// debug( "paramName='" + paramName + "'" );
|
||||
// debug( "paramValue='" + paramValue + "'" );
|
||||
// debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );
|
||||
|
||||
if (allowedAttribute(name, paramName)) {
|
||||
if (inArray(paramName, vProtocolAtts)) {
|
||||
paramValue = processParamProtocol(paramValue);
|
||||
}
|
||||
params += " " + paramName + "=\"" + paramValue + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
if (inArray(name, vSelfClosingTags)) {
|
||||
ending = " /";
|
||||
}
|
||||
|
||||
if (inArray(name, vNeedClosingTags)) {
|
||||
ending = "";
|
||||
}
|
||||
|
||||
if (ending == null || ending.length() < 1) {
|
||||
if (vTagCounts.containsKey(name)) {
|
||||
vTagCounts.put(name, vTagCounts.get(name) + 1);
|
||||
} else {
|
||||
vTagCounts.put(name, 1);
|
||||
}
|
||||
} else {
|
||||
ending = " /";
|
||||
}
|
||||
return "<" + name + params + ending + ">";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// comments
|
||||
m = P_COMMENT.matcher(s);
|
||||
if (!stripComment && m.find()) {
|
||||
return "<" + m.group() + ">";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private String processParamProtocol(String s) {
|
||||
s = decodeEntities(s);
|
||||
final Matcher m = P_PROTOCOL.matcher(s);
|
||||
if (m.find()) {
|
||||
final String protocol = m.group(1);
|
||||
if (!inArray(protocol, vAllowedProtocols)) {
|
||||
// bad protocol, turn into local anchor link instead
|
||||
s = "#" + s.substring(protocol.length() + 1, s.length());
|
||||
if (s.startsWith("#//")) {
|
||||
s = "#" + s.substring(3, s.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String decodeEntities(String s) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
Matcher m = P_ENTITY.matcher(s);
|
||||
while (m.find()) {
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.decode(match).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
buf = new StringBuffer();
|
||||
m = P_ENTITY_UNICODE.matcher(s);
|
||||
while (m.find()) {
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.valueOf(match, 16).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
buf = new StringBuffer();
|
||||
m = P_ENCODE.matcher(s);
|
||||
while (m.find()) {
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.valueOf(match, 16).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
s = validateEntities(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private String validateEntities(final String s) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
// validate entities throughout the string
|
||||
Matcher m = P_VALID_ENTITIES.matcher(s);
|
||||
while (m.find()) {
|
||||
final String one = m.group(1); //([^&;]*)
|
||||
final String two = m.group(2); //(?=(;|&|$))
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
return encodeQuotes(buf.toString());
|
||||
}
|
||||
|
||||
private String encodeQuotes(final String s){
|
||||
if(encodeQuotes){
|
||||
StringBuffer buf = new StringBuffer();
|
||||
Matcher m = P_VALID_QUOTES.matcher(s);
|
||||
while (m.find()) {
|
||||
final String one = m.group(1); //(>|^)
|
||||
final String two = m.group(2); //([^<]+?)
|
||||
final String three = m.group(3); //(<|$)
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, """, two) + three));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
return buf.toString();
|
||||
}else{
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
private String checkEntity(final String preamble, final String term) {
|
||||
|
||||
return ";".equals(term) && isValidEntity(preamble)
|
||||
? '&' + preamble
|
||||
: "&" + preamble;
|
||||
}
|
||||
|
||||
private boolean isValidEntity(final String entity) {
|
||||
return inArray(entity, vAllowedEntities);
|
||||
}
|
||||
|
||||
private static boolean inArray(final String s, final String[] array) {
|
||||
for (String item : array) {
|
||||
if (item != null && item.equals(s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean allowed(final String name) {
|
||||
return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);
|
||||
}
|
||||
|
||||
private boolean allowedAttribute(final String name, final String paramName) {
|
||||
return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
|
||||
package com.zcloud.common.xss;
|
||||
|
||||
import com.zcloud.common.exception.ZException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* SQL过滤
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class SQLFilter {
|
||||
|
||||
/**
|
||||
* SQL注入过滤
|
||||
* @param str 待验证的字符串
|
||||
*/
|
||||
public static String sqlInject(String str){
|
||||
if(StringUtils.isBlank(str)){
|
||||
return null;
|
||||
}
|
||||
//去掉'|"|;|\字符
|
||||
str = StringUtils.replace(str, "'", "");
|
||||
str = StringUtils.replace(str, "\"", "");
|
||||
str = StringUtils.replace(str, ";", "");
|
||||
str = StringUtils.replace(str, "\\", "");
|
||||
|
||||
//转换成小写
|
||||
str = str.toLowerCase();
|
||||
|
||||
//非法字符
|
||||
String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"};
|
||||
|
||||
//判断是否包含非法字符
|
||||
for(String keyword : keywords){
|
||||
if(str.indexOf(keyword) != -1){
|
||||
throw new ZException("包含非法字符");
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
|
||||
package com.zcloud.common.xss;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* XSS过滤
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class XssFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig config) throws ServletException {
|
||||
}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
|
||||
(HttpServletRequest) request);
|
||||
chain.doFilter(xssRequest, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
|
||||
|
||||
package com.zcloud.common.xss;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* XSS过滤处理
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
//没被包装过的HttpServletRequest(特殊场景,需要自己过滤)
|
||||
HttpServletRequest orgRequest;
|
||||
//html过滤
|
||||
private final static HTMLFilter htmlFilter = new HTMLFilter();
|
||||
|
||||
public XssHttpServletRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
orgRequest = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
//非json类型,直接返回
|
||||
if(!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))){
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
//为空,直接返回
|
||||
String json = IOUtils.toString(super.getInputStream(), "utf-8");
|
||||
if (StringUtils.isBlank(json)) {
|
||||
return super.getInputStream();
|
||||
}
|
||||
|
||||
//xss过滤
|
||||
json = xssEncode(json);
|
||||
final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8"));
|
||||
return new ServletInputStream() {
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return bis.read();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
String value = super.getParameter(xssEncode(name));
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
value = xssEncode(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] parameters = super.getParameterValues(name);
|
||||
if (parameters == null || parameters.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
parameters[i] = xssEncode(parameters[i]);
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String,String[]> getParameterMap() {
|
||||
Map<String,String[]> map = new LinkedHashMap<>();
|
||||
Map<String,String[]> parameters = super.getParameterMap();
|
||||
for (String key : parameters.keySet()) {
|
||||
String[] values = parameters.get(key);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = xssEncode(values[i]);
|
||||
}
|
||||
map.put(key, values);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
String value = super.getHeader(xssEncode(name));
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
value = xssEncode(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private String xssEncode(String input) {
|
||||
return htmlFilter.filter(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最原始的request
|
||||
*/
|
||||
public HttpServletRequest getOrgRequest() {
|
||||
return orgRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最原始的request
|
||||
*/
|
||||
public static HttpServletRequest getOrgRequest(HttpServletRequest request) {
|
||||
if (request instanceof XssHttpServletRequestWrapper) {
|
||||
return ((XssHttpServletRequestWrapper) request).getOrgRequest();
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
|
||||
package com.zcloud.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class CorsConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.maxAge(3600);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
|
||||
package com.zcloud.config;
|
||||
|
||||
import com.zcloud.common.xss.XssFilter;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.DelegatingFilterProxy;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
/**
|
||||
* Filter配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterConfig {
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean shiroFilterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
|
||||
//该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
|
||||
registration.addInitParameter("targetFilterLifecycle", "true");
|
||||
registration.setEnabled(true);
|
||||
registration.setOrder(Integer.MAX_VALUE - 1);
|
||||
registration.addUrlPatterns("/*");
|
||||
return registration;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public FilterRegistrationBean xssFilterRegistration() {
|
||||
// FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
// registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
// registration.setFilter(new XssFilter());
|
||||
// registration.addUrlPatterns("/*");
|
||||
// registration.setName("xssFilter");
|
||||
// registration.setOrder(Integer.MAX_VALUE);
|
||||
// return registration;
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
|
||||
package com.zcloud.config;
|
||||
|
||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||
import com.google.code.kaptcha.util.Config;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
/**
|
||||
* 生成验证码配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class KaptchaConfig {
|
||||
|
||||
@Bean
|
||||
public DefaultKaptcha producer() {
|
||||
Properties properties = new Properties();
|
||||
properties.put("kaptcha.border", "no");
|
||||
properties.put("kaptcha.textproducer.font.color", "black");
|
||||
properties.put("kaptcha.textproducer.char.space", "5");
|
||||
properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
|
||||
Config config = new Config(properties);
|
||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
||||
defaultKaptcha.setConfig(config);
|
||||
return defaultKaptcha;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.zcloud.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.zcloud.modules.sys.plugins.YearTableNameHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* mybatis-plus配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
/**
|
||||
* 分页插件
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor paginationInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
|
||||
dynamicTableNameInnerInterceptor.setTableNameHandler(
|
||||
//可以传多个表名参数,指定哪些表使用MonthTableNameHandler处理表名称
|
||||
new YearTableNameHandler("sys_log")
|
||||
);
|
||||
//以拦截器的方式处理表名称
|
||||
interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
|
||||
//可以传递多个拦截器,即:可以传递多个表名处理器TableNameHandler
|
||||
//interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
|
||||
package com.zcloud.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
/**
|
||||
* Redis配置
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
@Autowired
|
||||
private RedisConnectionFactory factory;
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate() {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
|
||||
redisTemplate.setValueSerializer(new StringRedisSerializer());
|
||||
redisTemplate.setConnectionFactory(factory);
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForHash();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
|
||||
return redisTemplate.opsForValue();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForList();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForSet();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
|
||||
return redisTemplate.opsForZSet();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.zcloud.config;
|
||||
|
||||
import com.zcloud.modules.sys.oauth2.OAuth2Filter;
|
||||
import com.zcloud.modules.sys.oauth2.OAuth2Realm;
|
||||
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.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Shiro配置
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class ShiroConfig {
|
||||
|
||||
@Bean("securityManager")
|
||||
public SecurityManager securityManager(OAuth2Realm oAuth2Realm) {
|
||||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||
securityManager.setRealm(oAuth2Realm);
|
||||
securityManager.setRememberMeManager(null);
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
@Bean("shiroFilter")
|
||||
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
|
||||
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
|
||||
shiroFilter.setSecurityManager(securityManager);
|
||||
|
||||
//oauth过滤
|
||||
Map<String, Filter> filters = new HashMap<>();
|
||||
filters.put("oauth2", new OAuth2Filter());
|
||||
shiroFilter.setFilters(filters);
|
||||
|
||||
Map<String, String> filterMap = new LinkedHashMap<>();
|
||||
filterMap.put("/webjars/**", "anon");
|
||||
filterMap.put("/druid/**", "anon");
|
||||
filterMap.put("/app/**", "anon");
|
||||
filterMap.put("/busExercises/downExcel", "anon");
|
||||
filterMap.put("/busStudyTask/downExamExcel", "anon");
|
||||
filterMap.put("/sys/login", "anon");
|
||||
filterMap.put("/busVisitor/**", "anon");
|
||||
filterMap.put("/wxpost/**", "anon");
|
||||
// filterMap.put("/swagger/**", "anon");
|
||||
// filterMap.put("/v2/api-docs", "anon");
|
||||
// filterMap.put("/swagger-ui.html", "anon");
|
||||
// filterMap.put("/swagger-resources/**", "anon");
|
||||
filterMap.put("/captcha.jpg", "anon");
|
||||
// filterMap.put("/aaa.txt", "anon");
|
||||
filterMap.put("/**", "oauth2");
|
||||
shiroFilter.setFilterChainDefinitionMap(filterMap);
|
||||
|
||||
return shiroFilter;
|
||||
}
|
||||
|
||||
@Bean("lifecycleBeanPostProcessor")
|
||||
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
||||
return new LifecycleBeanPostProcessor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
|
||||
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
||||
advisor.setSecurityManager(securityManager);
|
||||
return advisor;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
|
||||
package com.zcloud.config;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.ApiKey;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
||||
@Configuration
|
||||
//@EnableSwagger2
|
||||
public class SwaggerConfig implements WebMvcConfigurer {
|
||||
|
||||
@Bean
|
||||
public Docket createRestApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(apiInfo())
|
||||
.select()
|
||||
//加了ApiOperation注解的类,才生成接口文档
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
//包下的类,才生成接口文档
|
||||
// .apis(Predicates.or(
|
||||
// RequestHandlerSelectors.basePackage("com.zcloud.modules.app.controller"),
|
||||
// RequestHandlerSelectors.basePackage("com.zcloud.modules.sys.controller")
|
||||
// ))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.securitySchemes(security());
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("教育")
|
||||
.description("文档")
|
||||
.version("1.0.0")
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<ApiKey> security() {
|
||||
return newArrayList(
|
||||
new ApiKey("token", "token", "header")
|
||||
);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket web_api_app() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(apiInfo())
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.any())
|
||||
.paths(PathSelectors.ant("/app/**"))
|
||||
.build()
|
||||
.groupName("APP")
|
||||
.pathMapping("/");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.zcloud.datasource.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 多数据源注解
|
||||
*
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface DataSource {
|
||||
String value() default "";
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.zcloud.datasource.aspect;
|
||||
|
||||
|
||||
import com.zcloud.datasource.annotation.DataSource;
|
||||
import com.zcloud.datasource.config.DynamicContextHolder;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 多数据源,切面处理类
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class DataSourceAspect {
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Pointcut("@annotation(com.zcloud.datasource.annotation.DataSource) " +
|
||||
"|| @within(com.zcloud.datasource.annotation.DataSource)")
|
||||
public void dataSourcePointCut() {
|
||||
|
||||
}
|
||||
|
||||
@Around("dataSourcePointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
||||
Class targetClass = point.getTarget().getClass();
|
||||
Method method = signature.getMethod();
|
||||
|
||||
DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class);
|
||||
DataSource methodDataSource = method.getAnnotation(DataSource.class);
|
||||
if(targetDataSource != null || methodDataSource != null){
|
||||
String value;
|
||||
if(methodDataSource != null){
|
||||
value = methodDataSource.value();
|
||||
}else {
|
||||
value = targetDataSource.value();
|
||||
}
|
||||
|
||||
DynamicContextHolder.push(value);
|
||||
logger.debug("set datasource is {}", value);
|
||||
}
|
||||
|
||||
try {
|
||||
return point.proceed();
|
||||
} finally {
|
||||
DynamicContextHolder.poll();
|
||||
logger.debug("clean datasource");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.zcloud.datasource.config;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* 多数据源上下文
|
||||
*/
|
||||
public class DynamicContextHolder {
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final ThreadLocal<Deque<String>> CONTEXT_HOLDER = new ThreadLocal() {
|
||||
@Override
|
||||
protected Object initialValue() {
|
||||
return new ArrayDeque();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获得当前线程数据源
|
||||
*
|
||||
* @return 数据源名称
|
||||
*/
|
||||
public static String peek() {
|
||||
return CONTEXT_HOLDER.get().peek();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前线程数据源
|
||||
*
|
||||
* @param dataSource 数据源名称
|
||||
*/
|
||||
public static void push(String dataSource) {
|
||||
CONTEXT_HOLDER.get().push(dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空当前线程数据源
|
||||
*/
|
||||
public static void poll() {
|
||||
Deque<String> deque = CONTEXT_HOLDER.get();
|
||||
deque.poll();
|
||||
if (deque.isEmpty()) {
|
||||
CONTEXT_HOLDER.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.zcloud.datasource.config;
|
||||
|
||||
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
||||
|
||||
/**
|
||||
* 多数据源
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DynamicDataSource extends AbstractRoutingDataSource {
|
||||
|
||||
@Override
|
||||
protected Object determineCurrentLookupKey() {
|
||||
return DynamicContextHolder.peek();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.zcloud.datasource.config;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.zcloud.datasource.properties.DataSourceProperties;
|
||||
import com.zcloud.datasource.properties.DynamicDataSourceProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 配置多数据源
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
|
||||
public class DynamicDataSourceConfig {
|
||||
@Autowired
|
||||
private DynamicDataSourceProperties properties;
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "spring.datasource.druid")
|
||||
public DataSourceProperties dataSourceProperties() {
|
||||
return new DataSourceProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
|
||||
DynamicDataSource dynamicDataSource = new DynamicDataSource();
|
||||
dynamicDataSource.setTargetDataSources(getDynamicDataSource());
|
||||
|
||||
//默认数据源
|
||||
DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties);
|
||||
dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
|
||||
|
||||
return dynamicDataSource;
|
||||
}
|
||||
|
||||
private Map<Object, Object> getDynamicDataSource(){
|
||||
Map<String, DataSourceProperties> dataSourcePropertiesMap = properties.getDatasource();
|
||||
Map<Object, Object> targetDataSources = new HashMap<>(dataSourcePropertiesMap.size());
|
||||
dataSourcePropertiesMap.forEach((k, v) -> {
|
||||
DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);
|
||||
targetDataSources.put(k, druidDataSource);
|
||||
});
|
||||
|
||||
return targetDataSources;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.zcloud.datasource.config;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.zcloud.datasource.properties.DataSourceProperties;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* DruidDataSource
|
||||
*
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class DynamicDataSourceFactory {
|
||||
|
||||
public static DruidDataSource buildDruidDataSource(DataSourceProperties properties) {
|
||||
DruidDataSource druidDataSource = new DruidDataSource();
|
||||
druidDataSource.setDriverClassName(properties.getDriverClassName());
|
||||
druidDataSource.setUrl(properties.getUrl());
|
||||
druidDataSource.setUsername(properties.getUsername());
|
||||
druidDataSource.setPassword(properties.getPassword());
|
||||
|
||||
druidDataSource.setInitialSize(properties.getInitialSize());
|
||||
druidDataSource.setMaxActive(properties.getMaxActive());
|
||||
druidDataSource.setMinIdle(properties.getMinIdle());
|
||||
druidDataSource.setMaxWait(properties.getMaxWait());
|
||||
druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
|
||||
druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
|
||||
druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis());
|
||||
druidDataSource.setValidationQuery(properties.getValidationQuery());
|
||||
druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout());
|
||||
druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
|
||||
druidDataSource.setTestOnReturn(properties.isTestOnReturn());
|
||||
druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
|
||||
druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements());
|
||||
druidDataSource.setSharePreparedStatements(properties.isSharePreparedStatements());
|
||||
|
||||
try {
|
||||
druidDataSource.setFilters(properties.getFilters());
|
||||
druidDataSource.init();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return druidDataSource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
package com.zcloud.datasource.properties;
|
||||
|
||||
/**
|
||||
* 多数据源属性
|
||||
*
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class DataSourceProperties {
|
||||
private String driverClassName;
|
||||
private String url;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Druid默认参数
|
||||
*/
|
||||
private int initialSize = 2;
|
||||
private int maxActive = 10;
|
||||
private int minIdle = -1;
|
||||
private long maxWait = 60 * 1000L;
|
||||
private long timeBetweenEvictionRunsMillis = 60 * 1000L;
|
||||
private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
|
||||
private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7;
|
||||
private String validationQuery = "select 1";
|
||||
private int validationQueryTimeout = -1;
|
||||
private boolean testOnBorrow = false;
|
||||
private boolean testOnReturn = false;
|
||||
private boolean testWhileIdle = true;
|
||||
private boolean poolPreparedStatements = false;
|
||||
private int maxOpenPreparedStatements = -1;
|
||||
private boolean sharePreparedStatements = false;
|
||||
private String filters = "stat,wall";
|
||||
|
||||
public String getDriverClassName() {
|
||||
return driverClassName;
|
||||
}
|
||||
|
||||
public void setDriverClassName(String driverClassName) {
|
||||
this.driverClassName = driverClassName;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public int getInitialSize() {
|
||||
return initialSize;
|
||||
}
|
||||
|
||||
public void setInitialSize(int initialSize) {
|
||||
this.initialSize = initialSize;
|
||||
}
|
||||
|
||||
public int getMaxActive() {
|
||||
return maxActive;
|
||||
}
|
||||
|
||||
public void setMaxActive(int maxActive) {
|
||||
this.maxActive = maxActive;
|
||||
}
|
||||
|
||||
public int getMinIdle() {
|
||||
return minIdle;
|
||||
}
|
||||
|
||||
public void setMinIdle(int minIdle) {
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
public long getMaxWait() {
|
||||
return maxWait;
|
||||
}
|
||||
|
||||
public void setMaxWait(long maxWait) {
|
||||
this.maxWait = maxWait;
|
||||
}
|
||||
|
||||
public long getTimeBetweenEvictionRunsMillis() {
|
||||
return timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
|
||||
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public long getMinEvictableIdleTimeMillis() {
|
||||
return minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
|
||||
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public long getMaxEvictableIdleTimeMillis() {
|
||||
return maxEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) {
|
||||
this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public String getValidationQuery() {
|
||||
return validationQuery;
|
||||
}
|
||||
|
||||
public void setValidationQuery(String validationQuery) {
|
||||
this.validationQuery = validationQuery;
|
||||
}
|
||||
|
||||
public int getValidationQueryTimeout() {
|
||||
return validationQueryTimeout;
|
||||
}
|
||||
|
||||
public void setValidationQueryTimeout(int validationQueryTimeout) {
|
||||
this.validationQueryTimeout = validationQueryTimeout;
|
||||
}
|
||||
|
||||
public boolean isTestOnBorrow() {
|
||||
return testOnBorrow;
|
||||
}
|
||||
|
||||
public void setTestOnBorrow(boolean testOnBorrow) {
|
||||
this.testOnBorrow = testOnBorrow;
|
||||
}
|
||||
|
||||
public boolean isTestOnReturn() {
|
||||
return testOnReturn;
|
||||
}
|
||||
|
||||
public void setTestOnReturn(boolean testOnReturn) {
|
||||
this.testOnReturn = testOnReturn;
|
||||
}
|
||||
|
||||
public boolean isTestWhileIdle() {
|
||||
return testWhileIdle;
|
||||
}
|
||||
|
||||
public void setTestWhileIdle(boolean testWhileIdle) {
|
||||
this.testWhileIdle = testWhileIdle;
|
||||
}
|
||||
|
||||
public boolean isPoolPreparedStatements() {
|
||||
return poolPreparedStatements;
|
||||
}
|
||||
|
||||
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
|
||||
this.poolPreparedStatements = poolPreparedStatements;
|
||||
}
|
||||
|
||||
public int getMaxOpenPreparedStatements() {
|
||||
return maxOpenPreparedStatements;
|
||||
}
|
||||
|
||||
public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
|
||||
this.maxOpenPreparedStatements = maxOpenPreparedStatements;
|
||||
}
|
||||
|
||||
public boolean isSharePreparedStatements() {
|
||||
return sharePreparedStatements;
|
||||
}
|
||||
|
||||
public void setSharePreparedStatements(boolean sharePreparedStatements) {
|
||||
this.sharePreparedStatements = sharePreparedStatements;
|
||||
}
|
||||
|
||||
public String getFilters() {
|
||||
return filters;
|
||||
}
|
||||
|
||||
public void setFilters(String filters) {
|
||||
this.filters = filters;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.zcloud.datasource.properties;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 多数据源属性
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "dynamic")
|
||||
public class DynamicDataSourceProperties {
|
||||
private Map<String, DataSourceProperties> datasource = new LinkedHashMap<>();
|
||||
|
||||
public Map<String, DataSourceProperties> getDatasource() {
|
||||
return datasource;
|
||||
}
|
||||
|
||||
public void setDatasource(Map<String, DataSourceProperties> datasource) {
|
||||
this.datasource = datasource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.zcloud.modules.app.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* app登录效验
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Login {
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.app.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 登录用户信息
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface LoginUser {
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.zcloud.modules.app.config;
|
||||
|
||||
import com.zcloud.modules.app.interceptor.AuthorizationInterceptor;
|
||||
import com.zcloud.modules.app.resolver.LoginUserHandlerMethodArgumentResolver;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MVC配置
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
@Autowired
|
||||
private AuthorizationInterceptor authorizationInterceptor;
|
||||
@Autowired
|
||||
private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(authorizationInterceptor)
|
||||
.addPathPatterns("/app/**")
|
||||
.addPathPatterns("/busVisitor/**")
|
||||
.addPathPatterns("/busStudyTask/downExamExcel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.app.controller;
|
||||
|
||||
|
||||
import com.zcloud.common.utils.R;
|
||||
import com.zcloud.common.validator.ValidatorUtils;
|
||||
import com.zcloud.modules.app.form.LoginForm;
|
||||
import com.zcloud.modules.app.service.UserService;
|
||||
import com.zcloud.modules.app.utils.JwtUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* APP登录授权
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
//@RequestMapping("/app")
|
||||
//@Api(tags="APP登录接口")
|
||||
public class AppLoginController {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
@Autowired
|
||||
private JwtUtils jwtUtils;
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
@PostMapping("login")
|
||||
// @ApiOperation("登录")
|
||||
public R login(@RequestBody LoginForm form){
|
||||
//表单校验
|
||||
ValidatorUtils.validateEntity(form);
|
||||
|
||||
//用户登录
|
||||
String userId = userService.login(form);
|
||||
|
||||
//生成token
|
||||
String token = jwtUtils.generateToken(userId);
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("token", token);
|
||||
map.put("expire", jwtUtils.getExpire());
|
||||
|
||||
return R.ok(map);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.app.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.zcloud.modules.app.entity.UserEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserDao extends BaseMapper<UserEntity> {
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.app.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@TableName("tb_user")
|
||||
public class UserEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@TableId
|
||||
private String userId;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.app.form;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 登录表单
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value = "登录表单")
|
||||
public class LoginForm {
|
||||
@ApiModelProperty(value = "用户名")
|
||||
@NotBlank(message="用户名不能为空")
|
||||
private String username;
|
||||
|
||||
@ApiModelProperty(value = "密码")
|
||||
@NotBlank(message="密码不能为空")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty(value = "验证码")
|
||||
@NotBlank(message="验证码不能为空")
|
||||
private String verifyCode;
|
||||
|
||||
@ApiModelProperty(value = "验证码code")
|
||||
private String codeNum;
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.app.form;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 注册表单
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value = "注册表单")
|
||||
public class RegisterForm {
|
||||
@ApiModelProperty(value = "手机号")
|
||||
@NotBlank(message="手机号不能为空")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty(value = "密码")
|
||||
@NotBlank(message="密码不能为空")
|
||||
private String password;
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.app.interceptor;
|
||||
|
||||
|
||||
import com.zcloud.common.exception.ZException;
|
||||
import com.zcloud.modules.app.annotation.Login;
|
||||
import com.zcloud.modules.app.utils.JwtUtils;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 权限(Token)验证
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
|
||||
@Autowired
|
||||
private JwtUtils jwtUtils;
|
||||
|
||||
public static final String USER_KEY = "userId";
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
Login annotation;
|
||||
if(handler instanceof HandlerMethod) {
|
||||
annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class);
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(annotation == null){
|
||||
return true;
|
||||
}
|
||||
|
||||
//获取用户凭证
|
||||
String token = request.getHeader(jwtUtils.getHeader());
|
||||
if(StringUtils.isBlank(token)){
|
||||
token = request.getParameter(jwtUtils.getHeader());
|
||||
}
|
||||
|
||||
//凭证为空
|
||||
if(StringUtils.isBlank(token)){
|
||||
throw new ZException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
|
||||
}
|
||||
|
||||
Claims claims = jwtUtils.getClaimByToken(token);
|
||||
if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
|
||||
throw new ZException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
|
||||
}
|
||||
|
||||
//设置userId到request里,后续根据userId,获取用户信息
|
||||
request.setAttribute(USER_KEY, Long.parseLong(claims.getSubject()));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.zcloud.modules.app.resolver;
|
||||
|
||||
import com.zcloud.modules.app.annotation.LoginUser;
|
||||
import com.zcloud.modules.app.entity.UserEntity;
|
||||
import com.zcloud.modules.app.interceptor.AuthorizationInterceptor;
|
||||
import com.zcloud.modules.app.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* 有@LoginUser注解的方法参数,注入当前登录用户
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return parameter.getParameterType().isAssignableFrom(UserEntity.class) && parameter.hasParameterAnnotation(LoginUser.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
|
||||
NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
|
||||
//获取用户ID
|
||||
Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
|
||||
if(object == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
//获取用户信息
|
||||
UserEntity user = userService.getById((String)object);
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.zcloud.modules.app.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.zcloud.modules.app.entity.UserEntity;
|
||||
import com.zcloud.modules.app.form.LoginForm;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
*/
|
||||
public interface UserService extends IService<UserEntity> {
|
||||
|
||||
UserEntity queryByMobile(String mobile);
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @param form 登录表单
|
||||
* @return 返回用户ID
|
||||
*/
|
||||
String login(LoginForm form);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.zcloud.modules.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.zcloud.common.exception.ZException;
|
||||
import com.zcloud.common.validator.Assert;
|
||||
import com.zcloud.modules.app.dao.UserDao;
|
||||
import com.zcloud.modules.app.entity.UserEntity;
|
||||
import com.zcloud.modules.app.form.LoginForm;
|
||||
import com.zcloud.modules.app.service.UserService;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
@Service("userService")
|
||||
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
|
||||
|
||||
@Override
|
||||
public UserEntity queryByMobile(String mobile) {
|
||||
return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("mobile", mobile));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String login(LoginForm form) {
|
||||
UserEntity user = queryByMobile(form.getUsername());
|
||||
Assert.isNull(user, "手机号或密码错误");
|
||||
|
||||
//密码错误
|
||||
if(!user.getPassword().equals(DigestUtils.sha256Hex(form.getPassword()))){
|
||||
throw new ZException("手机号或密码错误");
|
||||
}
|
||||
|
||||
return user.getUserId();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package com.zcloud.modules.app.utils;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* jwt工具类
|
||||
*
|
||||
*
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.jwt")
|
||||
@Component
|
||||
public class JwtUtils {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private String secret;
|
||||
private long expire;
|
||||
private String header;
|
||||
|
||||
/**
|
||||
* 生成jwt token
|
||||
*/
|
||||
public String generateToken(String userId) {
|
||||
Date nowDate = new Date();
|
||||
//过期时间
|
||||
Date expireDate = new Date(nowDate.getTime() + expire * 1000);
|
||||
|
||||
return Jwts.builder()
|
||||
.setHeaderParam("typ", "JWT")
|
||||
.setSubject(userId+"")
|
||||
.setIssuedAt(nowDate)
|
||||
.setExpiration(expireDate)
|
||||
.signWith(SignatureAlgorithm.HS512, secret)
|
||||
.compact();
|
||||
}
|
||||
|
||||
public Claims getClaimByToken(String token) {
|
||||
try {
|
||||
return Jwts.parser()
|
||||
.setSigningKey(secret)
|
||||
.parseClaimsJws(token)
|
||||
.getBody();
|
||||
}catch (Exception e){
|
||||
logger.debug("validate is token error ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* token是否过期
|
||||
* @return true:过期
|
||||
*/
|
||||
public boolean isTokenExpired(Date expiration) {
|
||||
return expiration.before(new Date());
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public long getExpire() {
|
||||
return expire;
|
||||
}
|
||||
|
||||
public void setExpire(long expire) {
|
||||
this.expire = expire;
|
||||
}
|
||||
|
||||
public String getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public void setHeader(String header) {
|
||||
this.header = header;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.zcloud.modules.job.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 定时任务配置
|
||||
*
|
||||
*/
|
||||
//@Configuration
|
||||
public class ScheduleConfig {
|
||||
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
|
||||
SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
factory.setDataSource(dataSource);
|
||||
|
||||
//quartz参数
|
||||
Properties prop = new Properties();
|
||||
prop.put("org.quartz.scheduler.instanceName", "ZcloudScheduler");
|
||||
prop.put("org.quartz.scheduler.instanceId", "AUTO");
|
||||
//线程池配置
|
||||
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
|
||||
prop.put("org.quartz.threadPool.threadCount", "20");
|
||||
prop.put("org.quartz.threadPool.threadPriority", "5");
|
||||
//JobStore配置
|
||||
prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
|
||||
//集群配置
|
||||
prop.put("org.quartz.jobStore.isClustered", "true");
|
||||
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
|
||||
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
|
||||
|
||||
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
|
||||
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
|
||||
prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
|
||||
|
||||
factory.setQuartzProperties(prop);
|
||||
|
||||
factory.setSchedulerName("ZcloudScheduler");
|
||||
//延时启动
|
||||
factory.setStartupDelay(30);
|
||||
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
|
||||
//可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
|
||||
factory.setOverwriteExistingJobs(true);
|
||||
//设置自动启动,默认为true
|
||||
factory.setAutoStartup(true);
|
||||
|
||||
return factory;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package com.zcloud.modules.job.controller;
|
||||
|
||||
import com.zcloud.common.annotation.SysLog;
|
||||
import com.zcloud.common.utils.PageUtils;
|
||||
import com.zcloud.common.utils.R;
|
||||
import com.zcloud.common.validator.ValidatorUtils;
|
||||
import com.zcloud.modules.job.entity.ScheduleJobEntity;
|
||||
import com.zcloud.modules.job.service.ScheduleJobService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 定时任务
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/schedule")
|
||||
public class ScheduleJobController {
|
||||
@Autowired
|
||||
private ScheduleJobService scheduleJobService;
|
||||
|
||||
/**
|
||||
* 定时任务列表
|
||||
*/
|
||||
@RequestMapping("/list")
|
||||
//@RequiresPermission("sys:schedule:list")
|
||||
public R list(@RequestBody Map<String, Object> params){
|
||||
PageUtils page = scheduleJobService.queryPage(params);
|
||||
|
||||
return R.ok().put("page", page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务信息
|
||||
*/
|
||||
@RequestMapping("/info")
|
||||
//@RequiresPermission("sys:schedule:info")
|
||||
public R info(@RequestBody ScheduleJobEntity scheduleJob){
|
||||
ScheduleJobEntity schedule = scheduleJobService.getById(scheduleJob.getJobId());
|
||||
return R.ok().put("schedule", schedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存定时任务
|
||||
*/
|
||||
@SysLog("保存定时任务")
|
||||
@RequestMapping("/save")
|
||||
//@RequiresPermission("sys:schedule:save")
|
||||
public R save(@RequestBody ScheduleJobEntity scheduleJob){
|
||||
ValidatorUtils.validateEntity(scheduleJob);
|
||||
|
||||
scheduleJobService.saveJob(scheduleJob);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改定时任务
|
||||
*/
|
||||
@SysLog("修改定时任务")
|
||||
@RequestMapping("/update")
|
||||
//@RequiresPermission("sys:schedule:update")
|
||||
public R update(@RequestBody ScheduleJobEntity scheduleJob){
|
||||
ValidatorUtils.validateEntity(scheduleJob);
|
||||
|
||||
scheduleJobService.update(scheduleJob);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
*/
|
||||
@SysLog("删除定时任务")
|
||||
@RequestMapping("/delete")
|
||||
//@RequiresPermission("sys:schedule:delete")
|
||||
public R delete(@RequestBody ScheduleJobEntity scheduleJob){
|
||||
scheduleJobService.removeById(scheduleJob.getJobId());
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行任务
|
||||
*/
|
||||
@SysLog("立即执行任务")
|
||||
@RequestMapping("/run")
|
||||
//@RequiresPermission("sys:schedule:run")
|
||||
public R run(@RequestBody ScheduleJobEntity scheduleJob){
|
||||
scheduleJobService.run(scheduleJob.getJobId());
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停定时任务
|
||||
*/
|
||||
@SysLog("暂停定时任务")
|
||||
@RequestMapping("/pause")
|
||||
//@RequiresPermission("sys:schedule:pause")
|
||||
public R pause(@RequestBody ScheduleJobEntity scheduleJob){
|
||||
scheduleJobService.pause(scheduleJob.getJobId());
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复定时任务
|
||||
*/
|
||||
@SysLog("恢复定时任务")
|
||||
@RequestMapping("/resume")
|
||||
//@RequiresPermission("sys:schedule:resume")
|
||||
public R resume(@RequestBody ScheduleJobEntity scheduleJob){
|
||||
scheduleJobService.resume(scheduleJob.getJobId());
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.job.controller;
|
||||
|
||||
import com.zcloud.common.utils.PageUtils;
|
||||
import com.zcloud.common.utils.R;
|
||||
import com.zcloud.modules.job.entity.ScheduleJobLogEntity;
|
||||
import com.zcloud.modules.job.service.ScheduleJobLogService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 定时任务日志
|
||||
*
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/scheduleLog")
|
||||
public class ScheduleJobLogController {
|
||||
@Autowired
|
||||
private ScheduleJobLogService scheduleJobLogService;
|
||||
|
||||
/**
|
||||
* 定时任务日志列表
|
||||
*/
|
||||
@RequestMapping("/list")
|
||||
//@RequiresPermission("sys:schedule:log")
|
||||
public R list(@RequestBody Map<String, Object> params){
|
||||
PageUtils page = scheduleJobLogService.queryPage(params);
|
||||
|
||||
return R.ok().put("page", page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务日志信息
|
||||
*/
|
||||
@RequestMapping("/info/{logId}")
|
||||
public R info(@PathVariable("logId") String logId){
|
||||
ScheduleJobLogEntity log = scheduleJobLogService.getById(logId);
|
||||
|
||||
return R.ok().put("log", log);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.job.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.zcloud.modules.job.entity.ScheduleJobEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 定时任务
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Mapper
|
||||
public interface ScheduleJobDao extends BaseMapper<ScheduleJobEntity> {
|
||||
|
||||
/**
|
||||
* 批量更新状态
|
||||
*/
|
||||
int updateBatch(Map<String, Object> map);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.job.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.zcloud.modules.job.entity.ScheduleJobLogEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 定时任务日志
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Mapper
|
||||
public interface ScheduleJobLogDao extends BaseMapper<ScheduleJobLogEntity> {
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.job.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 定时任务
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@TableName("schedule_job")
|
||||
public class ScheduleJobEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 任务调度参数key
|
||||
*/
|
||||
public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
@TableId
|
||||
private String jobId;
|
||||
|
||||
/**
|
||||
* spring bean名称
|
||||
*/
|
||||
@NotBlank(message="bean名称不能为空")
|
||||
private String beanName;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* cron表达式
|
||||
*/
|
||||
@NotBlank(message="cron表达式不能为空")
|
||||
private String cronExpression;
|
||||
|
||||
/**
|
||||
* 任务状态
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.job.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 定时任务日志
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@TableName("schedule_job_log")
|
||||
public class ScheduleJobLogEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 日志id
|
||||
*/
|
||||
@TableId
|
||||
private String logId;
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
private String jobId;
|
||||
|
||||
/**
|
||||
* spring bean名称
|
||||
*/
|
||||
private String beanName;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* 任务状态 0:成功 1:失败
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 失败信息
|
||||
*/
|
||||
private String error;
|
||||
|
||||
/**
|
||||
* 耗时(单位:毫秒)
|
||||
*/
|
||||
private Integer times;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
|
||||
package com.zcloud.modules.job.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.zcloud.common.utils.PageUtils;
|
||||
import com.zcloud.modules.job.entity.ScheduleJobLogEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 定时任务日志
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface ScheduleJobLogService extends IService<ScheduleJobLogEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue